353 lines
12 KiB
C#
353 lines
12 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Beyond
|
|
{
|
|
[RequireComponent(typeof(MeshFilter))]
|
|
[RequireComponent(typeof(MeshRenderer))]
|
|
[DisallowMultipleComponent]
|
|
public class WeaponTrail : MonoBehaviour
|
|
{
|
|
[SerializeField] private Transform m_tip;
|
|
[SerializeField] private Transform m_base;
|
|
private Mesh m_mesh;
|
|
[SerializeField] private int m_numFrames = 10;
|
|
|
|
private Transform m_parentWeapon;
|
|
private const int NUM_VERTICES = 2;
|
|
private int m_frameNum = 0;
|
|
private int m_triNum = 0;
|
|
|
|
private int[] m_triangles;
|
|
private Vector3[] m_vertices;
|
|
private Color[] m_colours;
|
|
private bThirdPersonInput m_tpInput;
|
|
private Renderer m_renderer;
|
|
|
|
private const int NUM_PREV_POINTS = 3;
|
|
private Vector3[] m_prevTip = new Vector3[NUM_PREV_POINTS], m_prevBase = new Vector3[NUM_PREV_POINTS];
|
|
|
|
[SerializeField] private int m_maxDivisions = 4;
|
|
[SerializeField] private float m_stripLength = 0.1f;
|
|
|
|
[ColorUsageAttribute(true, true, 0f, 8f, 0.125f, 3f)]
|
|
public Color m_colorMultiplier = Color.white;
|
|
public bool m_alwaysPlay = true;
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
m_tpInput = Player.Instance.GetComponent<bThirdPersonInput>();
|
|
// transform.parent = null;
|
|
var meshFilter = GetComponent<MeshFilter>();
|
|
m_renderer = GetComponent<MeshRenderer>();
|
|
m_mesh = new Mesh();
|
|
m_renderer.shadowCastingMode = ShadowCastingMode.Off;
|
|
m_mesh.MarkDynamic();
|
|
meshFilter.mesh = m_mesh;
|
|
|
|
m_tip.transform.parent = transform.parent;
|
|
m_base.transform.parent = transform.parent;
|
|
m_parentWeapon = transform.parent;
|
|
transform.parent = null;
|
|
transform.position = Vector3.zero;
|
|
transform.rotation = Quaternion.identity;
|
|
transform.localScale = Vector3.one;
|
|
|
|
for (int i = 0; i < NUM_PREV_POINTS; i++)
|
|
{
|
|
m_prevTip[i] = m_tip.transform.position;
|
|
m_prevBase[i] = m_base.transform.position;
|
|
}
|
|
|
|
//m_vertices = new Vector3[m_numFrames * NUM_VERTICES];
|
|
m_vertices = new Vector3[m_numFrames * NUM_VERTICES];
|
|
m_colours = new Color[m_vertices.Length];
|
|
m_triangles = new int[(m_numFrames-1) * 6];
|
|
var basePos = m_base.transform.position;
|
|
var tipPos = m_tip.transform.position;
|
|
|
|
for (int i = 0; i < m_numFrames; i++)
|
|
{
|
|
int vdx = i * NUM_VERTICES;
|
|
m_vertices[vdx + 0] = basePos;
|
|
m_vertices[vdx + 1] = tipPos;
|
|
}
|
|
|
|
int numV = m_vertices.Length;
|
|
|
|
for (int i = 0; i < m_numFrames-1; i++)
|
|
{
|
|
int vdx = i * NUM_VERTICES;
|
|
int tdx = i * 6;
|
|
|
|
int v2 = (vdx + 2 )% numV;
|
|
int v3 = (vdx + 3 )% numV;
|
|
//int v2 = (vdx - 2 );//% numV;
|
|
//int v3 = (vdx - 1 );//% numV;
|
|
//if (v2 < 0) v2 += numV;
|
|
//if (v3 < 0) v3 += numV;
|
|
|
|
m_triangles[tdx + 0] = vdx + 0;
|
|
m_triangles[tdx + 1] = vdx + 1;
|
|
m_triangles[tdx + 2] = v2;
|
|
m_triangles[tdx + 3] = v2;
|
|
m_triangles[tdx + 4] = v3;
|
|
m_triangles[tdx + 5] = vdx + 1;
|
|
}
|
|
|
|
// m_mesh.vertices = m_vertices;
|
|
// m_mesh.triangles = m_triangles;
|
|
|
|
}
|
|
|
|
Vector3 CatmullRom(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float s)
|
|
{
|
|
Vector3 res;
|
|
float s2, s3;
|
|
s2 = s * s;
|
|
s3 = s2 * s;
|
|
res = p1 * (-s3 + 2.0f * s2 - s) + p2 * (3.0f * s3 - 5.0f * s2 + 2.0f) + p3 * (-3.0f * s3 + 4.0f * s2 + s) + p4 * (s3 - s2);
|
|
res /= 2.0f;
|
|
return res;
|
|
}
|
|
|
|
bool PlayConditions()
|
|
{
|
|
bool playConditions = m_tpInput.cc.IsAnimatorTag("Attack") && m_parentWeapon.gameObject.activeInHierarchy;
|
|
return playConditions;
|
|
}
|
|
/*
|
|
void Update()
|
|
{
|
|
bool shouldPlay = PlayConditions() || m_alwaysPlay;
|
|
m_renderer.enabled = shouldPlay;
|
|
var basePos = m_base.transform.position;
|
|
var tipPos = m_tip.transform.position;
|
|
|
|
|
|
if (!shouldPlay)
|
|
{
|
|
for (int i = 0; i < NUM_PREV_POINTS; i++)
|
|
{
|
|
m_prevBase[i] = basePos;
|
|
m_prevTip[i] = tipPos;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Attack!");
|
|
}
|
|
|
|
|
|
int numV = m_vertices.Length;
|
|
|
|
int idx = m_frameNum * NUM_VERTICES;
|
|
if (m_numDivisions > 1)
|
|
{
|
|
for (int d = 0; d < m_numDivisions; d++ )
|
|
{
|
|
idx = m_frameNum * NUM_VERTICES;
|
|
float t = (float) d / (float) m_numDivisions;
|
|
m_vertices[idx + 0] = CatmullRom(m_prevBase[1], m_prevBase[0], basePos, basePos, t);
|
|
m_vertices[idx + 1] = CatmullRom(m_prevTip[1], m_prevTip[0], tipPos, tipPos, t);
|
|
|
|
int tdx = m_frameNum * 6;
|
|
//int v2 = (idx + 2 );//% numV;
|
|
//int v3 = (idx + 3 );//% numV;
|
|
int v2 = (idx - 2 );//% numV;
|
|
int v3 = (idx - 1 );//% numV;
|
|
if (v2 < 0) v2 += numV;
|
|
if (v3 < 0) v3 += numV;
|
|
|
|
m_triangles[tdx + 0] = idx + 0;
|
|
m_triangles[tdx + 1] = idx + 1;
|
|
m_triangles[tdx + 2] = v2;
|
|
m_triangles[tdx + 3] = v2;
|
|
m_triangles[tdx + 4] = v3;
|
|
m_triangles[tdx + 5] = idx + 1;
|
|
|
|
|
|
m_frameNum++;
|
|
m_frameNum %= m_numFrames;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_vertices[idx + 0] = basePos;
|
|
m_vertices[idx + 1] = tipPos;
|
|
m_vertices[idx + 2] = m_prevBase[0];
|
|
m_vertices[idx + 3] = m_prevTip[0];
|
|
int tdx = m_frameNum * 6;
|
|
|
|
int v2 = (idx +2 );//% numV;
|
|
int v3 = (idx +3 );//% numV;
|
|
if (v2 < 0) v2 += numV;
|
|
if (v3 < 0) v3 += numV;
|
|
|
|
m_triangles[tdx + 0] = idx + 0;
|
|
m_triangles[tdx + 1] = idx + 1;
|
|
m_triangles[tdx + 2] = v2;
|
|
m_triangles[tdx + 3] = v2;
|
|
m_triangles[tdx + 4] = v3;
|
|
m_triangles[tdx + 5] = idx + 1;
|
|
m_frameNum++;
|
|
m_frameNum %= m_numFrames;
|
|
|
|
}
|
|
|
|
//fill colours
|
|
Color colour = Color.white;
|
|
for (int i = 0; i < m_numFrames; i++)
|
|
{
|
|
//colour.a = (float) (i) / ((float) m_numFrames);
|
|
colour.a = (float) (m_numFrames - i) / ((float) m_numFrames);
|
|
int cnum = (m_frameNum - i) % m_numFrames;
|
|
if (cnum < 0) cnum += m_numFrames;
|
|
int cid = (cnum * NUM_VERTICES);
|
|
for (int j = 0; j < NUM_VERTICES; j++)
|
|
{
|
|
m_colours[cid + j] = colour;
|
|
}
|
|
}
|
|
|
|
|
|
m_mesh.vertices = m_vertices;
|
|
m_mesh.colors = m_colours;
|
|
//m_mesh.
|
|
m_mesh.triangles = m_triangles;
|
|
m_mesh.RecalculateBounds();
|
|
|
|
for (int i = 0; i < NUM_PREV_POINTS - 1; i++)
|
|
{
|
|
m_prevTip[i + 1] = m_prevTip[i];
|
|
m_prevBase[i + 1] = m_prevBase[i];
|
|
}
|
|
m_prevTip[0] = tipPos;
|
|
m_prevBase[0] = basePos;
|
|
|
|
}
|
|
*/
|
|
// Update is called once per frame
|
|
void AddStrip(Vector3 basePos, Vector3 tipPos)
|
|
{
|
|
int numV = m_vertices.Length;
|
|
int idx = m_frameNum * NUM_VERTICES;
|
|
|
|
m_vertices[idx + 0] = basePos;
|
|
m_vertices[idx + 1] = tipPos;
|
|
|
|
int tidx = m_triNum * 6;
|
|
|
|
int v2 = (idx - 2);
|
|
int v3 = (idx - 1);
|
|
if (v2 < 0) v2 += numV;
|
|
if (v3 < 0) v3 += numV;
|
|
|
|
m_triangles[tidx + 0] = idx + 0;
|
|
m_triangles[tidx + 1] = idx + 1;
|
|
m_triangles[tidx + 2] = v2;
|
|
m_triangles[tidx + 3] = v2;
|
|
m_triangles[tidx + 4] = v3;
|
|
m_triangles[tidx + 5] = idx + 1;
|
|
|
|
m_frameNum++;
|
|
m_frameNum %= m_numFrames;
|
|
m_triNum++;
|
|
m_triNum %= (m_numFrames - 1);
|
|
}
|
|
void FixedUpdate()
|
|
{
|
|
bool shouldPlay = PlayConditions() || m_alwaysPlay;
|
|
|
|
m_renderer.enabled = shouldPlay;
|
|
var basePos = m_base.transform.position;
|
|
var tipPos = m_tip.transform.position;
|
|
|
|
|
|
if (!shouldPlay)
|
|
{
|
|
if (Player.Instance.ActiveWeaponTrail == this)
|
|
{
|
|
Player.Instance.ActiveWeaponTrail = null;
|
|
}
|
|
|
|
for (int i = 0; i < NUM_PREV_POINTS; i++)
|
|
{
|
|
m_prevBase[i] = basePos;
|
|
m_prevTip[i] = tipPos;
|
|
}
|
|
AddStrip(basePos, tipPos);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Player.Instance.ActiveWeaponTrail = this;
|
|
//Debug.Log("Attack!");
|
|
}
|
|
|
|
|
|
int numV = m_vertices.Length;
|
|
|
|
int idx = m_frameNum * NUM_VERTICES;
|
|
if (m_maxDivisions > 1)
|
|
{
|
|
float bdist = Vector3.Distance(m_prevBase[0], basePos);
|
|
float tdist = Vector3.Distance(m_prevTip[0], tipPos);
|
|
float dist = Mathf.Max(bdist, tdist);
|
|
int div = Mathf.CeilToInt(dist / m_stripLength);
|
|
div = Math.Min(div, m_maxDivisions);
|
|
//Debug.Log("Divisions: "+div);
|
|
for (int d = 0; d < div; d++ )
|
|
{
|
|
float t = (float) d / (float) div;
|
|
//var bp = CatmullRom(m_prevBase[1], m_prevBase[0], basePos, basePos, t);
|
|
//var tp = CatmullRom(m_prevTip[1], m_prevTip[0], tipPos, tipPos, t);
|
|
var bp = CatmullRom(m_prevBase[2], m_prevBase[1], m_prevBase[0], basePos, t);
|
|
var tp = CatmullRom(m_prevTip[2], m_prevTip[1], m_prevTip[0], tipPos, t);
|
|
AddStrip(bp, tp);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
AddStrip(basePos, tipPos);
|
|
}
|
|
|
|
//fill colours
|
|
Color colour = m_colorMultiplier;
|
|
for (int i = 0; i < m_numFrames; i++)
|
|
{
|
|
//colour.a = (float) (i) / ((float) m_numFrames);
|
|
colour.a = (float) (m_numFrames - i) / ((float) m_numFrames);
|
|
int cnum = (m_frameNum - i-1) % m_numFrames;
|
|
if (cnum < 0) cnum += m_numFrames;
|
|
int cid = (cnum * NUM_VERTICES);
|
|
for (int j = 0; j < NUM_VERTICES; j++)
|
|
{
|
|
m_colours[cid + j] = colour;
|
|
}
|
|
}
|
|
|
|
|
|
m_mesh.vertices = m_vertices;
|
|
m_mesh.colors = m_colours;
|
|
//m_mesh.
|
|
m_mesh.triangles = m_triangles;
|
|
m_mesh.RecalculateBounds();
|
|
|
|
for (int i = 0; i < NUM_PREV_POINTS - 1; i++)
|
|
{
|
|
m_prevTip[i + 1] = m_prevTip[i];
|
|
m_prevBase[i + 1] = m_prevBase[i];
|
|
}
|
|
m_prevTip[0] = tipPos;
|
|
m_prevBase[0] = basePos;
|
|
|
|
}
|
|
}
|
|
}
|