using System; 
 | 
using System.Collections; 
 | 
using System.Collections.Generic; 
 | 
using Spine.Unity; 
 | 
using UnityEngine; 
 | 
using Spine; 
 | 
using UnityEngine.UI; 
 | 
using Cysharp.Threading.Tasks; 
 | 
  
 | 
//UI特效播放器,spine特效直接加载无需提前做预制体 
 | 
//UI特效大部分情况不会改变特效,无需销毁 
 | 
public class UIEffectPlayer : EffectPlayer 
 | 
{ 
 | 
    [Header("是否循环播放spine特效")] 
 | 
    public bool isPlaySpineLoop = false; 
 | 
  
 | 
    [Header("是否在显示时播放")] 
 | 
    public bool isPlayOnEnable = false; 
 | 
  
 | 
    [Header("延迟播放(毫秒)")] 
 | 
    public int playDelayTime = 0; 
 | 
  
 | 
    int playSpineAnimIndex = -1; //播放spine特效动画索引, 
 | 
  
 | 
  
 | 
  
 | 
    protected override void OnEnable() 
 | 
    { 
 | 
        playSpineAnimIndex = -1; 
 | 
        if (isPlayOnEnable) 
 | 
        { 
 | 
            PlayAsync(false).Forget(); 
 | 
        } 
 | 
        else if (spineComp != null) 
 | 
        { 
 | 
            if (!isPlaying) 
 | 
            { 
 | 
                //隐藏,会有静态显示问题 
 | 
                spineComp.enabled = false; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public override void Play(bool showLog = true) 
 | 
    { 
 | 
        isPlaying = true; 
 | 
        if (!isInit) 
 | 
        { 
 | 
            InitComponent(showLog); 
 | 
            //effeid 为0也初始化成功,避免重复处理,在变更effectid时会重新初始化 
 | 
            isInit = true; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            //避免重复创建 
 | 
            if (!this.gameObject.activeSelf) 
 | 
            { 
 | 
                this.gameObject.SetActive(true); 
 | 
            } 
 | 
            //防范effeid 为0 
 | 
            if (effectConfig != null && effectConfig.isSpine != 0) 
 | 
            { 
 | 
                PlayerTheSpineAnim(); 
 | 
            } 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        if (EffectMgr.IsNotShowBySetting(effectId)) 
 | 
        { 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        if (null != effectTarget) 
 | 
        { 
 | 
            if (pool != null) 
 | 
                pool.Release(effectTarget); 
 | 
            effectTarget = null; 
 | 
        } 
 | 
  
 | 
        if (!this.gameObject.activeSelf) 
 | 
        { 
 | 
            this.gameObject.SetActive(true); 
 | 
        } 
 | 
  
 | 
        // 加载spine特效资源 
 | 
        if (effectConfig.isSpine != 0) 
 | 
        { 
 | 
            PlaySpineEffect(); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            PlayerEffect(false); 
 | 
        } 
 | 
        SoundPlayer.Instance.PlayUIAudio(effectConfig.audio); 
 | 
    } 
 | 
  
 | 
  
 | 
    protected override void PlaySpineEffect() 
 | 
    { 
 | 
        if (spineComp == null) 
 | 
        { 
 | 
            spineComp = gameObject.AddMissingComponent<SkeletonGraphic>(); 
 | 
        } 
 | 
  
 | 
        if (spineComp.skeletonDataAsset == null) 
 | 
        { 
 | 
            //LoadAsset 已经有缓存SkeletonDataAsset 
 | 
            spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName); 
 | 
            spineComp.raycastTarget = false; 
 | 
            spineComp.Initialize(true); 
 | 
  
 | 
            // 检查动画是否有相加模式 
 | 
            bool hasAdditiveBlend = CheckForAdditiveBlend(spineComp.Skeleton); 
 | 
            if (hasAdditiveBlend) 
 | 
            { 
 | 
                spineComp.material = ResManager.Instance.LoadAsset<Material>("UIEffect/" + effectConfig.packageName, effectConfig.fxName.Split('_')[0] + "_Material-Additive"); 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                spineComp.material = null; 
 | 
            } 
 | 
  
 | 
            spineAnimationState = spineComp.AnimationState; 
 | 
            spineAnimationState.Data.DefaultMix = 0f; 
 | 
            spineAnimationState.Complete -= OnSpineAnimationComplete; 
 | 
            spineAnimationState.Complete += OnSpineAnimationComplete; 
 | 
        } 
 | 
  
 | 
        spineComp.enabled = true; 
 | 
        PlayerTheSpineAnim(); 
 | 
    } 
 | 
  
 | 
    private bool CheckForAdditiveBlend(Spine.Skeleton skeleton) 
 | 
    { 
 | 
        // 遍历所有插槽,检查是否有相加模式 
 | 
        foreach (var slot in skeleton.Slots) 
 | 
        { 
 | 
            if (slot.Data.BlendMode == Spine.BlendMode.Additive) 
 | 
            { 
 | 
                return true; 
 | 
            } 
 | 
        } 
 | 
        return false; 
 | 
    } 
 | 
  
 | 
    public void Play(int index, bool showLog = true) 
 | 
    { 
 | 
        playSpineAnimIndex = index; 
 | 
        PlayAsync(showLog).Forget(); 
 | 
    } 
 | 
  
 | 
    async UniTask PlayAsync(bool showLog = true) 
 | 
    { 
 | 
        await UniTask.Delay(playDelayTime); 
 | 
        Play(showLog); 
 | 
    } 
 | 
  
 | 
    // 播放指定动画 
 | 
    void PlayerTheSpineAnim() 
 | 
    { 
 | 
        spineComp.enabled = true; 
 | 
        var skeletonData = spineComp.Skeleton.Data; 
 | 
        if (skeletonData.Animations.Count > 0) 
 | 
        { 
 | 
            string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? effectConfig.animIndex : playSpineAnimIndex].Name; 
 | 
            spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            Debug.LogError("Spine 数据中没有找到任何动画!" + effectConfig.id); 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
  
 | 
    //单次播放完毕就会触发,即使是循环 
 | 
    protected override void OnSpineAnimationComplete(Spine.TrackEntry trackEntry) 
 | 
    { 
 | 
        if (!isPlaySpineLoop) 
 | 
        { 
 | 
            spineComp.enabled = false; 
 | 
            isPlaying = false; 
 | 
            if (isReleaseImmediately) 
 | 
            { 
 | 
                Stop(); 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                onComplete?.Invoke(); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
  
 | 
    //  创建后的特效会自动隐藏 需要手动调用Play才能播放 
 | 
    public static UIEffectPlayer CreateEffect(int effectId, Transform parent, bool createNewChild = false) 
 | 
    { 
 | 
        UIEffectPlayer effectPlayer = null; 
 | 
  
 | 
        if (createNewChild) 
 | 
        { 
 | 
            GameObject newGo = new GameObject("EffectPlayer_" + effectId); 
 | 
            newGo.transform.SetParent(parent, false); 
 | 
            effectPlayer = newGo.AddComponent<UIEffectPlayer>(); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            effectPlayer = parent.AddMissingComponent<UIEffectPlayer>(); 
 | 
            effectPlayer.effectId = effectId; 
 | 
        } 
 | 
        effectPlayer.SetActive(true); 
 | 
        return effectPlayer; 
 | 
    } 
 | 
  
 | 
  
 | 
} 
 |