|   | 
| using System; | 
| using Spine.Unity; | 
| using UnityEngine; | 
|   | 
| public class UIHeroController : MonoBehaviour | 
| { | 
|     private GameObjectPoolManager.GameObjectPool pool; | 
|     private int skinID; | 
|     protected SkeletonGraphic skeletonGraphic; | 
|   | 
|     protected Spine.AnimationState spineAnimationState; | 
|     private GameObject instanceGO; | 
|   | 
|     private Action onComplete; | 
|     public void Create(int _skinID, float scale = 1f, Action _onComplete = null, string motionName = "idle", bool isLh = false) | 
|     { | 
|         if (skinID == _skinID) | 
|         {  | 
|             //避免重复创建 | 
|             return; | 
|         } | 
|   | 
|         skinID = _skinID; | 
|         onComplete = _onComplete; | 
|         pool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("UIHero")); | 
|          | 
|         if (!transform.gameObject.activeSelf) | 
|         { | 
|             transform.SetActive(true); | 
|         } | 
|         if (instanceGO == null) | 
|         {  | 
|             instanceGO = pool.Request(); | 
|             instanceGO.transform.SetParent(transform); | 
|             //transform 的Pivot Y是0,让instanceGO 居中 | 
|             instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f); | 
|   | 
|             //instanceGO.transform.localPosition = Vector3.zero; | 
|             instanceGO.transform.localScale = Vector3.one; | 
|             instanceGO.transform.localRotation = Quaternion.identity; | 
|         } | 
|   | 
|         skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true); | 
|         var skinConfig = HeroSkinConfig.Get(skinID); | 
|         if (isLh) | 
|         { | 
|             skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie); | 
|         } | 
|         else | 
|         {  | 
|             skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes); | 
|         } | 
|         skeletonGraphic.Initialize(true); | 
|         this.transform.localScale = Vector3.one * scale; | 
|         spineAnimationState = skeletonGraphic.AnimationState; | 
|         spineAnimationState.Data.DefaultMix = 0f; | 
|         if (motionName == "") | 
|             motionName = GetFistSpineAnim(); | 
|         PlayAnimation(motionName, true); | 
|         spineAnimationState.Complete -= OnAnimationComplete; | 
|         spineAnimationState.Complete += OnAnimationComplete; | 
|     } | 
|   | 
|   | 
|   | 
|   | 
|     protected void OnDestroy() | 
|     { | 
|         if (spineAnimationState != null) | 
|         { | 
|             spineAnimationState.Complete -= OnAnimationComplete; | 
|         } | 
|         if (pool != null) | 
|             pool.Release(instanceGO); | 
|         skeletonGraphic = null; | 
|         pool = null; | 
|     } | 
|   | 
|   | 
|     public virtual void PlayAnimation(string motionName, bool loop = false) | 
|     { | 
|         if (spineAnimationState == null) return; | 
|   | 
|         // 直接使用 ToString() 而不是调用 GetAnimationName | 
|         spineAnimationState.SetAnimation(0, motionName.ToString(), loop); | 
|     } | 
|   | 
|     // 播放第一个动画(作为默认动画) | 
|     string GetFistSpineAnim() | 
|     { | 
|         var skeletonData = skeletonGraphic.Skeleton.Data; | 
|         if (skeletonData.Animations.Count > 0) | 
|         { | 
|             return skeletonData.Animations.Items[0].Name; | 
|         } | 
|         else | 
|         { | 
|             Debug.LogError("Spine 数据中没有找到任何动画!武将皮肤:" + skinID); | 
|         } | 
|         return ""; | 
|     } | 
|   | 
|     /// <summary> | 
|     /// 动画完成事件处理 | 
|     /// </summary> | 
|     protected virtual void OnAnimationComplete(Spine.TrackEntry trackEntry) | 
|     { | 
|         onComplete?.Invoke(); | 
|     } | 
|   | 
| } |