using System.Collections.Generic; using UnityEngine; /// /// 印记效果控制器 /// // 由于常规特效ParticleCleaner需要Hack的部分太多,暂时通过全面重写的方式实现重用特效系统 public class MarkSfxController : MonoBehaviour, IParticleCleaner { public float DelayRecoveryTime { get { return IsDetonated ? delayTime : 0f; } } public float delayTime = 1.033f; private readonly List _cloneList = new List(); private float _currentRotation; private bool _clean; public float rotateSpeed = 540f; public GameObject source; public int TargetCount { get; set; } private int _currentCount; public bool IsDetonated { get; private set; } private void Start() { source.SetActive(false); CleanState(); } private void Update() { if (_clean) { _clean = false; CleanState(); } } private void CleanState() { IsDetonated = false; for (var i = 0; i < _cloneList.Count; i++) _cloneList[i].Detonate(false); } private void OnDisable() { _clean = true; IsDetonated = false; _currentCount = 0; for (var i = 0; i < _cloneList.Count; i++) { _cloneList[i].Clean(); _cloneList[i].gameObject.SetActive(false); } } private void LateUpdate() { if (!IsDetonated) { _currentRotation += rotateSpeed * Time.deltaTime; _currentRotation = CommonUtility.LoopFloat(_currentRotation, 0f, 360f); if (TargetCount != _currentCount) { _currentCount = TargetCount; for (var i = _cloneList.Count; i < _currentCount; i++) { var cloneObj = Instantiate(source); cloneObj.transform.SetParent(source.transform.parent, false); var clone = new MarkSfxCloneController(cloneObj); _cloneList.Add(clone); } for (var i = 0; i < _cloneList.Count; i++) _cloneList[i].gameObject.SetActive(i < _currentCount); } } for (var i = 0; i < _currentCount; i++) _cloneList[i].SetRotation(_currentRotation + i * 360f / _currentCount); } public void Detonate(bool isDetonate) { IsDetonated = isDetonate; // 特殊处理,反激活爆破由Clean来处理 for (var i = 0; i < _currentCount; i++) _cloneList[i].Detonate(isDetonate); } public void StartDelayRecovery() { } } public class MarkSfxCloneController { public const string idleEffect = "Idle"; public const string activeEffect = "Active"; private readonly GameObject _activeObject; private readonly GameObject _idleObject; private readonly Animator _markAnimator; public readonly GameObject gameObject; public MarkSfxCloneController(GameObject gameObject) { this.gameObject = gameObject; _markAnimator = gameObject.GetComponentInChildren(); var idleTransform = gameObject.transform.Find(idleEffect); var activeTransform = gameObject.transform.Find(activeEffect); if (idleTransform != null) _idleObject = idleTransform.gameObject; if (activeTransform != null) _activeObject = activeTransform.gameObject; } public void SetRotation(float degree) { var targetRotation = Quaternion.Euler(0f, degree, 0f); gameObject.transform.localRotation = targetRotation; } public void Detonate(bool isDetonate) { if (isDetonate && _markAnimator != null) _markAnimator.SetBool("Detonate", true); if (_idleObject != null) _idleObject.SetActive(!isDetonate); if (_activeObject != null) _activeObject.SetActive(isDetonate); } /// /// 反激活时清空状态 /// public void Clean() { //if (_markAnimator != null) // _markAnimator.SetBool("Detonate", false); if (_idleObject != null) _idleObject.SetActive(false); if (_activeObject != null) _activeObject.SetActive(false); } }