using System; using System.Collections.Generic; using Cielonos.MainGame.Characters; using Lean.Pool; using Sirenix.OdinInspector; using SLSUtilities.LeanPoolAssistance; using UnityEngine; namespace Cielonos.MainGame { public class VFXObject : PooledObject { [NonSerialized] public CharacterBase creator; public bool affectedByCreatorTimeScale = true; public float DeltaTime => affectedByCreatorTimeScale && creator != null ? creator.selfTimeSm.DeltaTime : Time.deltaTime; public float TimeScale => affectedByCreatorTimeScale && creator != null ? creator.selfTimeSm.TimeScale : 1f; public List particles = new List(); [Tooltip("需要特殊标记的部分")] public Dictionary parts = new Dictionary(); [NonSerialized] private List particleMainModules; [NonSerialized] private bool _isWaitingToDespawn = false; public static GameObject Spawn(GameObject vfxPrefab, CharacterBase creator, Transform parent = null) { VFXObject vfxObject = LeanPool.Spawn(vfxPrefab, parent).GetComponent(); vfxObject.SetCreator(creator); return vfxObject.gameObject; } public static GameObject Spawn(GameObject vfxPrefab, CharacterBase creator, Vector3 position, Quaternion rotation, Transform parent = null) { VFXObject vfxObject = LeanPool.Spawn(vfxPrefab, position, rotation, parent).GetComponent(); vfxObject.SetCreator(creator); return vfxObject.gameObject; } private void Reset() { CollectParticles(); } public override void OnSpawn() { if (spawnExecuted) { return; } base.OnSpawn(); _isWaitingToDespawn = false; particleMainModules = new List(); foreach (var ps in particles) { particleMainModules.Add(ps.main); } } [Button("Collect Particles")] private void CollectParticles() { particles.Clear(); ParticleSystem[] foundParticles = GetComponentsInChildren(); foreach (var ps in foundParticles) { particles.Add(ps); } } /// /// 停止发射粒子并等待现存粒子全部消散后,再将该特效放入池中。 /// public void StopAndDespawn() { if (particles == null || particles.Count == 0) { LeanPool.Despawn(gameObject); return; } foreach (var ps in particles) { ps.Stop(true, ParticleSystemStopBehavior.StopEmitting); } // 标记为正在等待自动销毁,交由 Update 去检测粒子存活状态 _isWaitingToDespawn = true; } protected override void Update() { if (_isWaitingToDespawn) { bool anyAlive = false; for (int i = 0; i < particles.Count; i++) { if (particles[i] != null && particles[i].IsAlive(true)) { anyAlive = true; break; } } if (!anyAlive) { _isWaitingToDespawn = false; LeanPool.Despawn(gameObject); return; // 提前返回,不再执行后续的时间更新 } } UpdateTimer(DeltaTime); if (affectedByCreatorTimeScale) { particleMainModules.ForEach(main => main.simulationSpeed = TimeScale); } } public void SetCreator(CharacterBase character) { creator = character; } } }