| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using Spine.Unity; |
| | | using UnityEngine; |
| | | using Spine; |
| | | |
| | | public class EffectPlayer : MonoBehaviour |
| | | { |
| | | public int effectId; |
| | | public int effectId; |
| | | |
| | | public bool autoDestroy = false; |
| | | public bool autoDestroy = false; |
| | | |
| | | public float destroyDelay = 0f; |
| | | public float destroyDelay = 0f; |
| | | |
| | | [HideInInspector] public Canvas canvas = null; |
| | | public Action<EffectPlayer> onDestroy; |
| | | |
| | | [HideInInspector] public Canvas canvas = null; |
| | | |
| | | [HideInInspector] public GameObject effectTarget = null; |
| | | |
| | | protected EffectPenetrationBlocker blocker = null; |
| | | |
| | | protected void Start() |
| | | { |
| | | { |
| | | ReStart(); |
| | | } |
| | | |
| | | public void Stop() |
| | | { |
| | | { |
| | | if (null != effectTarget) |
| | | { |
| | | DestroyImmediate(effectTarget); |
| | |
| | | |
| | | public void Play() |
| | | { |
| | | if (!isActiveAndEnabled) |
| | | { |
| | | gameObject.SetActive(true); |
| | | } |
| | | ReStart(); |
| | | } |
| | | |
| | | |
| | | |
| | | protected void ReStart() |
| | |
| | | } |
| | | |
| | | // 添加特效穿透阻挡器 |
| | | EffectPenetrationBlocker blocker = effectTarget.AddComponent<EffectPenetrationBlocker>(); |
| | | blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>(); |
| | | blocker.parentCanvas = canvas; |
| | | |
| | | // 延迟一帧才生效 |
| | |
| | | } |
| | | } |
| | | |
| | | public void SetSortingOrderOffset(int offset) |
| | | { |
| | | // 被Destroy之后effectTarget == null 为 true 但是访问内容会报错 |
| | | if (blocker != null && effectTarget != null) |
| | | { |
| | | blocker.sortingOrderOffset = offset; |
| | | blocker.UpdateSortingOrder(); |
| | | } |
| | | else |
| | | { |
| | | blocker = null; |
| | | effectTarget = null; |
| | | } |
| | | } |
| | | |
| | | protected void OnDestroy() |
| | | { |
| | | if (onDestroy != null) |
| | | { |
| | | onDestroy.Invoke(this); |
| | | onDestroy = null; |
| | | } |
| | | } |
| | | |
| | | // 创建后的特效会自动隐藏 需要手动调用Play才能播放 |
| | | public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false, bool _autoDestroy = true, float _destroyDelay = 5f) |
| | | { |
| | | EffectPlayer effectPlayer = null; |
| | | |
| | | if (createNewChild) |
| | | { |
| | | GameObject newGo = new GameObject("EffectPlayer_" + effectId); |
| | | newGo.transform.SetParent(parent, false); |
| | | effectPlayer = newGo.AddComponent<EffectPlayer>(); |
| | | } |
| | | else |
| | | { |
| | | effectPlayer = parent.AddMissingComponent<EffectPlayer>(); |
| | | effectPlayer.effectId = effectId; |
| | | effectPlayer.autoDestroy = _autoDestroy; |
| | | effectPlayer.destroyDelay = _destroyDelay; |
| | | } |
| | | effectPlayer.SetActive(false); |
| | | return effectPlayer; |
| | | } |
| | | |
| | | public void Pause() |
| | | { |
| | | if (effectTarget == null) return; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | sg.timeScale = 0f; |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | animator.speed = 0f; |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | ps.Pause(); |
| | | } |
| | | } |
| | | |
| | | public void Resume() |
| | | { |
| | | if (effectTarget == null) return; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | sg.timeScale = 1f; |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | animator.speed = 1f; |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | ps.Play(); |
| | | } |
| | | } |
| | | |
| | | public bool IsFinish() |
| | | { |
| | | if (effectTarget == null) return true; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | if (!sg.AnimationState.GetCurrent(0).IsComplete) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); |
| | | |
| | | // 循环动画不考虑结束的问题 |
| | | if (!stateInfo.loop && stateInfo.normalizedTime < 1f) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | if (ps.IsAlive()) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | } |