Files
2026-07-30 23:15:58 +08:00

92 lines
2.9 KiB
C#

using UnityEngine;
/// <summary>
/// 挂在被 GfxController 池化的特效实例上,记录它来自哪个 prefab,
/// 并在复用前把会被逐次修改的可视状态(粒子起始色/循环、拖尾渐变、材质属性块)
/// 还原到首次实例化时的原始值,保证复用后的视觉与 Instantiate 全新实例完全等价。
/// </summary>
public class GfxPooledItem : MonoBehaviour
{
public GameObject prefabKey;
public GfxController owner;
// 防止同一实例被重复回收(粒子回调 + 计时回收等路径)。
[System.NonSerialized] public bool released;
private ParticleSystem[] _particles;
private ParticleSystem.MinMaxGradient[] _origStartColors;
private bool[] _origLoops;
private TrailRenderer[] _trails;
private Gradient[] _origTrailGradients;
private Renderer[] _renderers;
private bool _captured;
/// <summary>首次实例化后调用一次,快照原始可视状态。</summary>
public void CaptureOriginals()
{
_particles = GetComponentsInChildren<ParticleSystem>(true);
_origStartColors = new ParticleSystem.MinMaxGradient[_particles.Length];
_origLoops = new bool[_particles.Length];
for (int i = 0; i < _particles.Length; i++)
{
var main = _particles[i].main;
_origStartColors[i] = main.startColor;
_origLoops[i] = main.loop;
}
_trails = GetComponentsInChildren<TrailRenderer>(true);
_origTrailGradients = new Gradient[_trails.Length];
for (int i = 0; i < _trails.Length; i++)
{
_origTrailGradients[i] = CloneGradient(_trails[i].colorGradient);
}
_renderers = GetComponentsInChildren<Renderer>(true);
_captured = true;
}
/// <summary>复用前还原到原始状态。</summary>
public void ResetToOriginal()
{
if (!_captured) return;
for (int i = 0; i < _particles.Length; i++)
{
if (_particles[i] == null) continue;
var main = _particles[i].main;
main.startColor = _origStartColors[i];
main.loop = _origLoops[i];
}
for (int i = 0; i < _trails.Length; i++)
{
if (_trails[i] == null) continue;
_trails[i].Clear();
_trails[i].colorGradient = CloneGradient(_origTrailGradients[i]);
}
for (int i = 0; i < _renderers.Length; i++)
{
if (_renderers[i] != null) _renderers[i].SetPropertyBlock(null);
}
}
// 粒子播放完毕(root 的 stopAction 设为 Callback)时回收整个特效。
private void OnParticleSystemStopped()
{
if (owner != null) owner.ReleaseFx(gameObject);
}
private static Gradient CloneGradient(Gradient src)
{
if (src == null) return null;
var g = new Gradient();
g.SetKeys(src.colorKeys, src.alphaKeys);
g.mode = src.mode;
return g;
}
}