hch
10 天以前 8c46bc3e9de02cd5aa8d399bbc3e852fe0bfaefc
Main/System/Hero/UIHeroController.cs
@@ -45,6 +45,11 @@
         return;
      }
      if (skeletonGraphic != null)
      {
         skeletonGraphic.enabled = false;
      }
      skinID = _skinID;
      var skinConfig = HeroSkinConfig.Get(skinID);
      if (isLh)
@@ -94,51 +99,6 @@
      }
      onComplete = _onComplete;
      pool = GameObjectPoolManager.Instance.GetPool(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);
      if (isLh)
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
      }
      else
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
      }
      if (skeletonGraphic.skeletonDataAsset == null)
      {
         transform.SetActive(false);
         if (pool != null)
            pool.Release(instanceGO);
         skeletonGraphic = null;
         Destroy(instanceGO);
         Debug.LogError("未配置spine");
         return;
      }
      // 使用 UniTask 进行延迟初始化,避免批量创建时卡顿
      if (isInitializing)
      {
         // 如果正在初始化,设置标志位取消之前的任务
         isInitializing = false;
      }
      
      // 立绘需要立即显示,其他情况延迟初始化
      if (isLh)
@@ -148,13 +108,7 @@
      }
      else
      {
         // 在加载新模型前先隐藏当前显示的模型(非立绘情况)
         if (skeletonGraphic != null)
         {
            skeletonGraphic.enabled = false;
         }
         // 使用 UniTask 进行异步初始化
         // 使用 UniTask 进行异步初始化,将instanceGO创建和资源加载都移到异步处理
         DelayedInitializeAsync(skinConfig, motionName).Forget();
      }
   }
@@ -355,17 +309,26 @@
            currentIndex = activeInitializationCount++;
         }
         // 根据当前初始化序号计算延迟时间
         // 第一个卡片延迟1帧,第二个延迟2帧,以此类推,最多延迟10帧
         int delayFrames = Mathf.Min(currentIndex + 2, 80);
      // 根据当前初始化序号计算延迟时间
      // 第一个卡片延迟1帧,第二个延迟2帧,以此类推,最多延迟60帧
      int delayFrames = Mathf.Min(currentIndex + 1, 60);
         for (int i = 0; i < delayFrames; i++)
         {
            await UniTask.NextFrame();
         }
      for (int i = 0; i < delayFrames; i++)
      {
         await UniTask.NextFrame();
      }
         skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
         skeletonGraphic.Initialize(true);
      // 异步创建instanceGO和加载资源
      await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh: false);
      if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
      {
         Debug.LogError("资源加载失败,无法初始化模型");
         return;
      }
      skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
      skeletonGraphic.Initialize(true);
         // 初始化完成后设置皮肤
         if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
@@ -454,35 +417,138 @@
      }
      var skinConfig = HeroSkinConfig.Get(skinID);
      if (skinConfig != null && skeletonGraphic != null)
      if (skinConfig != null)
      {
         skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
         skeletonGraphic.Initialize(true);
         // 同步创建instanceGO和加载资源(立绘需要立即显示)
         CreateInstanceAndLoadAssetsSync(skinConfig, isLh: true);
         
         if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
         if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null)
         {
            var skeleton = skeletonGraphic.Skeleton;
            skeleton.SetSkin(skinConfig.InitialSkinName);
            skeleton.SetSlotsToSetupPose();
            skeletonGraphic.Update(0);
            skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
            skeletonGraphic.Initialize(true);
            if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
            {
               var skeleton = skeletonGraphic.Skeleton;
               skeleton.SetSkin(skinConfig.InitialSkinName);
               skeleton.SetSlotsToSetupPose();
               skeletonGraphic.Update(0);
            }
            skeletonGraphic.enabled = true;
            SetMaterialNone();
            spineAnimationState = skeletonGraphic.AnimationState;
            if (spineAnimationState != null)
            {
               spineAnimationState.Data.DefaultMix = 0f;
               if (string.IsNullOrEmpty(motionName))
                  motionName = GetFistSpineAnim();
               PlayAnimation(motionName, true);
               spineAnimationState.Complete -= OnAnimationComplete;
               spineAnimationState.Complete += OnAnimationComplete;
            }
            isInitialized = true;
            isInitializing = false;
         }
      }
   }
         skeletonGraphic.enabled = true;
         SetMaterialNone();
   /// <summary>
   /// 同步创建instanceGO和加载资源(用于立绘)
   /// </summary>
   private void CreateInstanceAndLoadAssetsSync(HeroSkinConfig skinConfig, bool isLh)
   {
      // 确保transform处于激活状态
      if (!transform.gameObject.activeSelf)
      {
         transform.SetActive(true);
      }
         spineAnimationState = skeletonGraphic.AnimationState;
         if (spineAnimationState != null)
         {
            spineAnimationState.Data.DefaultMix = 0f;
            if (string.IsNullOrEmpty(motionName))
               motionName = GetFistSpineAnim();
            PlayAnimation(motionName, true);
            spineAnimationState.Complete -= OnAnimationComplete;
            spineAnimationState.Complete += OnAnimationComplete;
         }
      // 创建pool和instanceGO
      pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
      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.localScale = Vector3.one;
         instanceGO.transform.localRotation = Quaternion.identity;
      }
         isInitialized = true;
         isInitializing = false;
      skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
      // 同步加载资源
      if (isLh)
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
      }
      else
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
      }
      if (skeletonGraphic.skeletonDataAsset == null)
      {
         transform.SetActive(false);
         if (pool != null)
            pool.Release(instanceGO);
         skeletonGraphic = null;
         Destroy(instanceGO);
         Debug.LogError("未配置spine");
      }
   }
   /// <summary>
   /// 异步创建instanceGO和加载资源(用于非立绘)
   /// </summary>
   private async UniTask CreateInstanceAndLoadAssetsAsync(HeroSkinConfig skinConfig, bool isLh)
   {
      // 确保transform处于激活状态
      if (!transform.gameObject.activeSelf)
      {
         transform.SetActive(true);
      }
      // 创建pool和instanceGO
      pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
      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.localScale = Vector3.one;
         instanceGO.transform.localRotation = Quaternion.identity;
      }
      skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
      // 在主线程中加载资源,避免Unity API线程安全问题
      // 使用UniTask.Yield()来确保在主线程中执行
      await UniTask.Yield();
      if (isLh)
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
      }
      else
      {
         skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
      }
      if (skeletonGraphic.skeletonDataAsset == null)
      {
         transform.SetActive(false);
         if (pool != null)
            pool.Release(instanceGO);
         skeletonGraphic = null;
         Destroy(instanceGO);
         Debug.LogError("未配置spine");
      }
   }