using UnityEngine; /// /// 挂在被 GfxController 池化的特效实例上,记录它来自哪个 prefab, /// 并在复用前把会被逐次修改的可视状态(粒子起始色/循环、拖尾渐变、材质属性块) /// 还原到首次实例化时的原始值,保证复用后的视觉与 Instantiate 全新实例完全等价。 /// 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; /// 首次实例化后调用一次,快照原始可视状态。 public void CaptureOriginals() { _particles = GetComponentsInChildren(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(true); _origTrailGradients = new Gradient[_trails.Length]; for (int i = 0; i < _trails.Length; i++) { _origTrailGradients[i] = CloneGradient(_trails[i].colorGradient); } _renderers = GetComponentsInChildren(true); _captured = true; } /// 复用前还原到原始状态。 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; } }