好多新内容

This commit is contained in:
FloatGaming
2026-07-22 05:35:53 +08:00
parent b5d1cdcbc5
commit 15649d02f8
128 changed files with 5956 additions and 673 deletions
@@ -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);
}