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 m_Ghosts = new List(); 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 - start]; 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; } }