hch
9 天以前 8c46bc3e9de02cd5aa8d399bbc3e852fe0bfaefc
0312 模型初始化加载优化
1个文件已修改
176 ■■■■■ 已修改文件
Main/System/Hero/UIHeroController.cs 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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();
        }
    }
@@ -356,12 +310,21 @@
            }
            // 根据当前初始化序号计算延迟时间
            // 第一个卡片延迟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();
        }
        // 异步创建instanceGO和加载资源
        await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh: false);
        if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
        {
            Debug.LogError("资源加载失败,无法初始化模型");
            return;
            }
            skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
@@ -454,7 +417,12 @@
        }
        var skinConfig = HeroSkinConfig.Get(skinID);
        if (skinConfig != null && skeletonGraphic != null)
        if (skinConfig != null)
        {
            // 同步创建instanceGO和加载资源(立绘需要立即显示)
            CreateInstanceAndLoadAssetsSync(skinConfig, isLh: true);
            if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null)
        {
            skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
            skeletonGraphic.Initialize(true);
@@ -485,6 +453,104 @@
            isInitializing = false;
        }
    }
    }
    /// <summary>
    /// 同步创建instanceGO和加载资源(用于立绘)
    /// </summary>
    private void CreateInstanceAndLoadAssetsSync(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);
        // 同步加载资源
        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");
        }
    }