yyl
2025-07-21 5bc2cc9a3e007b96a0de96e70e87f25bc5a254a2
Main/Component/UI/Effect/EffectPlayer.cs
@@ -1,26 +1,33 @@
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);
@@ -30,9 +37,12 @@
    public void Play()
    {
        if (!isActiveAndEnabled)
        {
            gameObject.SetActive(true);
        }
        ReStart();
    }
    protected void ReStart()
@@ -80,7 +90,7 @@
        }
        // 添加特效穿透阻挡器
        EffectPenetrationBlocker blocker = effectTarget.AddComponent<EffectPenetrationBlocker>();
        blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>();
        blocker.parentCanvas = canvas;
        //  延迟一帧才生效
@@ -95,4 +105,141 @@
        }
    }
    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;
    }
}