using UnityEngine; using UnityEngine.Events; using System.Collections; using System.Collections.Generic; public enum EffectPlayTypes { None = 0, Oneshot, Loop, } public static class TransformEx { public static void DoRecursively(this Transform root, System.Action action, bool containMe = true) { if (containMe) action(root); foreach (Transform child in root) child.DoRecursively(action); } } public struct PlayEffectInfo { public string path { get; set; } public Transform rootTr { get; set; } public bool bAttached { get; set; } public Vector3 posOffset { get; set; } public Vector3 rot { get; set; } public Vector3 scale { get; set; } public EffectPlayTypes playEffectType { get; set; } } public class FxClear : MonoBehaviour { [SerializeField] public float ClearTime = 2f; private EffectPlayTypes m_EffectPlayType = EffectPlayTypes.None; private Transform m_Root = null; //根节点,可以是角色或者某个骨骼,如果是空,代表是世界空间 private bool m_Attached = false; // 跟随根节点运动 private Vector3 m_Offset = Vector3.zero; private Vector3 m_Rotation = Vector3.zero; private Vector3 m_Scale = Vector3.one; private Quaternion m_RootRot = Quaternion.identity; private Vector3 m_RootPos = Vector3.zero; #if UNITY_EDITOR private double m_PrevTime = 0.0f; private float m_RemoveWaitTime = 0.0f; private bool m_DestroyRequested = false; #endif private float m_CurTime = 0.0f; public float time { get { return m_CurTime; } } private void Awake() { if (ClearTime <= float.Epsilon) m_EffectPlayType = EffectPlayTypes.Loop; } private void Start() { } private void OnDestroy() { Release(); } public void Initialize(PlayEffectInfo info) { m_EffectPlayType = info.playEffectType; m_Root = info.rootTr; m_CurTime = 0.0f; m_Offset = info.posOffset; m_Rotation = info.rot; m_Scale = info.scale; m_Attached = info.bAttached; if(info.rootTr != null) { m_RootPos = info.rootTr.transform.position; m_RootRot = info.rootTr.transform.rotation; } SyncTr(); gameObject.SetActive(true); } public void Release() { m_Root = null; m_CurTime = 0.0f; m_Attached = false; m_Offset = Vector3.zero; m_Rotation = Vector3.zero; m_Scale = Vector3.zero; } // 同步特效的缩放、旋转和位置 private void SyncTr() { if (transform == null || transform.gameObject == null) return; if (m_Scale != Vector3.zero) { transform.localScale = m_Scale; } if (m_Root == null) // 世界空间 { transform.position = m_Offset; transform.rotation = Quaternion.Euler(m_Rotation); } else { if (m_Attached) { transform.rotation = m_Root.rotation * Quaternion.Euler(m_Rotation); transform.position = m_Root.TransformPoint(m_Offset); } else { transform.rotation = m_RootRot * Quaternion.Euler(m_Rotation); transform.position = m_RootPos + (m_Root.rotation * m_Offset); } } } public void Restore() { DestroyImmediate(this.gameObject); } public void UpdateFunc(float dt) { m_CurTime += dt; SyncTr(); if (m_EffectPlayType != EffectPlayTypes.Loop && m_CurTime >= ClearTime) { Restore(); return; } } private void Update() { UpdateFunc(Time.unscaledDeltaTime); } }