好多新内容
This commit is contained in:
@@ -88,6 +88,17 @@ public class groundParticularController : MonoBehaviour
|
||||
private float[] _audioSamples = new float[128];
|
||||
private float _currentAverageVolume = 0f;
|
||||
private float _emitTimer = 0f;
|
||||
|
||||
// 性能:复用一个 MaterialPropertyBlock,避免每颗粒子 new(GC)。
|
||||
private MaterialPropertyBlock _sharedPropBlock;
|
||||
// 性能:缓存粒子的 Renderer,避免 Emit/MoveRoutine 每次 GetComponent。
|
||||
private readonly Dictionary<GameObject, Renderer> _rendererCache = new Dictionary<GameObject, Renderer>();
|
||||
// 性能:记录已对某共享材质设过 renderQueue,避免重复写。
|
||||
private readonly HashSet<Material> _renderQueueApplied = new HashSet<Material>();
|
||||
// Shader 属性 ID 缓存(比字符串查找快,且避免每帧字符串)。
|
||||
private static readonly int _headColorId = Shader.PropertyToID("_HeadColor");
|
||||
private static readonly int _tailColorId = Shader.PropertyToID("_TailColor");
|
||||
private static readonly int _moveDirId = Shader.PropertyToID("_MoveDir");
|
||||
|
||||
// 材质均衡分配逻辑
|
||||
private List<MaterialConfig> _cachedEnabledConfigs = new List<MaterialConfig>();
|
||||
@@ -99,11 +110,15 @@ public class groundParticularController : MonoBehaviour
|
||||
private void Awake()
|
||||
{
|
||||
if (startPoint != null) _originalStartScale = startPoint.localScale;
|
||||
_sharedPropBlock = new MaterialPropertyBlock();
|
||||
|
||||
_pool = new ObjectPool<GameObject>(
|
||||
createFunc: () => {
|
||||
GameObject go = Instantiate(particlePrefab);
|
||||
go.SetActive(false);
|
||||
// 创建时缓存 Renderer,后续 Emit/Move 复用,避免每颗粒子 GetComponent。
|
||||
var r = go.GetComponent<Renderer>();
|
||||
if (r != null) _rendererCache[go] = r;
|
||||
return go;
|
||||
},
|
||||
actionOnGet: (obj) => {
|
||||
@@ -155,10 +170,11 @@ public class groundParticularController : MonoBehaviour
|
||||
// 批量生成
|
||||
for (int i = 0; i < emitBatchSize; i++)
|
||||
{
|
||||
// 引入混乱度:随机延迟发射
|
||||
// 引入混乱度:随机延迟发射。用协程替代 Invoke(nameof)——
|
||||
// 后者每次做字符串反射+分配;协程延迟无字符串开销。
|
||||
if (chaosRandomDelay > 0)
|
||||
{
|
||||
Invoke(nameof(DelayedEmit), Random.Range(0f, chaosRandomDelay));
|
||||
StartCoroutine(DelayedEmitRoutine(Random.Range(0f, chaosRandomDelay)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -168,11 +184,22 @@ public class groundParticularController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void DelayedEmit()
|
||||
private System.Collections.IEnumerator DelayedEmitRoutine(float delay)
|
||||
{
|
||||
if (delay > 0f) yield return new WaitForSeconds(delay);
|
||||
Emit();
|
||||
}
|
||||
|
||||
// 取粒子缓存的 Renderer;未缓存(异常情况)则补取一次。
|
||||
private Renderer GetCachedRenderer(GameObject particle)
|
||||
{
|
||||
if (particle == null) return null;
|
||||
if (_rendererCache.TryGetValue(particle, out Renderer r) && r != null) return r;
|
||||
r = particle.GetComponent<Renderer>();
|
||||
if (r != null) _rendererCache[particle] = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
private void AnalyzeAudio()
|
||||
{
|
||||
if (musicSource == null || !musicSource.isPlaying || !useAudioAnalysis)
|
||||
@@ -233,7 +260,7 @@ public class groundParticularController : MonoBehaviour
|
||||
particle.layer = layer;
|
||||
}
|
||||
|
||||
var renderer = particle.GetComponent<Renderer>();
|
||||
Renderer renderer = GetCachedRenderer(particle);
|
||||
if (renderer != null)
|
||||
{
|
||||
// 设置渲染层级
|
||||
@@ -242,11 +269,17 @@ public class groundParticularController : MonoBehaviour
|
||||
|
||||
if (selectedConfig != null)
|
||||
{
|
||||
// 使用实例化材质以允许独立修改 RenderQueue
|
||||
renderer.material = selectedConfig.Value.material;
|
||||
if (renderQueueOffset != 0)
|
||||
Material mat = selectedConfig.Value.material;
|
||||
// 用共享材质(sharedMaterial)避免克隆实例产生 GC / 破坏合批。
|
||||
// renderQueue 是全局统一配置(renderQueueOffset),只需对每个材质设一次即可,
|
||||
// 所有用该材质的粒子渲染队列一致,视觉与原来相同。
|
||||
if (renderQueueOffset != 0 && _renderQueueApplied.Add(mat))
|
||||
{
|
||||
renderer.material.renderQueue = selectedConfig.Value.material.renderQueue + renderQueueOffset;
|
||||
mat.renderQueue = mat.renderQueue + renderQueueOffset;
|
||||
}
|
||||
if (renderer.sharedMaterial != mat)
|
||||
{
|
||||
renderer.sharedMaterial = mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,9 +343,9 @@ public class groundParticularController : MonoBehaviour
|
||||
|
||||
particle.transform.position = spawnWorldPos;
|
||||
|
||||
// 获取材质属性块用于动态修改颜色 (不产生材质实例 GC)
|
||||
MaterialPropertyBlock propBlock = new MaterialPropertyBlock();
|
||||
var renderer = particle.GetComponent<Renderer>();
|
||||
// 复用共享属性块(不 new,避免每颗粒子 GC)与缓存的 Renderer。
|
||||
MaterialPropertyBlock propBlock = _sharedPropBlock;
|
||||
Renderer renderer = GetCachedRenderer(particle);
|
||||
|
||||
while (particle != null && particle.activeInHierarchy)
|
||||
{
|
||||
@@ -346,10 +379,10 @@ public class groundParticularController : MonoBehaviour
|
||||
Color tailColor = config.Value.colorGradient.Evaluate(0f);
|
||||
|
||||
renderer.GetPropertyBlock(propBlock);
|
||||
// 对应 Shader 中的属性
|
||||
propBlock.SetColor("_HeadColor", headColor);
|
||||
propBlock.SetColor("_TailColor", tailColor);
|
||||
propBlock.SetVector("_MoveDir", moveDir);
|
||||
// 用缓存的属性 ID(避免每帧字符串查找)
|
||||
propBlock.SetColor(_headColorId, headColor);
|
||||
propBlock.SetColor(_tailColorId, tailColor);
|
||||
propBlock.SetVector(_moveDirId, moveDir);
|
||||
renderer.SetPropertyBlock(propBlock);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user