From cd577d03019b1a399b29e18c802a97ce665daec6 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期五, 05 九月 2025 11:55:51 +0800
Subject: [PATCH] 50 【主界面】核心主体 - 增加等级功能开启限制 153 【武将】招募系统 - 免费次数显示和

---
 Main/Component/UI/Effect/EffectPlayer.cs |  470 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 334 insertions(+), 136 deletions(-)

diff --git a/Main/Component/UI/Effect/EffectPlayer.cs b/Main/Component/UI/Effect/EffectPlayer.cs
index d7ca3fc..ceeddc6 100644
--- a/Main/Component/UI/Effect/EffectPlayer.cs
+++ b/Main/Component/UI/Effect/EffectPlayer.cs
@@ -5,25 +5,54 @@
 using UnityEngine;
 using Spine;
 using UnityEngine.UI;
+using Cysharp.Threading.Tasks;
 
+// 鐗规晥鎾斁鍣紝棰勫埗浣撳璞℃睜绠$悊锛寀nity鐨勯鍒朵綋姹犱娇鐢ㄦ湁闂锛�1涓壒鏁�1涓睜浣嗗鐢ㄥ張浣庯級鍚庣画淇敼
+// unity鐗规晥銆婇鍒朵綋銆嬫槸鐗规晥甯堝湪鍒朵綔鐨勬椂鍊欑敓鎴愮殑涓嶅悓棰勫埗浣擄紝unity鐗规晥蹇呴』鎸傝浇璁剧疆鎾斁鏃堕暱鑴氭湰 EffectTime
+// spine鐗规晥鏄壒鏁堝笀鍒朵綔鐨勫姩鐢绘枃浠讹紝鍙叡鍚屽鐢ㄤ竴涓�婇鍒朵綋銆�
 public class EffectPlayer : MonoBehaviour
 {
-    public int effectId;
+    [SerializeField]
+    private int m_EffectID;
+    public int effectId
+    {
+        get
+        {
+            return m_EffectID;
+        }
+        set
+        {
+            if (value != m_EffectID)
+            {
+                Stop();
+                isInit = false;
+                m_EffectID = value;
+            }
+        }
+    }
+
+
 
     public EffectConfig effectConfig;
 
-    public Action<EffectPlayer> onDestroy;
-    public Action onComplete;
-
     public float speedRate = 1f;
+
+    [Header("鏄惁寰幆鎾斁spine鐗规晥")]
+    public bool isPlaySpineLoop = false;
 
     [Header("鏄惁鍦ㄦ樉绀烘椂鎾斁")]
     public bool isPlayOnEnable = false;
 
-    [Header("鏄惁绔嬪嵆鎾斁spine鐗规晥")]
-    public bool isPlaySpineImmediately = false;  
-    [Header("鏄惁寰幆鎾斁spine鐗规晥")]
-    public bool isPlaySpineLoop = false; 
+    [Header("寤惰繜鎾斁(姣)")]
+    public int playDelayTime = 0;
+
+    public int playSpineAnimIndex = -1; //鎾斁spine鐗规晥鍔ㄧ敾绱㈠紩,浠g爜鎺у埗
+
+
+    [Header("鎾斁瀹屾瘯绔嬪嵆鍥炴敹")]
+    public bool isReleaseImmediately = false;  //鐣岄潰鐗规晥涓�鑸笉闇�瑕佽嚜鎴戦攢姣侊紝璺熼殢鐣岄潰鎴栬�呯埗瀵硅薄閿�姣佸氨琛�
+
+    public Action<EffectPlayer> onDestroy;
 
     [HideInInspector] public Canvas canvas = null;
 
@@ -32,6 +61,7 @@
     protected EffectPenetrationBlocker blocker = null;
 
     protected bool isInit = false;
+    protected bool isPlaying = false;
 
     protected List<ParticleSystem> particleList = new List<ParticleSystem>();
 
@@ -42,150 +72,257 @@
     protected SkeletonGraphic spineComp;
     protected Spine.AnimationState spineAnimationState;
 
-    protected void OnEnable()
+    public GameObjectPoolManager.GameObjectPool pool;
+
+    public Action onComplete;
+
+    protected virtual void OnEnable()
     {
+        
         if (isPlayOnEnable)
         {
-            Play();
+            Play(false);
+        }
+        else if (spineComp != null)
+        {
+            if (!isPlaying)
+            {
+                //闅愯棌锛屼細鏈夐潤鎬佹樉绀洪棶棰�
+                spineComp.enabled = false;
+            }
         }
     }
 
-    protected bool InitCompnent()
+    protected void InitComponent(bool showLog = true)
     {
         if (effectId <= 0)
         {
             effectConfig = null;
-            // 鏍规嵁閫昏緫闇�姹傦紝鍔ㄦ�佽缃壒鏁堢殑鎯呭喌
-            // Debug.LogError("EffectPlayer effectId is not set");
-            // #if UNITY_EDITOR
-            //             UnityEditor.Selection.activeGameObject = gameObject;
-            //             UnityEditor.EditorGUIUtility.PingObject(gameObject);
-            // #endif
-            return false;
+#if UNITY_EDITOR
+            if (showLog)
+            {
+                Debug.LogError("EffectPlayer effectId is not set");
+                UnityEditor.Selection.activeGameObject = gameObject;
+                UnityEditor.EditorGUIUtility.PingObject(gameObject);
+            }
+#endif
+            return;
         }
 
         effectConfig = EffectConfig.Get(effectId);
 
         if (null == effectConfig)
         {
-            Debug.LogError("could not find effect config, effect id is " + effectId);
 #if UNITY_EDITOR
+            Debug.LogError("could not find effect config, effect id is " + effectId);
             UnityEditor.Selection.activeGameObject = gameObject;
             UnityEditor.EditorGUIUtility.PingObject(gameObject);
 #endif
-            return false;
-        }
-
-
-        particleList.Clear();
-        animatorList.Clear();
-        rendererList.Clear();
-        spineComp = null;
-
-        //spine鏄姞杞芥枃浠讹紝闇�瑕佹彁鍓嶆寕杞借剼鏈紝unity鐗规晥鏄凡缁忓仛濂界殑棰勫埗浣撳緟鍔犺浇鍚庢敹闆嗙粍浠�
-        if (effectConfig.isSpine != 0)
-        {
-            spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
-
-        }
-        // else
-        // {
-        //     //  鏀堕泦缁勪欢
-        //     particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
-        //     animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
-        // }
-        // rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
-
-        return true;
-    }
-
-    public void Stop()
-    {
-        if (null != effectTarget)
-        {
-            DestroyImmediate(effectTarget);
-            effectTarget = null;
-        }
-
-        isInit = false;
-
-        particleList.Clear();
-        animatorList.Clear();
-        rendererList.Clear();
-        spineComp = null;
-    }
-
-    public void Play()
-    {
-        ReStart();
-    }
-
-
-    protected void ReStart()
-    {
-        if (!isInit)
-        {
-            if (InitCompnent())
-            {
-                isInit = true;
-            }
-            else
-            {
-                //鏍规嵁閫昏緫闇�姹傦紝鍔ㄦ�佽缃壒鏁堢殑鎯呭喌
-                return;
-            }
-
-        }
-
-        if (EffectMgr.Instance.IsNotShowBySetting(effectId))
-        {
             return;
         }
 
+        Clear();
+        return;
+    }
+
+    protected virtual void Clear()
+    {
+        isInit = false;
+        particleList.Clear();
+        animatorList.Clear();
+        rendererList.Clear();
+
+        if (spineComp != null)
+        {
+            spineComp.skeletonDataAsset = null;
+            // spineComp.Initialize(false);    
+            spineComp.Clear();
+        }
+
+        spineComp = null;
+    }
+
+    public virtual void Stop()
+    {
         if (null != effectTarget)
         {
-            DestroyImmediate(effectTarget);
+            // 濡傛灉浣跨敤浜嗙壒鏁堥鍒朵綋姹狅紝鍒欏綊杩樺埌姹犱腑
+            if (pool != null)
+            {
+                pool.Release(effectTarget);
+            }
+            effectTarget = null;
+        }
+        if (spineComp != null)
+        {
+            spineComp.enabled = false;
+        }
+        isPlaying = false;
+        playSpineAnimIndex = -1;
+    }
+
+    protected void Release()
+    {
+        Stop();
+
+        Clear();
+    }
+
+    public virtual void Play(bool showLog = true, bool closePMA = false)
+    {
+        isPlaying = true;
+        if (!isInit)
+        {
+            InitComponent(showLog);
+            //effeid 涓�0涔熷垵濮嬪寲鎴愬姛锛岄伩鍏嶉噸澶嶅鐞嗭紝鍦ㄥ彉鏇磂ffectid鏃朵細閲嶆柊鍒濆鍖�
+            isInit = true;
+        }
+        else
+        {
+            //閬垮厤閲嶅鍒涘缓
+            if (!this.gameObject.activeSelf)
+            {
+                this.gameObject.SetActive(true);
+            }
+            //闃茶寖effeid 涓�0
+            if (effectConfig != null && effectConfig.isSpine != 0)
+            {
+                PlaySpineEffect(closePMA);
+            }
+            return;
+        }
+        if (effectConfig == null)
+            return;
+
+        if (EffectMgr.IsNotShowBySetting(effectId))
+            {
+                return;
+            }
+
+        if (null != effectTarget)
+        {
+            if (pool != null)
+                pool.Release(effectTarget);
             effectTarget = null;
         }
 
-        //	YYL TODO
-        //	鍦ㄨ繖閲岃�冭檻鐢ㄦ睜鐨勮瘽鍙兘璧伴厤缃ソ涓�鐐� 鍘熸湰鐨勬槸鏃犺濡備綍閮借蛋姹� 浣嗘槸瀹為檯涓婃湁浜涚壒鏁堝苟涓嶉渶瑕�
+        if (!this.gameObject.activeSelf)
+        {
+            this.gameObject.SetActive(true);
+        }
 
         // 鍔犺浇spine鐗规晥璧勬簮
         if (effectConfig.isSpine != 0)
         {
-            spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName + "_SkeletonData");
-            spineComp.raycastTarget = false;
-            spineComp.Initialize(true);
-            spineAnimationState = spineComp.AnimationState;
-            spineAnimationState.Complete -= OnSpineAnimationComplete;
-            spineAnimationState.Complete += OnSpineAnimationComplete;
-            if (isPlaySpineImmediately)
-            {
-                //UI鐗规晥甯哥敤鏂瑰紡
-                spineComp.enabled = true;
-                // 鎾斁绗竴涓姩鐢伙紙浣滀负榛樿鍔ㄧ敾锛�
-                var skeletonData = spineComp.Skeleton.Data;
-                if (skeletonData.Animations.Count > 0)
-                {
-                    string defaultAnimationName = skeletonData.Animations.Items[0].Name;
-                    spineComp.AnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
-                }
-                else
-                {
-                    Debug.LogError("Spine 鏁版嵁涓病鏈夋壘鍒颁换浣曞姩鐢伙紒" + effectConfig.id);
-                }
-            }
-            else
-            {
-                spineComp.enabled = false;
-            }
+            PlaySpineEffect(closePMA);
+        }
+        else
+        {
+            PlayerEffect();
+        }
+    
+        SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
 
-            
-            return;
+    }
+
+
+    // protected virtual void PlaySpineEffect()
+    // {
+    //     spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true);
+    //     spineComp.raycastTarget = false;
+    //     spineComp.Initialize(true);
+    //     spineAnimationState = spineComp.AnimationState;
+    //     spineAnimationState.Complete -= OnSpineAnimationComplete;
+    //     spineAnimationState.Complete += OnSpineAnimationComplete;
+
+    //     // 澶栧眰鎺у埗鍏蜂綋鎾斁鍝釜鍔ㄧ敾
+    //     spineComp.enabled = true;
+
+    //     return;
+    // }
+
+
+
+    protected void PlaySpineEffect(bool closePMA = false)
+    {
+
+        // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
+        if (spineComp == null)
+        { 
+            spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
         }
 
-        //鍔犺浇unity鐗规晥
+        if (spineComp.skeletonDataAsset == null || spineAnimationState == null)
+        {
+            //LoadAsset 宸茬粡鏈夌紦瀛楽keletonDataAsset
+            spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
+            spineComp.MeshGenerator.settings.pmaVertexColors = !closePMA;   //涓簍rue鏃朵細鏈夐儴鍒嗙壒鏁堜笉鏄剧ず 濡備富鐣岄潰瑁呭鐗规晥
+            spineComp.raycastTarget = false;
+            spineComp.Initialize(true);
+            spineComp.timeScale = speedRate;
+            // 妫�鏌ュ姩鐢绘槸鍚︽湁鐩稿姞妯″紡
+            // 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;
+            // }
+            spineComp.material = ResManager.Instance.LoadAsset<Material>("Materials", "SkeletonGraphicDefault-Straight");
+
+            spineAnimationState = spineComp.AnimationState;
+            spineAnimationState.Data.DefaultMix = 0f;
+            spineAnimationState.Complete -= OnSpineAnimationComplete;
+            spineAnimationState.Complete += OnSpineAnimationComplete;
+        }
+
+        spineComp.enabled = true;
+        PlayerTheSpineAnim();
+    }
+
+        // 鎾斁鎸囧畾鍔ㄧ敾
+    void PlayerTheSpineAnim()
+    {
+        spineComp.enabled = true;
+        var skeletonData = spineComp.Skeleton.Data;
+        if (skeletonData.Animations.Count > 0)
+        {
+            //鎸夐厤缃垨鑰呴粯璁ょ涓�涓�
+            int defaultAnimIndex = Math.Max(0, effectConfig.animIndex.Length == 0 ? 0 : effectConfig.animIndex[0]);
+            if (playSpineAnimIndex >= skeletonData.Animations.Count)
+            {
+                playSpineAnimIndex = -1;
+                Debug.LogError("鐗规晥锛�" + effectConfig.id + " 绱㈠紩瓒呭嚭鎾斁榛樿鍔ㄧ敾銆� error锛�" + playSpineAnimIndex);
+            }
+            string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? defaultAnimIndex : playSpineAnimIndex].Name;
+            spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
+        }
+        else
+        {
+            Debug.LogError("Spine 鏁版嵁涓病鏈夋壘鍒颁换浣曞姩鐢伙紒" + effectConfig.id);
+        }
+    }
+
+
+    private bool CheckForAdditiveBlend(Spine.Skeleton skeleton)
+    {
+        // 閬嶅巻鎵�鏈夋彃妲斤紝妫�鏌ユ槸鍚︽湁鐩稿姞妯″紡
+        foreach (var slot in skeleton.Slots)
+        {
+            if (slot.Data.BlendMode == Spine.BlendMode.Additive)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    //unity鐗规晥
+    protected virtual void PlayerEffect()
+    {
         var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
         if (effectPrefab == null)
         {
@@ -193,20 +330,37 @@
             return;
         }
 
-        // 瀹炰緥鍖栫壒鏁�
-        effectTarget = Instantiate(effectPrefab, transform);
+        if (effectConfig.isSpine == 0)
+        {
+            //unity鐗规晥 鍒ゆ柇棰勫埗浣撴槸鍚︽寕杞紼ffectTime
+            var timeObj = effectPrefab.GetComponent<EffectTime>();
+            if (null == timeObj)
+            {
+                Debug.LogError($"{effectPrefab.name}棰勫埗浣撴病鏈夋寕杞紼ffectTime");
+                return;
+            }
+        }
+
+        // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
+        pool = GameObjectPoolManager.Instance.RequestPool(effectPrefab);
+        effectTarget = pool.Request();
+        // 璁剧疆鐖惰妭鐐瑰拰浣嶇疆
+        effectTarget.transform.SetParent(transform);
+        effectTarget.transform.localPosition = Vector3.zero;
+        effectTarget.transform.localScale = Vector3.one;
+        effectTarget.transform.localRotation = Quaternion.identity;
         effectTarget.name = $"Effect_{effectConfig.fxName}";
+
 
         //鎸傝浇缁勪欢鍚� 寮�濮嬫敹闆�
         particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
         animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
         rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
+        OnUnityAnimationComplete();
+    
 
-
-        //  鎬濊�冧竴涓嬪湪娌℃湁鎸傚湪鑺傜偣鐨勬椂鍊�
         if (null == canvas)
             canvas = GetComponentInParent<Canvas>();
-
 
         // 娣诲姞鐗规晥绌块�忛樆鎸″櫒
         blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>();
@@ -216,14 +370,20 @@
         {
             blocker.SetParentCanvas(canvas);
         }
-
-        // 鑷姩閿�姣�
-        if (effectConfig.autoDestroy != 0)
-        {
-            Destroy(effectTarget, effectConfig.destroyDelay);
-        }
     }
 
+    public async UniTask PlayAsync(bool showLog = true, bool closePMA = false)
+    {
+        await UniTask.Delay(playDelayTime);
+        try
+        {
+            Play(showLog, closePMA);
+        }
+        catch (Exception e)
+        {
+            Debug.LogError(e);
+        }
+    }
 
     protected void OnDestroy()
     {
@@ -232,33 +392,57 @@
             onDestroy.Invoke(this);
             onDestroy = null;
         }
+        // 鍋滄鐗规晥骞跺綊杩樺埌姹犱腑
+        Release();
+
         if (spineAnimationState != null)
         {
             spineAnimationState.Complete -= OnSpineAnimationComplete;
         }
+
+
     }
 
     //鍗曟鎾斁瀹屾瘯灏变細瑙﹀彂锛屽嵆浣挎槸寰幆
-    protected void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
+    protected virtual void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
     {
         if (!isPlaySpineLoop)
         {
-            if (onComplete == null)
+            spineComp.enabled = false;
+            isPlaying = false;
+            onComplete?.Invoke();
+            if (isReleaseImmediately)
             {
-                if (effectConfig.isSpine != 0)
-                {
-                    spineComp.enabled = false;
-                }
+                Release();
             }
 
-            onComplete?.Invoke();
         }
+    }
+
+
+    private void OnUnityAnimationComplete()
+    {
+        var timeObj = effectTarget.GetComponent<EffectTime>();
+        if (!timeObj.isLoop)
+        {
+            this.SetWait(timeObj.playTime);
+            this.DoWaitRestart();
+            this.OnWaitCompelete(OnEffectComplete);
+        }
+    }
+
+    private void OnEffectComplete(Component comp)
+    {
+        this.DoWaitStop();
+        if (isReleaseImmediately)
+            Release();
     }
 
 
     //  鍒涘缓鍚庣殑鐗规晥浼氳嚜鍔ㄩ殣钘� 闇�瑕佹墜鍔ㄨ皟鐢≒lay鎵嶈兘鎾斁
     public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false)
     {
+        // 鐩存帴鍒涘缓鐗规晥鎾斁鍣紝涓嶄娇鐢ㄥ璞℃睜
         EffectPlayer effectPlayer = null;
 
         if (createNewChild)
@@ -270,11 +454,23 @@
         else
         {
             effectPlayer = parent.AddMissingComponent<EffectPlayer>();
-            effectPlayer.effectId = effectId;
         }
+
+        effectPlayer.effectId = effectId;
         effectPlayer.SetActive(true);
         return effectPlayer;
     }
+
+    /// <summary>
+    /// 璁剧疆娓告垙瀵硅薄婵�娲荤姸鎬�
+    // /// </summary>
+    // public void SetActive(bool active)
+    // {
+    //     if (gameObject != null)
+    //     {
+    //         gameObject.SetActive(active);
+    //     }
+    // }
 
     public void Pause()
     {
@@ -372,4 +568,6 @@
             return;
         }
     }
+
+
 }

--
Gitblit v1.8.0