1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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 - 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;
}
}
|