summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Effects/CharacterGhostEffect.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts/Effects/CharacterGhostEffect.cs')
-rw-r--r--Assets/Scripts/Effects/CharacterGhostEffect.cs127
1 files changed, 127 insertions, 0 deletions
diff --git a/Assets/Scripts/Effects/CharacterGhostEffect.cs b/Assets/Scripts/Effects/CharacterGhostEffect.cs
new file mode 100644
index 00000000..d40adc17
--- /dev/null
+++ b/Assets/Scripts/Effects/CharacterGhostEffect.cs
@@ -0,0 +1,127 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class CharacterGhostEffect : EffectHandler
+{
+ [Tooltip("目标skinMeshRenderer")]
+ public SkinnedMeshRenderer m_Renderer;
+
+ [Tooltip("如果mesh包含多个submesh,需要每个submesh单独设置一个材质")]
+ public Material[] Materials;
+
+ [Tooltip("Submesh是否使用同一个材质")]
+ public bool SubmeshShareMaterial;
+
+ [Tooltip("使用范围内的submesh")]
+ public bool UseRangedSubmesh;
+
+ [Tooltip("Submesh索引范围")]
+ public Vector2Int SubmeshRange;
+
+ [Tooltip("是否开启残影效果")]
+ public bool IsEnable;
+
+ [Tooltip("残影生成的时间间隔")]
+ public float Interval = 0.1f;
+
+ [Tooltip("残影的生存时间")]
+ public float LifeTime = 0.5f;
+
+ private float m_Time = 0;
+ private List<GhostSnapshot> m_Ghosts = new List<GhostSnapshot>();
+
+ void Update()
+ {
+ //if (!IsEnable)
+ //{
+ // if (m_Ghosts.Count > 0)
+ // UpdateGhost(); // destroy ghosts
+ // return;
+ //}
+
+ if (m_Ghosts == null || m_Renderer == null || Materials == null || Materials.Length == 0)
+ {
+ IsEnable = false;
+ return;
+ }
+
+ m_Time += Time.deltaTime;
+
+ //if(IsEnable)
+ // CreateGhost();
+
+ UpdateGhost();
+ DrawGhost();
+ }
+
+ public void CreateGhost()
+ {
+ if(m_Time >= Interval)
+ {
+ m_Time -= Interval;
+
+ Mesh mesh = new Mesh();
+ m_Renderer.BakeMesh(mesh);
+
+ Matrix4x4 mat = m_Renderer.localToWorldMatrix;
+
+ m_Ghosts.Add(new GhostSnapshot(mesh, mat, Time.realtimeSinceStartup, LifeTime));
+ }
+ }
+
+ void UpdateGhost()
+ {
+ for(int i = m_Ghosts.Count - 1; i >= 0 ; --i)
+ {
+ GhostSnapshot ghost = m_Ghosts[i];
+ float passTime = Time.realtimeSinceStartup - ghost.startTime;
+
+ if (passTime > ghost.lifeTime)
+ {
+ m_Ghosts.Remove(ghost);
+ Destroy(ghost);
+ continue;
+ }
+ }
+ }
+
+ void DrawGhost()
+ {
+ for(int i = 0; i < m_Ghosts.Count; ++ i)
+ {
+ GhostSnapshot ghost = m_Ghosts[i];
+ int start = 0, end = ghost.mesh.subMeshCount - 1;
+ if(UseRangedSubmesh)
+ {
+ start = SubmeshRange.x;
+ end = SubmeshRange.y;
+ }
+ for (int j = start; j <= end; ++j)
+ {
+ Material material;
+ if (SubmeshShareMaterial)
+ material = Materials[0];
+ else
+ material = Materials[j];
+ Graphics.DrawMesh(ghost.mesh, ghost.matrix, material, gameObject.layer, null, j);
+ }
+ }
+ }
+}
+
+class GhostSnapshot : Object
+{
+ public Mesh mesh;
+ public Matrix4x4 matrix;
+ public float startTime;
+ public float lifeTime;
+
+ public GhostSnapshot(Mesh mesh, Matrix4x4 mat, float startTime, float lifeTime)
+ {
+ this.mesh = mesh;
+ this.matrix = mat;
+ this.startTime = startTime;
+ this.lifeTime = lifeTime;
+ }
+}