用于统计粒子特效信息,比如粒子个数、三角面数
一般粒子需要统计的信息有
1
2
3
4
5
|
public int triangles;
public bool prewarm = false;
public int distortion;
public int particleCount;
public int materialCount;
|
粒子中可能包含一些模型,所以先要获取所有的 MeshFilter, MeshRenderer, SkinnedMeshRenderer,从里面得到 mesh 和 material。然后得到所有的 ParticleSystem ,以及它的 Renderer 模块 ParticleSystemRenderer,从中获取剩余的 sharedMaterials。最后用 CurveUtil 计算出 ParticleSystem 的 particleCount 和剩余的 trianglesCount。一般 mesh 的 triangleCount 计算方法为
1
|
triangles += mesh.triangles.Length / 3;
|
注意判断 renderer 和 emission 模块是否开启,否则粒子信息无效。
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class CurveUtil
{
public static int GetForecastParticleCount(this ParticleSystem particleSystem)
{
float rateOverTime = particleSystem.GetRateOverTimeMax();
return Mathf.CeilToInt(Mathf.Min(particleSystem.main.startLifetime.GetMaxVal() * rateOverTime, particleSystem.main.maxParticles));
}
public static int GetForecastTrianglesCount(this ParticleSystem particleSystem)
{
int count = particleSystem.GetForecastParticleCount();
ParticleSystemRenderer renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
if(renderer.renderMode == ParticleSystemRenderMode.Mesh && renderer.mesh != null)
{
return count * renderer.mesh.triangles.Length / 3;
}
else
{
return count * 2;
}
}
public static ParticleSystemRenderMode GetRenderMode(this ParticleSystem particleSystem)
{
ParticleSystemRenderer renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
return renderer.renderMode;
}
public static string GetMeshName(this ParticleSystem particleSystem)
{
ParticleSystemRenderer renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
if (renderer.renderMode == ParticleSystemRenderMode.Mesh)
{
#if UNITY_EDITOR
return UnityEditor.AssetDatabase.GetAssetPath(renderer.mesh);
#endif
return renderer.mesh.name;
}
else
{
return renderer.renderMode.ToString();
}
}
public static float GetRateOverTimeMax(this ParticleSystem particleSystem)
{
float rateOverTime = particleSystem.emission.rateOverTime.GetMaxVal();
return Mathf.Max(rateOverTime, particleSystem.GetBurstMax());
}
public static int GetBurstMax(this ParticleSystem particleSystem)
{
int val = 0;
ParticleSystem.Burst[] bursts = new ParticleSystem.Burst[particleSystem.emission.burstCount];
particleSystem.emission.GetBursts(bursts);
foreach (ParticleSystem.Burst burst in bursts)
{
val = Mathf.Max(val, burst.maxCount);
val = Mathf.Max(val, burst.minCount);
if(burst.cycleCount == 0 && burst.repeatInterval > 0)
{
val = Mathf.Max(val, Mathf.CeilToInt(1f / burst.repeatInterval) * val);
}
}
return val;
}
public static float GetMaxVal(this ParticleSystem.MinMaxCurve minMaxCurve)
{
switch (minMaxCurve.mode)
{
case ParticleSystemCurveMode.TwoConstants:
return Mathf.Max(minMaxCurve.constantMax, minMaxCurve.constantMin);
case ParticleSystemCurveMode.Curve:
return minMaxCurve.curve.GetMaxVal();
case ParticleSystemCurveMode.TwoCurves:
return Mathf.Max( minMaxCurve.curveMax.GetMaxVal(), minMaxCurve.curveMax.GetMaxVal());
case ParticleSystemCurveMode.Constant:
default:
return minMaxCurve.constant;
}
}
public static float GetMaxVal(this AnimationCurve animationCurve)
{
float maxVal = int.MinValue;
foreach (Keyframe keyframe in animationCurve.keys)
{
if (maxVal < keyframe.value)
{
maxVal = keyframe.value;
}
}
return maxVal;
}
public static float GetMinVal(this AnimationCurve animationCurve)
{
float minVal = int.MaxValue;
foreach (Keyframe keyframe in animationCurve.keys)
{
if (minVal > keyframe.value)
{
minVal = keyframe.value;
}
}
return minVal;
}
}
|