yyl
2026-03-31 0fa617a09eedf6bdb25eda55fac1d3344859fd93
webgl
130个文件已修改
4个文件已添加
1292 ■■■■■ 已修改文件
Main/Common/Jace/JaceOptions.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/ConfigManager.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/GameEngine/Launch/AssetCopyTask.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/NetPkgCtl.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/Platform/DeviceProfile.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Manager/UIManager.cs 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/ResModule/UILoader.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/SDK/SDKUtils.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaChallengeCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaPlayerRankCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaPlayerTop3Cell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaRecordCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/AssetVersion.cs 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/AssetVersionUtility.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/DownLoadAndDiscompressHotTask.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/DownLoadWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/DownloadHotMgr.cs 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/InGameDownLoad.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/AssetVersion/InGameDownTestUtility.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/PriviewBattleField.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/QYBattleField.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BillboardRank/PlayerRankCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BillboardRank/PlayerTop3Cell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/QunyingTabHandler.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Chat/ChatPlayerMineCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Chat/ChatPlayerOtherCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ClientVersion/RequestSecretWin.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ClientVersion/VersionConfig.cs 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ClientVersion/VersionUtility.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Debug/DebugUtility.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FirstCharge/FirstChargeWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildApplyListCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildBossHurtRankCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildBossWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildDonateDetailCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildMemberCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildPreviewWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HappyXBModel.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/UIHeroController.cs 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCallChangeWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCallRateItem.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCallResultWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCallWin.cs 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutCheckInWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutGiftCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutManager.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutPopWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutRankCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutRankTop3Cell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutShopCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutSkinWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutStarUpWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroDebut/HeroDebutWin.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroFates/HeroFatesIHItem.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBestBaseWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBestWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCardCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionCardCell.cs 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionWin.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftEatSuccessWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroScenePosCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroSkinRoleCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroSkinWin.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainBaseWin.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Horse/HorseController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/GoldRushLeader.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/GoldRushWorkCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/GoldRushWorkerCell.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Invest/InvestModel.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ItemTipWayWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnMoneyCell.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Language/Language.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/LineupRecommend/LineupRecommendItem.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Login/LoginWin.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HeroFightingCardCell.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HomeWin.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/MainWin.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/RightFuncInHome.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/MainLevel/MainBossEnterWin.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSActivityBaseWin.cs 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSBeautyMMBaseWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSGalaGiftCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSHeroCallBaseWin.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSHeroTrainBaseWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSMainLevelBaseWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSMinggeBaseWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSRankGiftBaseCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSRankHeroCallGiftCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSRankHeroTrainWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OSActivity/OSRankMinggeWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OfficialRank/OfficialTitleCell.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OtherPlayerDetail/BuffInfoWin.cs 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OtherPlayerDetail/OtherNpcHeroCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/PhantasmPavilion/AvatarCell.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/PhantasmPavilion/PhantasmPavilionManager.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/PlayerProfile/PlayerProfileWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QYBattleFailWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QYBattleWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QYFighterCell.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QYPlayerTop3Cell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QYWin.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Qunying/QunyingManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Settlement/BattleSettlementManager.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/SpineUpdateManager.cs 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/SpineUpdateManager.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/SkinStoreCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/SkinStoreWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreBaseWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreModel.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TianziBillborad/TianziBillboradPlayerRankCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TianziBillborad/TianziBillboradPlayerTop3Cell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TianziBillborad/TianziBillboradWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TimeRush/TimeRushGiftCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/UIBase/UIBase.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/UIBase/UIJumpManager.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Video/UIVideoPlayer.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ViewNPC/ViewBuffManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/WarlordPavilion/WarlordPavilionNPCItem.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/WarlordPavilion/WarlordPavilionPlayerRankCell.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/WarlordPavilion/WarlordPavilionPlayerTop3Cell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/ComponentExtersion.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/DeviceUtility.cs 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/OperationLogCollect.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/RunTimeExceptionUtility.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/SystemCMD.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/WebGLDebug.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/WebGLDebug.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Common/Jace/JaceOptions.cs
@@ -14,7 +14,11 @@
        public JaceOptions()
        {
            CultureInfo = CultureInfo.CurrentCulture;
#if UNITY_WEBGL
            ExecutionMode = ExecutionMode.Interpreted;
#else
            ExecutionMode = ExecutionMode.Compiled;
#endif
            CacheEnabled = true;
            OptimizerEnabled = true;
            CaseSensitive = false;
Main/Config/ConfigManager.cs
@@ -556,12 +556,18 @@
    /// </summary>
    private async UniTask<string[]> LoadConfigTextAsync(Type configType)
    {
<<<<<<< HEAD
        string configName = configType.Name;
        if (configName.EndsWith("Config"))
            configName = configName.Substring(0, configName.Length - 6);
        return await ResManager.Instance.LoadConfigAsync(configName);
=======
    }
#if UNITY_EDITOR
    /// <summary>
    /// Editor 自检:反射加载所有配置类并记录耗时。
    /// </summary>
    public async void SelfCheckAllConfigs()
    {
        // 获取 Editor Assembly
        var editorAsm = System.AppDomain.CurrentDomain.GetAssemblies()
            .FirstOrDefault(a => a.FullName.Contains("Editor"));
@@ -601,8 +607,8 @@
        foreach (var className in checkClasses)
        {
            // 这里也要用 Editor Assembly 获取类型
            var configType = editorAsm.GetType(className) ?? Type.GetType(className);
            if (configType == null)
            var cfgType = editorAsm.GetType(className) ?? Type.GetType(className);
            if (cfgType == null)
            {
                Debug.LogWarning($"[自检] 未找到类型: {className}");
                continue;
@@ -611,15 +617,15 @@
            var sw = System.Diagnostics.Stopwatch.StartNew();
            // 反射调用静态Init方法
            string configName = configType.Name;
            string configName = cfgType.Name;
            if (configName.EndsWith("Config"))
                configName = configName.Substring(0, configName.Length - 6);
            string[] texts = ResManager.Instance.LoadConfig(configName);
            string[] texts = await ResManager.Instance.LoadConfigAsync(configName);
            if (texts != null)
            {
                string[] lines = texts;
                var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
                var methodInfo = cfgType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
                if (methodInfo != null)
                {
                    methodInfo.Invoke(null, new object[] { lines });
@@ -630,21 +636,21 @@
            if (sw.ElapsedMilliseconds >= 500)
            {
                Debug.LogError($"[自检] 加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
                Debug.LogError($"[自检] 加载配置 {cfgType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
            }
            else if (sw.ElapsedMilliseconds <= 5)
            {
                fastName.Add(configType.Name);
                fastName.Add(cfgType.Name);
            }
            Debug.Log($"[自检] 加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");
            Debug.Log($"[自检] 加载配置: {cfgType.Name} 用时: {sw.ElapsedMilliseconds} ms");
        }
        // 释放所有已加载的配置
        foreach (var className in checkClasses)
        {
            var configType = editorAsm.GetType(className) ?? Type.GetType(className);
            if (configType == null) continue;
            var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
            var cfgType = editorAsm.GetType(className) ?? Type.GetType(className);
            if (cfgType == null) continue;
            var methodInfo = cfgType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
            if (methodInfo != null)
            {
                methodInfo.Invoke(null, null);
@@ -653,8 +659,8 @@
        System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
        Debug.Log($"[自检] fastConfig.txt 生成完毕,快速表有:{string.Join(", ", fastName)}");
>>>>>>> origin/master
    }
#endif
    /// <summary>
    /// 从已加载的文本初始化配置(纯内存操作,无网络)。
Main/Core/GameEngine/Launch/AssetCopyTask.cs
@@ -27,6 +27,11 @@
        {
            done = true;
        }
        else if (Application.platform == RuntimePlatform.WebGLPlayer)
        {
            // WebGL平台无需拷贝文件,资源由 YooAsset WebPlayMode 加载
            done = true;
        }
        else
        {
            switch (Application.platform)
Main/Core/NetworkPackage/NetPkgCtl.cs
@@ -59,6 +59,7 @@
    public static void WriteAllNetLog(bool @details)
    {
#if !UNITY_WEBGL
        if (packages != null)
        {
            var count = 0;
@@ -88,6 +89,7 @@
            File.WriteAllLines(Application.dataPath + "/PackageLogs_" + (@details ? "details" : "abstract") + "_" + DateTime.Now.ToString("HH_mm_ss") + ".txt", lines.ToArray());
        }
#endif
    }
}
Main/Core/Platform/DeviceProfile.cs
@@ -59,12 +59,17 @@
            };
            
            // 根据内存判定性能档次
#if UNITY_WEBGL
            // WebGL下systemMemorySize不准确,默认中端
            profile.PerformanceLevel = PerformanceLevel.Medium;
#else
            if (profile.TotalMemory < 2048)
                profile.PerformanceLevel = PerformanceLevel.Low;
            else if (profile.TotalMemory < 4096)
                profile.PerformanceLevel = PerformanceLevel.Medium;
            else
                profile.PerformanceLevel = PerformanceLevel.High;
#endif
            
            return profile;
        }
Main/Manager/UIManager.cs
@@ -775,6 +775,16 @@
    /// </summary>
    public async UniTask<T> OpenWindowAsync<T>(int functionOrder = 0) where T : UIBase
    {
        if (typeof(T).Name == "MainWin")
        {
            //MainWin 比较关键且唯一,做安全防范
            var ui = GetUI<MainWin>();
            if (ui != null)
            {
                ui.ClickFunc(0);
                return ui as T;
            }
        }
        string uiName = typeof(T).Name;
        var result = await OpenWindowAsync(uiName, functionOrder);
        return result as T;
@@ -976,127 +986,6 @@
        return null;
    }
    public async UniTask<UIBase> OpenWindow(string uiName, int functionOrder = 0)
    {
        // 优先从closedUIDict中获取
        UIBase parentUI = null;
        UIBase returnValue = null;
        List<UIBase> closedUIList = new List<UIBase>();
        if (closedUIDict.TryGetValue(uiName, out closedUIList) && closedUIList.Count > 0)
        {
            #if UNITY_EDITOR
            Debug.Log("OpenWindow getFromClosedDict " + uiName);
            #endif
            returnValue = closedUIList[0] as UIBase;
            closedUIList.RemoveAt(0);
            if (closedUIList.Count == 0)
            {
                closedUIDict.Remove(uiName);
            }
        }
        else
        {
            #if UNITY_EDITOR
            Debug.Log("OpenWindow getNewLoad " + uiName);
            #endif
            returnValue = await LoadUIResourceAsync(uiName);
            if (returnValue == null)
            {
                // 记录错误日志
                Debug.LogError($"打开UI失败: {uiName}");
                return null;
            }
        }
        returnValue.gameObject.SetActive(true);
        // 自动设置父级UI, 如果勾选了ismainui 则不需要找父级UI
        if (returnValue.supportParentChildRelation && uiStack.Count > 0 && !returnValue.isMainUI)
        {
            // 获取栈顶UI
            parentUI = GetLastSupportParentChildRelationUI();
        }
        // 设置父级UI
        if (parentUI != null)
        {
            // 设置父子关系
            returnValue.parentUI = parentUI;
            if (parentUI.childrenUI == null)
            {
                // 初始化父级UI的子UI列表
                parentUI.childrenUI = new List<UIBase>();
            }
            // 添加到父级UI的子UI列表
            parentUI.childrenUI.Add(returnValue);
        }
        // 更新回合数
        currentRound++;
        // 设置UI的最后使用回合数
        returnValue.lastUsedRound = currentRound;
        // 更新父级UI的回合数
        UpdateParentUIRounds(returnValue);
        // 将UI添加到字典中
        if (!uiDict.ContainsKey(uiName))
        {
            // 如果字典中不存在该类型的UI,创建新列表
            uiDict[uiName] = new List<UIBase>();
        }
        // 添加到UI列表
        uiDict[uiName].Add(returnValue);
#if UNITY_EDITOR
        if (uiDict[uiName].Count > 5)
        {
            Debug.LogError("已打开" + uiDict[uiName].Count + "个界面:" + uiName);
        }
#endif
        // 将UI添加到栈中
        uiStack.Push(returnValue);
        // 更新UI排序顺序
        UpdateUISortingOrder();
        // 打开UI
        returnValue.functionOrder = functionOrder;
        returnValue.HandleOpen();
        OnOpenWindow?.Invoke(returnValue);
        // 检查并关闭长时间未使用的UI
        CheckAndCloseIdleUI();
        return returnValue;
    }
    /// <summary>
    /// 打开UI
    /// </summary>
    public T OpenWindow<T>(int functionOrder = 0) where T : UIBase
    {
        if (typeof(T).Name == "MainWin")
        {
            //MainWin 比较关键且唯一,做安全防范
            var ui = GetUI<MainWin>();
            if (ui != null)
            {
                ui.ClickFunc(0);
                return ui as T;
            }
        }
        // 获取UI类型名称
        string uiName = typeof(T).Name;
        return OpenWindow(uiName, functionOrder) as T;
    }
    /// <summary>
    /// 关闭UI
    /// </summary>
Main/ResModule/UILoader.cs
@@ -31,12 +31,10 @@
    public static async UniTask LoadSprite(string directory, string name, Image image, string failureName)
    {
        var sprite = await LoadSpriteAsync(directory, name);
        if (image == null) return;
        if (sprite != null)
        {
            if (image != null)
            {
                image.overrideSprite = sprite;
            }
            image.overrideSprite = sprite;
        }
        else
        {
@@ -80,9 +78,10 @@
            StringUtility.Concat(ResourcesPath.UI_TEXTURE_SUFFIX, "/" + iconConfig.folder), iconConfig.sprite, ct: ct);
    }
    public static UniTask<Texture2D> LoadTexture2DPNGAsync(string name, CancellationToken ct = default)
    public static async UniTask<Texture2D> LoadTexture2DPNGAsync(string name, CancellationToken ct = default)
    {
        return ResManager.Instance.LoadAssetAsync<Texture2D>(
            StringUtility.Concat(ResourcesPath.UI_TEXTURE_SUFFIX, "/FullScreenBg"), name + ".png", false, ct);
        var path = StringUtility.Concat(ResourcesPath.UI_TEXTURE_SUFFIX, "/FullScreenBg");
        var result = await ResManager.Instance.LoadAssetAsync<Texture2D>(path, name + ".png", false, ct);
        return result;
    }
}
Main/SDK/SDKUtils.cs
@@ -426,7 +426,7 @@
        }
#elif UNITY_IOS
        AotSdkUtility.IOSUniyMessageHandle(json.ToJson());
#elif UNITY_STANDALONE
#elif UNITY_STANDALONE || UNITY_WEBGL
        InitFinished=true;
#endif
        
@@ -640,7 +640,11 @@
                // else
                {
                    //默认都是退出游戏
#if UNITY_WEBGL
                    Application.OpenURL("about:blank");
#else
                    Application.Quit();
#endif
                }
                break;
            case CodeA2U.GetAdAward:
Main/System/Arena/ArenaChallengeCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class ArenaChallengeCell : MonoBehaviour
@@ -45,7 +46,7 @@
        txtFightPoint.text = UIHelper.ReplaceLargeArtNum(arenaMatchInfo.FightPower);
        txtAddScore.text = Language.Get("Arena16", ArenaManager.Instance.GetChallengePoints(index));
        officialTitleCell.InitUI(arenaMatchInfo.RealmLV, (int)arenaMatchInfo.TitleID, 0.55f);
        officialTitleCell.InitUI(arenaMatchInfo.RealmLV, (int)arenaMatchInfo.TitleID, 0.55f).Forget();
        int[][] rewards = ArenaManager.Instance.fixedChallengeRewards;
        for (int i = 0; i < itemCells.Count; i++)
Main/System/Arena/ArenaPlayerRankCell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -32,7 +33,7 @@
                rankText.text = Language.Get("L1045");
                rankValueText.text = ArenaManager.Instance.score.ToString();
                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                return;
            }
            rank = rankData.rank;
@@ -48,7 +49,7 @@
        {
            viewPlayerId = (int)rankData.id;
            officialTitleCell.SetActive(true);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
            avatarCell.SetActive(true);
            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
            avatarCell.SetOnLoaded(() =>
Main/System/Arena/ArenaPlayerTop3Cell.cs
@@ -24,7 +24,7 @@
        officialTitleCell.SetActive(true);
        rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue));
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, 1).Forget();
        queryPlayerBtn.SetListener(() =>
        {
Main/System/Arena/ArenaRecordCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using System;
@@ -74,7 +75,7 @@
        });
        txtName.text = arenaGameRec.Name;
        txtFightPoint.text = UIHelper.ReplaceLargeArtNum(arenaGameRec.FightPower);
        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 0.55f);
        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 0.55f).Forget();
        imgMoneyIcon.SetIconWithMoneyType(ArenaManager.Instance.ChallengeMoneyType);
        txtNeedCount.text = ArenaManager.Instance.NeedChallengeMoneyCnt.ToString();
    }
Main/System/AssetVersion/AssetVersion.cs
@@ -81,6 +81,10 @@
    public bool CheckLocalFileValid(bool _completeFile)
    {
#if UNITY_WEBGL
        // WebGL无本地文件系统,资源由YooAsset WebPlayMode管理
        return true;
#else
        if (_completeFile)
        {
            var path = StringUtility.Concat(ResourcesPath.Instance.ExternalStorePath, m_RelativePath);
@@ -139,6 +143,7 @@
        }
        return true;
#endif
    }
    // 检查外部存储文件是否存在
@@ -148,6 +153,29 @@
    {
        string path = string.Concat(ResourcesPath.Instance.ExternalStorePath, m_RelativePath);
#if UNITY_WEBGL
        // WebGL无本地文件系统,直接走流式加载路径
        if (!m_RelativePath.Contains(".txt"))
        {
            if (otherAssetInfo == null || string.IsNullOrEmpty(otherAssetInfo.relativePath))
                return false;
            if (otherAssetInfo.size != size)
            {
                Debug.LogFormat("StreamingAssetPath 文件大小不对{0}-{1}", size, otherAssetInfo.size);
                return false;
            }
            if (otherAssetInfo.md5 != md5)
            {
                Debug.LogFormat("StreamingAssetPath 文件md5不对{0}-{1}", md5, otherAssetInfo.md5);
                return false;
            }
            return true;
        }
        return true;
#else
        if (!File.Exists(path) && !m_RelativePath.Contains(".txt"))
        {
            //Debug.LogFormat("转查StreamingAssetPath - 文件不存在 {0} ", path);
@@ -170,7 +198,7 @@
        }
        return CheckLocalFileValid(false);
#endif
    }
Main/System/AssetVersion/AssetVersionUtility.cs
@@ -394,11 +394,12 @@
        if (reverse)
            _assetKey = EncodeFileName(_assetKey);
        var path = StringUtility.Concat(ResourcesPath.Instance.ExternalStorePath, _assetKey);
#if !UNITY_WEBGL
        if (!File.Exists(path))
        {
            path = StringUtility.Concat(ResourcesPath.Instance.StreamingAssetPath, _assetKey);
        }
#endif
        return path;
    }
@@ -407,11 +408,12 @@
        if (reverse)
            _assetKey = EncodeFileName(_assetKey);
        var path = StringUtility.Concat(ResourcesPath.Instance.ExternalStorePath, _assetKey);
#if !UNITY_WEBGL
        if (!File.Exists(path))
        {
            path = StringUtility.Concat(ResourcesPath.Instance.StreamingAssetPath, _assetKey);
        }
#endif
        return path;
    }
Main/System/AssetVersion/DownLoadAndDiscompressHotTask.cs
@@ -45,6 +45,15 @@
    public void Prepare(List<AssetVersion> _downLoadTasks, Action _downLoadOkCallBack)
    {
#if UNITY_WEBGL
        // WebGL 下文件下载由 YooAsset WebPlayMode 处理,跳过旧的文件下载流程
        Debug.Log("[DownLoadAndDiscompressHotTask] WebGL 平台跳过文件下载,YooAsset 负责资源加载");
        foreach (var asset in _downLoadTasks)
            asset.localValid = true;
        step = Step.Completed;
        _downLoadOkCallBack?.Invoke();
        return;
#endif
        tasks = _downLoadTasks;
        downLoadOkCallBack = _downLoadOkCallBack;
Main/System/AssetVersion/DownLoadWin.cs
@@ -142,7 +142,11 @@
    private void Cancel()
    {
#if UNITY_WEBGL
        Application.OpenURL("about:blank");
#else
        Application.Quit();
#endif
    }
}
Main/System/AssetVersion/DownloadHotMgr.cs
@@ -223,10 +223,26 @@
    public string SpeedFormat { get { return StringUtility.FormatSpeed(downloadedSpeed); } }
    //本地文件大小
    public long LocalLength { get { return (File.Exists(tempFile)) ? (new FileInfo(tempFile)).Length : 0L; } }
    public long LocalLength {
        get {
#if UNITY_WEBGL
            return 0L;
#else
            return (File.Exists(tempFile)) ? (new FileInfo(tempFile)).Length : 0L;
#endif
        }
    }
    //本地文件最后修改时间
    private System.DateTime LocalLastModified { get { return File.Exists(tempFile) ? File.GetLastWriteTime(tempFile) : DateTime.MinValue; } }
    private System.DateTime LocalLastModified {
        get {
#if UNITY_WEBGL
            return DateTime.MinValue;
#else
            return File.Exists(tempFile) ? File.GetLastWriteTime(tempFile) : DateTime.MinValue;
#endif
        }
    }
    public bool IsWorking { get { return state == TaskState.Working; } }
    public bool IsDone { get { return state == TaskState.Succeed; } }
@@ -250,9 +266,13 @@
    private bool IsOutdated //本地文件是否已过时
    {
        get {
#if UNITY_WEBGL
            return false;
#else
            if (File.Exists(tempFile))
                return remoteLastModified > LocalLastModified;
            return false;
#endif
        }
    }
@@ -279,15 +299,19 @@
    public bool BeginDownload(Action<DownloadHotTask> onCompleted)
    {
        if ((IsWorking && requestHeaderOk) || IsDone)//已经在下载任务中或已经下载完成了
#if UNITY_WEBGL
        Debug.LogWarning("DownloadHotTask: 文件下载在WebGL上不支持");
        return false;
#else
        if ((IsWorking && requestHeaderOk) || IsDone)
            return false;
        if (state == TaskState.Wait)//第一次尝试
        if (state == TaskState.Wait)
            failedTimes = 0;
        this.onCompleted = onCompleted;
        this.isStop = false;
        Co_DownloadFile().Forget();
        // SnxxzGame.Instance.StartCoroutine(Co_DownloadFile());
        return true;
#endif
    }
    //停止下载
@@ -450,8 +474,12 @@
    private async UniTask Move(string sourceFile, string destFile)
    {
        var copyState = 0;//复制文件状态,0等待,1成功,2失败
#if UNITY_WEBGL
        SetFailed("WebGL不支持文件操作");
        await UniTask.CompletedTask;
        return;
#else
        var copyState = 0;
        try
        {
            if (File.Exists(destFile))
@@ -474,6 +502,7 @@
            SetFailed("临时文件改名出错");
        await UniTask.CompletedTask;
#endif
    }
}
Main/System/AssetVersion/InGameDownLoad.cs
@@ -136,6 +136,15 @@
    //开始分配任务
    public void AssignTasks(List<AssetVersion> assets, Action _onDownLoadOk)
    {
#if UNITY_WEBGL
        // WebGL 下文件下载由 YooAsset WebPlayMode 处理,跳过旧的文件下载流程
        Debug.Log("[InGameDownLoad] WebGL 平台跳过文件下载,YooAsset 负责资源加载");
        foreach (var asset in assets)
            asset.localValid = true;
        state = State.Completed;
        _onDownLoadOk?.Invoke();
        return;
#endif
        
        this.inGameDownLoadAllow = false;
        this.assets = assets;
Main/System/AssetVersion/InGameDownTestUtility.cs
@@ -45,7 +45,9 @@
    public static void ClearAssets()
    {
#if !UNITY_WEBGL
        Directory.Delete(Application.persistentDataPath, true);
#endif
        LocalSave.DeleteKey("HasDownLoadFullAsset");
    }
Main/System/Battle/BattleField/PriviewBattleField.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using LitJson;
using System.Collections.Generic;
using System.Linq;
@@ -9,10 +10,10 @@
    }
    public override void Init(int MapID, int FuncLineID, JsonData _extendData,
    public override async UniTask Init(int MapID, int FuncLineID, JsonData _extendData,
        List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList, byte turnMax)
    {
        base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList, turnMax);
        await base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList, turnMax);
        SetBattleMode(BattleMode.Record);
    }
@@ -60,13 +61,14 @@
        BattleManager.Instance.DistributeNextReportPackage(guid);
    }
    public override void ShowWindow(HB424_tagSCTurnFightInit vNetData)
    public override async void ShowWindow(HB424_tagSCTurnFightInit vNetData)
    {
        PreviewBattleWin fsBattleWin = UIManager.Instance.GetUI<PreviewBattleWin>();// as FullScreenBattleWin;
        if (null == fsBattleWin)
        {
            fsBattleWin = UIManager.Instance.OpenWindow<PreviewBattleWin>();
            fsBattleWin = await UIManager.Instance.OpenWindowAsync<PreviewBattleWin>();
        }
        if (fsBattleWin == null) return;
        fsBattleWin.SetBattleField(this);
    }
Main/System/Battle/BattleField/QYBattleField.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using System;
using LitJson;
using UnityEngine;
@@ -13,10 +14,10 @@
    }
    public override void Init(int MapID, int FuncLineID, JsonData _extendData,
    public override async UniTask Init(int MapID, int FuncLineID, JsonData _extendData,
        List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList, byte turnMax)
    {
        base.Init(MapID, FuncLineID, _extendData, _redTeamList, _blueTeamList, turnMax);
        await base.Init(MapID, FuncLineID, _extendData, _redTeamList, _blueTeamList, turnMax);
        SetBattleMode(BattleMode.Record);
    }
@@ -65,7 +66,7 @@
        {
            UIManager.Instance.CloseWindow<QYBattleWin>();
            QunyingManager.Instance.openQYWinNeedRoll = false;
            UIManager.Instance.OpenWindow<QYWin>();
            UIManager.Instance.OpenWindowAsync<QYWin>().Forget();
        }
    }
@@ -90,13 +91,14 @@
    public override void ShowWindow(HB424_tagSCTurnFightInit vNetData)
    public override async void ShowWindow(HB424_tagSCTurnFightInit vNetData)
    {
        QYBattleWin fsBattleWin = UIManager.Instance.GetUI<QYBattleWin>();// as FullScreenBattleWin;
        if (null == fsBattleWin)
        {
            fsBattleWin = UIManager.Instance.OpenWindow<QYBattleWin>();
            fsBattleWin = await UIManager.Instance.OpenWindowAsync<QYBattleWin>();
        }
        if (fsBattleWin == null) return;
        fsBattleWin.SetBattleField(this);
        if (UIManager.Instance.IsOpened<QYWin>())
        {
Main/System/BillboardRank/PlayerRankCell.cs
@@ -2,6 +2,7 @@
//    [Author]:           玩个游戏
//    [  Date ]:           Wednesday, September 26, 2018
//--------------------------------------------------------
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -47,7 +48,7 @@
                rankText.text = Language.Get("L1045");
                rankValueText.text = "";//Language.Get("L1125");
                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                return;
            }
            rank = rankData.rank;
@@ -62,7 +63,7 @@
        else
        {
            officialTitleCell.SetActive(true);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
            avatarCell.SetActive(true);
            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
            viewPlayerId = (int)rankData.id;
Main/System/BillboardRank/PlayerTop3Cell.cs
@@ -44,7 +44,7 @@
            rankValueText.text = RankModel.Instance.GetCmpValueStr(rankType, rankData.cmpValue);
        }
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f).Forget();
        queryPlayerBtn.SetListener(() =>
        {
Main/System/ChallengeTab/QunyingTabHandler.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
public class QunyingTabHandler : BaseChallengeTabHandler
{
@@ -20,7 +21,7 @@
        return HandleNavigation;
    }
    private void HandleNavigation()
    private async void HandleNavigation()
    {
        if (!FuncOpen.Instance.IsFuncOpen(GetFuncId(), true))
            return;
@@ -32,7 +33,7 @@
            QYBattleWin battleWin;
            if (!UIManager.Instance.IsOpened<QYBattleWin>())
            {
                battleWin = UIManager.Instance.OpenWindow<QYBattleWin>();
                battleWin = await UIManager.Instance.OpenWindowAsync<QYBattleWin>();
            }
            else
            {
@@ -43,7 +44,7 @@
        else
        {
            QunyingManager.Instance.openQYWinNeedRoll = true;
            UIManager.Instance.OpenWindow<QYWin>();
            UIManager.Instance.OpenWindowAsync<QYWin>().Forget();
        }
    }
Main/System/Chat/ChatPlayerMineCell.cs
@@ -1,4 +1,5 @@
using System.Collections;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
public class ChatPlayerMineCell : MonoBehaviour
@@ -24,7 +25,7 @@
                                                PlayerDatas.Instance.baseData.face,
                                                PlayerDatas.Instance.baseData.facePic));
        title.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
        title.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
        if (manager.nowChatTab == ChatChannel.World)
        {
            string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID));
Main/System/Chat/ChatPlayerOtherCell.cs
@@ -1,4 +1,5 @@
using System.Collections;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -23,7 +24,7 @@
        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)data.PlayerID, (int)data.Face, (int)data.FacePic, data.Job));
        title.InitUI(data.RealmLV, (int)data.TitleID);
        title.InitUI(data.RealmLV, (int)data.TitleID).Forget();
        int bubbleID = ChatBubbleHelper.GetOtherChatBubbleID(data.Job, (int)data.BubbleBox);
        m_ChatBubble.DisplayBubble(bubbleID, (int)data.PlayerID);
Main/System/ClientVersion/RequestSecretWin.cs
@@ -26,6 +26,8 @@
            CloseWindow();
#if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
#elif UNITY_WEBGL
            Application.OpenURL("about:blank");
#else
            Application.Quit();
#endif
Main/System/ClientVersion/VersionConfig.cs
@@ -244,36 +244,10 @@
    }
    public static VersionConfig config = null;
    // public static VersionConfig Get()
    // {
    //     if (config == null)
    //     {
    //         if (Application.isEditor)
    //         {
    //             config = Resources.Load<VersionConfig>("VersionConfig");
    //             //debug登录后第二次启动默认恢复test
    //             if (LocalSave.GetBool("RestoreTest"))
    //             {
    //                 config.m_AppId = "test";
    //                 LocalSave.SetBool("RestoreTest", false);
    //                 Debug.Log("appid 恢复test");
    //             }
    //         }
    //         else
    //         {
    //             var text = Resources.Load<TextAsset>("VersionConfigEx");
    //             if (text != null)
    //             {
    //                 config = ScriptableObject.CreateInstance<VersionConfig>();
    //                 var json = JsonMapper.ToObject(text.text);
    //                 ReadJson(json);  //逐一解析,不用VersionConfig类结构读取,因为变量定义是按asset的结构定义的
    //             }
    //         }
    //     }
    //     return config;
    // }
    public static VersionConfig Get()
    {
        return config;
    }
    public static void ReadJson(JsonData _data)
    {
Main/System/ClientVersion/VersionUtility.cs
@@ -97,11 +97,13 @@
            {
                step = Step.Completed;
#if !UNITY_WEBGL
                var apkFiles = new DirectoryInfo(ResourcesPath.Instance.ExternalStorePath).GetFiles("*.apk");
                for (int i = apkFiles.Length - 1; i >= 0; i--)
                {
                    File.Delete(apkFiles[i].FullName);
                }
#endif
            }
        }
        else
Main/System/Debug/DebugUtility.cs
@@ -47,8 +47,12 @@
            }
            else
            {
#if !UNITY_WEBGL
                var parentDirectory = Directory.GetParent(Application.persistentDataPath);
                debugAccount = File.Exists(parentDirectory + "/Debug");
#else
                debugAccount = false;
#endif
            }
            if (LocalSave.GetString("#@#BrancH") != string.Empty)
@@ -70,6 +74,7 @@
            if (debugAccount)
            {
#if !UNITY_WEBGL
                if (Application.isMobilePlatform)
                {
                    var parentDirectory = Directory.GetParent(Application.persistentDataPath);
@@ -83,6 +88,7 @@
                        }
                    }
                }
#endif
            }
        }).Forget();
        
Main/System/FirstCharge/FirstChargeWin.cs
@@ -106,7 +106,7 @@
    private void OnClickPreviewHero()
    {
        HeroUIManager.Instance.selectForPreviewHeroID = model.mainItemId;
        UIManager.Instance.OpenWindow<HeroBestBaseWin>().Forget();
        UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
    }
    private void InitRedPoint()
    {
@@ -208,7 +208,7 @@
        txtDesc.text = heroInfo.heroConfig.Desc;
        imgCountry.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroInfo.heroConfig.Country));
        imgJob.SetSprite(HeroUIManager.Instance.GetJobIconName(heroInfo.heroConfig.Class));
        roleLhModel.Create(heroInfo.SkinID, lhScale, motionName: "", isLh: true);
        roleLhModel.Create(heroInfo.SkinID, lhScale, motionName: "", isLh: true).Forget();
        roleLhModel.transform.localScale = new Vector3(lhScale, lhScale, lhScale);
    }
Main/System/Guild/GuildApplyListCell.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -23,7 +24,7 @@
        lvText.text = data.LV.ToString();
        fightPointText.text = UIHelper.ReplaceLargeArtNum(data.FightPower);
        avatarCell.InitUI(AvatarHelper.GetAvatarModel(data.PlayerID, data.Face, data.FacePic));
        officialTitleCell.InitUI(data.RealmLV, data.TitleID);
        officialTitleCell.InitUI(data.RealmLV, data.TitleID).Forget();
        yesButton.SetListener(() =>
        {
Main/System/Guild/GuildBossHurtRankCell.cs
@@ -2,6 +2,7 @@
//    [Author]:           玩个游戏
//    [  Date ]:           Wednesday, September 26, 2018
//--------------------------------------------------------
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -52,7 +53,7 @@
                AvatarHelper.TryViewOtherPlayerInfo(playerID);
            });
        });
        officialTitleCell.InitUI(playerData.RealmLV, playerData.TitleID);
        officialTitleCell.InitUI(playerData.RealmLV, playerData.TitleID).Forget();
        nameText.text = playerData.Name;
        lvText.text = playerData.LV.ToString();
Main/System/Guild/GuildBossWin.cs
@@ -105,7 +105,7 @@
            UIManager.Instance.OpenWindowAsync<GuildBossAwardWin>().Forget();
        });
        bossModel.Create(GuildBossManager.Instance.bossSkinID, 1, motionName: "chuxian");
        bossModel.Create(GuildBossManager.Instance.bossSkinID, 1, motionName: "chuxian").Forget();
    }
Main/System/Guild/GuildDonateDetailCell.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -25,7 +26,7 @@
        nameText.text = playerInfo.Name;
        avatarCell.InitUI(AvatarHelper.GetAvatarModel(0, playerInfo.Face, playerInfo.FacePic));
        titleCell.InitUI(playerInfo.RealmLV, playerInfo.TitleID);
        titleCell.InitUI(playerInfo.RealmLV, playerInfo.TitleID).Forget();
        lvText.text = playerInfo.LV.ToString();
Main/System/Guild/GuildMemberCell.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -32,7 +33,7 @@
        nameText.text = playerInfo.Name;
        avatarCell.InitUI(AvatarHelper.GetAvatarModel(0, playerInfo.Face, playerInfo.FacePic));
        titleCell.InitUI(playerInfo.RealmLV, playerInfo.TitleID);
        titleCell.InitUI(playerInfo.RealmLV, playerInfo.TitleID).Forget();
        lvText.text = playerInfo.LV.ToString();
        if (playerInfo.FmLV > 0)
        {
Main/System/Guild/GuildPreviewWin.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -133,7 +134,7 @@
        var leaderInfo = OtherPlayerDetailManager.Instance.GetViewPlayerData(playerID);
        leaderAvatar.InitUI(AvatarHelper.GetAvatarModel(0, leaderInfo.Face, leaderInfo.FacePic));
        leaderTitle.InitUI(leaderInfo.RealmLV, leaderInfo.TitleID);
        leaderTitle.InitUI(leaderInfo.RealmLV, leaderInfo.TitleID).Forget();
        leaderLevelText.text = leaderInfo.LV.ToString();
        guildJobText.text = RichTextMsgReplaceConfig.GetRichReplace("FAMILY", 3);
        leaderFightPowerText.text = UIHelper.ReplaceLargeArtNum(leaderInfo.FightPower);
Main/System/HappyXB/HappyXBModel.cs
@@ -4,7 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks;
public partial class HappyXBModel : GameSystemManager<HappyXBModel>
@@ -189,7 +189,7 @@
        {
            if (!UIManager.Instance.IsOpened<HeroDebutCallResultWin>())
            {
                UIManager.Instance.OpenWindow<HeroDebutCallResultWin>();
                UIManager.Instance.OpenWindowAsync<HeroDebutCallResultWin>().Forget();
            }
        }
    }
Main/System/HappyXB/HeroCallResultCell.cs
@@ -93,7 +93,7 @@
    public void DisplayHero(HeroConfig heroConfig)
    {
        heroModel.SetActive(true);
        heroModel.Create(heroConfig.SkinIDList[0], 0.7f);
        heroModel.Create(heroConfig.SkinIDList[0], 0.7f).Forget();
    }
}
Main/System/HappyXB/HeroCallResultWin.cs
@@ -329,7 +329,7 @@
            return;
        }
        var hero = HeroConfig.Get(heroID);
        roleLHModel.Create(hero.SkinIDList[0], 1, motionName: "", isLh: true);
        roleLHModel.Create(hero.SkinIDList[0], 1, motionName: "", isLh: true).Forget();
        qualityImg.SetSprite("HeroCallQuality" + hero.Quality);
        newMarkLHImg.SetActive(HeroUIManager.Instance.IsNewHero(heroID));
        showLHResultCell.Display(heroID, 0, true);
@@ -342,7 +342,7 @@
        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(hero.SkinIDList[0], hero.Country));
        if (IsWishHero(heroID))
        {
            UIManager.Instance.OpenWindow<HeroCallXYFinishWin>();
            UIManager.Instance.OpenWindowAsync<HeroCallXYFinishWin>().Forget();
        }
    }
@@ -385,7 +385,7 @@
            if (IsWishHero(heroID))
            {
                // 抽到了心愿武将,打开完成特效界面
                UIManager.Instance.OpenWindow<HeroCallXYFinishWin>();
                UIManager.Instance.OpenWindowAsync<HeroCallXYFinishWin>().Forget();
                break;
            }
        }
Main/System/Hero/UIHeroController.cs
@@ -23,7 +23,8 @@
    private const int MAX_CONCURRENT_LOADS = 4;
    private static int currentLoadingCount = 0;
    private static readonly object loadLock = new object();
    private static int initializationOrder = 0; // 用于分帧延迟的序号
    private static int lastInitFrame = -1; // 上一次执行Initialize的帧号,用于确保每帧最多1次
    private static GameObjectPoolManager.GameObjectPool cachedUIHeroPool; // 缓存UIHero预制体池
    public Action onComplete;
    public async UniTask Create(int _skinID, float scale = 0.8f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
@@ -81,12 +82,10 @@
            {
                //图片替换
                lhImg.SetTexture2DPNG(skinConfig.Tachie);
                lhImg.SetNativeSize();
                if (skeletonGraphic != null)
                {
                    skeletonGraphic.enabled = false;
                }
                lhImg.enabled = true;
                lhImg.raycastTarget = false;
                return;
            }
@@ -201,7 +200,9 @@
        }
        onComplete = _onComplete;
        pool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHero"));
        if (cachedUIHeroPool == null)
            cachedUIHeroPool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHero"));
        pool = cachedUIHeroPool;
        if (this == null) return;
        if (!transform.gameObject.activeSelf)
@@ -251,6 +252,10 @@
        }
        skeletonGraphic.enabled = true;
        // 注册到SpineUpdateManager,批量更新减少跨语言调用开销
        SpineUpdateManager.Instance.Register(skeletonGraphic);
        // 不可见时完全停止更新,滚动列表场景收益很大
        skeletonGraphic.updateWhenInvisible = Spine.Unity.UpdateMode.Nothing;
        SetMaterialNone();
        spineAnimationState = skeletonGraphic.AnimationState;
@@ -262,7 +267,7 @@
        spineAnimationState.Complete -= OnAnimationComplete;
        spineAnimationState.Complete += OnAnimationComplete;
#if UNITY_EIDTOR
#if UNITY_EDITOR
        await UniTask.Delay(100);
        if (skeletonGraphic != null && skeletonGraphic.material != null)
        {
@@ -292,6 +297,9 @@
        {
            spineAnimationState.Complete -= OnAnimationComplete;
        }
        // 从SpineUpdateManager中移除
        if (skeletonGraphic != null)
            SpineUpdateManager.Instance.Unregister(skeletonGraphic);
        if (pool != null)
            pool.Release(instanceGO);
        skeletonGraphic = null;
@@ -452,7 +460,35 @@
            Debug.LogWarning("skeletonGraphic is null, cannot set material to none");
            return;
        }
        skeletonGraphic.material = null;
        skeletonGraphic.material = GetDefaultSpineMaterial();
    }
    /// <summary>
    /// 获取默认的 Spine 渲染材质。
    /// 对于包含非 Normal 混合模式(Additive/Multiply/Screen)插槽的角色,
    /// 返回 atlas 原始材质(Blend One OneMinusSrcAlpha),保证 PMA 混合正确;
    /// 对于普通角色,返回 null(使用 Canvas 默认材质,行为不变)。
    /// </summary>
    private Material GetDefaultSpineMaterial()
    {
        if (skeletonGraphic == null || skeletonGraphic.Skeleton == null)
            return null;
        var slotsData = skeletonGraphic.Skeleton.Data.Slots;
        for (int i = 0; i < slotsData.Count; i++)
        {
            if (slotsData.Items[i].BlendMode != Spine.BlendMode.Normal)
            {
                // 存在非 Normal 混合模式的插槽,必须使用 Spine 材质
                // Canvas 默认材质的 Blend SrcAlpha OneMinusSrcAlpha 会导致
                // PMA Additive 效果(vertex alpha=0)完全消失
                var dataAsset = skeletonGraphic.skeletonDataAsset;
                if (dataAsset != null && dataAsset.atlasAssets.Length > 0)
                    return dataAsset.atlasAssets[0].PrimaryMaterial;
                break;
            }
        }
        return null;
    }
    /// <summary>
@@ -475,30 +511,16 @@
            // 异步创建instanceGO和加载资源(真正的异步,不阻塞)
            await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh, cancellationToken);
            // 获取当前序号用于分帧延迟
            int myOrder;
            lock (loadLock)
            {
                myOrder = initializationOrder++;
            }
            // 再次检查是否已被取消
            cancellationToken.ThrowIfCancellationRequested();
            // 在 skeletonGraphic.Initialize() 前进行分帧延迟
            // 根据 MAX_CONCURRENT_LOADS 调整延迟,避免所有对象同时执行 Initialize
            int delayFrames = (myOrder % MAX_CONCURRENT_LOADS);
            if (delayFrames > 0)
            // 确保每帧最多执行1次Initialize(true),避免同帧大量骨骼解析导致卡顿
            while (Time.frameCount == lastInitFrame)
            {
                for (int i = 0; i < delayFrames; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await UniTask.NextFrame(cancellationToken);
                }
                cancellationToken.ThrowIfCancellationRequested();
                await UniTask.NextFrame(cancellationToken);
            }
            // 再次检查是否已被取消(可能在延迟期间被取消)
            cancellationToken.ThrowIfCancellationRequested();
            lastInitFrame = Time.frameCount;
            if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
            {
@@ -508,6 +530,7 @@
            skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
            skeletonGraphic.Initialize(true);
            Debug.Log($"[UIHeroController] Spine Initialize完成, skeleton valid: {skeletonGraphic.IsValid}, enabled: {skeletonGraphic.enabled}");
            // 初始化完成后设置皮肤
            if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
@@ -524,13 +547,18 @@
            // 初始化完成后才显示模型
            skeletonGraphic.enabled = pendingEnabled;
            // 注册到SpineUpdateManager,批量更新减少跨语言调用开销
            SpineUpdateManager.Instance.Register(skeletonGraphic);
            // 不可见时完全停止更新,滚动列表场景收益很大
            skeletonGraphic.updateWhenInvisible = Spine.Unity.UpdateMode.Nothing;
            if (pendingGray)
            {
                skeletonGraphic.material = MaterialUtility.GetDefaultSpriteGrayMaterial();
            }
            else
            {
                skeletonGraphic.material = null;
                skeletonGraphic.material = GetDefaultSpineMaterial();
            }
            // 检查是否有待设置的速度,如果有则设置
@@ -573,7 +601,7 @@
        }
        catch (System.Exception e)
        {
            Debug.LogError($"英雄初始化异常: {e.Message}");
            Debug.LogError($"英雄初始化异常: {e.Message}\n{e.StackTrace}");
            isInitializing = false;
        }
        finally
@@ -633,8 +661,10 @@
        // 检查是否已被取消
        cancellationToken.ThrowIfCancellationRequested();
        // 创建pool和instanceGO
        pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
        // 创建pool和instanceGO(使用缓存避免重复加载预制体)
        if (cachedUIHeroPool == null)
            cachedUIHeroPool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHero"));
        pool = cachedUIHeroPool;
        if (instanceGO == null)
        {
@@ -650,6 +680,7 @@
        // 真正的异步加载资源 - 不阻塞主线程
        string assetName = isLh ? skinConfig.Tachie : skinConfig.SpineRes;
        Debug.Log($"[UIHeroController] 开始加载spine 资源: {assetName}");
        SkeletonDataAsset loadedAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("Hero/SpineRes/", assetName);
        // 再次检查是否已被取消
@@ -658,6 +689,7 @@
        if (loadedAsset != null)
        {
            skeletonGraphic.skeletonDataAsset = loadedAsset;
            Debug.Log($"[UIHeroController] Spine资源加载成功: {assetName}, atlas count: {loadedAsset.atlasAssets?.Length}");
        }
        else
        {
Main/System/HeroDebut/HeroDebutCallChangeWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
public class HeroDebutCallChangeWin : UIBase
@@ -33,7 +34,7 @@
        previewButton.SetListener(() =>
        {
            HeroUIManager.Instance.selectForPreviewHeroID = manager.nowCallChooseHeroID;
            UIManager.Instance.OpenWindow<HeroBestBaseWin>();
            UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
        });
    }
@@ -95,6 +96,6 @@
        var skinConfig = HeroSkinConfig.Get(skinID);
        if (skinConfig == null) return;
        uiHeroController.Create(skinID, 1);
        uiHeroController.Create(skinID, 1).Forget();
    }
}
Main/System/HeroDebut/HeroDebutCallRateItem.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -62,7 +63,7 @@
                HeroDebutCallRateHeroWin.worldPos = libButton.transform.position;
                HeroDebutCallRateHeroWin.dataList = GetLibItemList(libID, list);
                HeroDebutCallRateHeroWin.isDownShow = true;
                UIManager.Instance.OpenWindow<HeroDebutCallRateHeroWin>();
                UIManager.Instance.OpenWindowAsync<HeroDebutCallRateHeroWin>().Forget();
            });
        }
    }
Main/System/HeroDebut/HeroDebutCallResultWin.cs
@@ -1,6 +1,7 @@
using UnityEngine;
using DG.Tweening;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
public class HeroDebutCallResultWin : UIBase
{
@@ -335,7 +336,7 @@
            if (!UIManager.Instance.IsOpenedInList<HeroShowLHWin>())
            {
                UIManager.Instance.OpenWindow<HeroShowLHWin>();
                UIManager.Instance.OpenWindowAsync<HeroShowLHWin>().Forget();
            }
        }
    }
Main/System/HeroDebut/HeroDebutCallWin.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
@@ -51,12 +52,12 @@
    protected override void InitComponent()
    {
        closeButton.SetListener(CloseWindow);
        shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutShopWin>());
        giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutGiftWin>());
        changeHeroButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallChangeWin>());
        rankButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutRankWin>());
        rateButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallRateWin>());
        historyButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallHistoryWin>());
        shopButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutShopWin>().Forget());
        giftButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutGiftWin>().Forget());
        changeHeroButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutCallChangeWin>().Forget());
        rankButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutRankWin>().Forget());
        rateButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutCallRateWin>().Forget());
        historyButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutCallHistoryWin>().Forget());
        previewButton.SetListener(OnClickPreview);
        skipToggle.AddListener((value) =>
        {
@@ -216,7 +217,7 @@
    {
        if (heroConfig == null) return;
        HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
        UIManager.Instance.OpenWindow<HeroBestBaseWin>();
        UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
    }
    OperationHeroAppearInfo act;
    ActHeroAppearConfig config;
@@ -251,8 +252,8 @@
        bgImage.SetSprite(artConfig.MainBgImage);
        lhController.Create(skinID, 1, motionName: "", isLh: true);
        uiHeroController.Create(skinID, modleSize);
        lhController.Create(skinID, 1, motionName: "", isLh: true).Forget();
        uiHeroController.Create(skinID, modleSize).Forget();
        uiHeroController.transform.localScale = new Vector3(modleSize, modleSize, modleSize);
        ownItemCell.itemID = treasureSetConfig.CostItemID;
Main/System/HeroDebut/HeroDebutCell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
public class HeroDebutCell : MonoBehaviour
{
@@ -10,7 +11,7 @@
    {
        clickButton.SetListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroDebutWin>();
            UIManager.Instance.OpenWindowAsync<HeroDebutWin>().Forget();
        });
Main/System/HeroDebut/HeroDebutCheckInWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
public class HeroDebutCheckInWin : UIBase
@@ -76,7 +77,7 @@
            }
        }
        rolelhShow.Create(skinID, 1, motionName: "", isLh: true);
        rolelhShow.Create(skinID, 1, motionName: "", isLh: true).Forget();
        OnSecondEvent();
    }
}
Main/System/HeroDebut/HeroDebutGiftCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class HeroDebutGiftCell : MonoBehaviour
@@ -78,13 +79,13 @@
            if (config.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
            {
                SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                return;
            }
            if (config.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
            {
                SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                return;
            }
            RechargeManager.Instance.CTG(ctgId);
Main/System/HeroDebut/HeroDebutManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using LitJson;
using UnityEngine;
@@ -159,14 +160,7 @@
    public void SetHeroSquareIcon(ImageEx image, string name)
    {
        var sprite = UILoader.LoadSprite("HeroHead", name);
        if (sprite != null)
        {
            image.overrideSprite = sprite;
            return;
        }
        image.SetSprite("herohead_default");
        UILoader.LoadSprite("HeroHead", name, image, "herohead_default").Forget();
    }
    public void GetActTimeStr(TextEx timeText, string key = "TimeRush05")
Main/System/HeroDebut/HeroDebutPopWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -24,7 +25,7 @@
        {
            UIManager.Instance.CloseWindow<HeroDebutPopWin>();
            if (!UIManager.Instance.IsOpened<HeroDebutWin>())
                UIManager.Instance.OpenWindow<HeroDebutWin>();
                UIManager.Instance.OpenWindowAsync<HeroDebutWin>().Forget();
        });
        todayPopToggle.AddListener((bool value) =>
        {
@@ -89,7 +90,7 @@
        infoText.text = artConfig.PopInfoText;
        infoText.color = manager.ParseColor32(artConfig.PopInfoColor);
        rolelhShow.Create(skinID, 1, motionName: "", isLh: true);
        rolelhShow.Create(skinID, 1, motionName: "", isLh: true).Forget();
        OnSecondEvent();
    }
Main/System/HeroDebut/HeroDebutRankCell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -41,7 +42,7 @@
                rankText.text = Language.Get("L1045");
                rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue);
                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                return;
            }
            rank = rankData.rank;
@@ -56,7 +57,7 @@
        else
        {
            officialTitleCell.SetActive(true);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
            avatarCell.SetActive(true);
            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
            viewPlayerId = (int)rankData.id;
Main/System/HeroDebut/HeroDebutRankTop3Cell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -34,9 +35,9 @@
        officialTitleCell.SetActive(true);
        rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue));
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.SetActive(true);
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f);
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f).Forget();
        queryPlayerBtn.SetListener(() =>
        {
            AvatarHelper.TryViewOtherPlayerInfo((int)rankData.id);
Main/System/HeroDebut/HeroDebutShopCell.cs
@@ -1,4 +1,5 @@
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
public class HeroDebutShopCell : MonoBehaviour
@@ -128,7 +129,7 @@
        else
        {
            StoreModel.Instance.buyShopID = shopID;
            UIManager.Instance.OpenWindow<BuyItemWin>();
            UIManager.Instance.OpenWindowAsync<BuyItemWin>().Forget();
        }
    }
}
Main/System/HeroDebut/HeroDebutSkinWin.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -32,7 +33,7 @@
            int heroID = manager.GetHeroIDBySkinID(manager.currentChooseSkinID);
            HeroUIManager.Instance.selectForPreviewHeroID = heroID;
            HeroUIManager.Instance.selectSkinIndex = manager.GetSkinIndexInHeroConfig(heroID, manager.currentChooseSkinID);
            UIManager.Instance.OpenWindow<HeroBestBaseWin>(1);
            UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>(1).Forget();
        });
    }
@@ -179,8 +180,8 @@
        awardBgImage.SetSprite(skinArtConfig.AwardBGImage);
        awardBgImage.SetNativeSize();
        uiHeroController.Create(skinID, modelScale);
        lhController.Create(skinID, 1, motionName: "", isLh: true);
        uiHeroController.Create(skinID, modelScale).Forget();
        lhController.Create(skinID, 1, motionName: "", isLh: true).Forget();
        countryImage.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        OnSecondEvent();
Main/System/HeroDebut/HeroDebutStarUpWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
public class HeroDebutStarUpWin : UIBase
@@ -16,14 +17,14 @@
        goCallButton.SetListener(() =>
        {
            UIManager.Instance.CloseWindow<HeroDebutStarUpWin>();
            UIManager.Instance.OpenWindow<HeroDebutCallWin>();
            UIManager.Instance.OpenWindowAsync<HeroDebutCallWin>().Forget();
        });
        goInfoButton.SetListener(() =>
        {
            if (heroConfig == null) return;
            UIManager.Instance.CloseWindow<HeroDebutStarUpWin>();
            HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
            UIManager.Instance.OpenWindow<HeroBestBaseWin>();
            UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
        });
    }
Main/System/HeroDebut/HeroDebutWin.cs
@@ -1,4 +1,5 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -33,12 +34,12 @@
    protected override void InitComponent()
    {
        closeButton.SetListener(() => UIManager.Instance.CloseWindow<HeroDebutWin>());
        checkInButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCheckInWin>());
        starUpButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutStarUpWin>());
        shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutShopWin>());
        skinButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutSkinWin>());
        giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutGiftWin>());
        callButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallWin>());
        checkInButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutCheckInWin>().Forget());
        starUpButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutStarUpWin>().Forget());
        shopButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutShopWin>().Forget());
        skinButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutSkinWin>().Forget());
        giftButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutGiftWin>().Forget());
        callButton.SetListener(() => UIManager.Instance.OpenWindowAsync<HeroDebutCallWin>().Forget());
    }
    protected override void OnPreOpen()
@@ -92,9 +93,9 @@
        var skinArtConfig = ActHeroAppearSkinArtConfig.Get(artConfig.MainSkinID);
        if (skinArtConfig == null) return;
        uiHeroController.Create(skinID, modleSize);
        uiHeroController.Create(skinID, modleSize).Forget();
        uiHeroController.transform.localScale = new Vector3(-modleSize, modleSize, modleSize);
        lhController.Create(skinID, 1, motionName: "", isLh: true);
        lhController.Create(skinID, 1, motionName: "", isLh: true).Forget();
        callRedImage.SetActive(!manager.IsShopVisitedToday || manager.HasGiftCanHave());
Main/System/HeroFates/HeroFatesIHItem.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -21,7 +22,7 @@
        uiHeroController.Create(heroSkinConfig.SkinID, lhSize);
        uiHeroController.Create(heroSkinConfig.SkinID, lhSize).Forget();
        bool isHasHero = HeroManager.Instance.HasHero(heroId);
        if (isHasHero)
        {
@@ -48,12 +49,12 @@
                }
                HeroInfo heroInfo = nowMaxStarHeroDict[heroId];
                HeroUIManager.Instance.selectHeroGuid = heroInfo.itemHero.guid;
                UIManager.Instance.OpenWindow<HeroTrainBaseWin>();
                UIManager.Instance.OpenWindowAsync<HeroTrainBaseWin>().Forget();
            }
            else
            {
                HeroUIManager.Instance.selectForPreviewHeroID = heroId;
                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
                UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
            }
        });
    }
Main/System/HeroUI/HeroBestBaseWin.cs
@@ -1,19 +1,20 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
public class HeroBestBaseWin : OneLevelWin
{
    protected override void OpenSubUIByTabIndex()
    protected override async void OpenSubUIByTabIndex()
    {
        ShowSkinBtn();
        switch (functionOrder)
        {
            case 0:
                currentSubUI = UIManager.Instance.OpenWindow<HeroBestWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<HeroBestWin>();
                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
                {
@@ -23,7 +24,7 @@
            case 1:
                //皮肤 图鉴界面打开的传1
                currentSubUI = UIManager.Instance.OpenWindow<HeroSkinWin>(1);
                currentSubUI = await UIManager.Instance.OpenWindowAsync<HeroSkinWin>(1);
                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
                {
Main/System/HeroUI/HeroBestWin.cs
@@ -137,8 +137,8 @@
        heroConfig = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
        int skinID = heroConfig.SkinIDList[0];
        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(skinID, heroConfig.Country));
        roleLhModel.Create(skinID, 1, motionName: "", isLh: true);
        roleXsModel.Create(skinID, 1);
        roleLhModel.Create(skinID, 1, motionName: "", isLh: true).Forget();
        roleXsModel.Create(skinID, 1).Forget();
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(heroConfig.Class);
        descText.text = heroConfig.Desc;
Main/System/HeroUI/HeroCardCell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
@@ -38,7 +39,7 @@
        var heroConfig = hero.heroConfig;
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale);
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale).Forget();
        onStateImg.SetActive(hero.IsInTeamByTeamType(BattlePreSetType.Story));
        int teamPos = TeamManager.Instance.GetTeam(BattlePreSetType.Story).GetPosition(hero.itemHero.guid);
@@ -92,7 +93,7 @@
        heroCardBtn.AddListener(() =>
        {
            HeroUIManager.Instance.selectHeroGuid = guid;
            UIManager.Instance.OpenWindow<HeroTrainBaseWin>(funcState == 3 ? 1 : 0);
            UIManager.Instance.OpenWindowAsync<HeroTrainBaseWin>(funcState == 3 ? 1 : 0).Forget();
        });
    }
}
Main/System/HeroUI/HeroCollectionCardCell.cs
@@ -1,6 +1,8 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Threading;
public class HeroCollectionCardCell : MonoBehaviour
{
@@ -17,6 +19,8 @@
    [SerializeField] GameObject unGetObj;
    [SerializeField] GameObject activeObj; // 可激活带流光效果材质
    [SerializeField] GameObject actLimitObj; // 活动限定
    private CancellationTokenSource displayCts;
    public void Display(int index, int quality)
    {
        var heroID = HeroUIManager.Instance.heroCollectDict[quality][index];
@@ -38,7 +42,12 @@
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        heroModel.Create(heroConfig.SkinIDList[0], heroConfig.UIScale);
        // 去抖加载:快速滚动时延迟2帧再创建Spine,如果卡片在延迟内被复用则取消旧加载
        displayCts?.Cancel();
        displayCts?.Dispose();
        displayCts = new CancellationTokenSource();
        DelayedCreateSpine(heroConfig.SkinIDList[0], heroConfig.UIScale, displayCts.Token).Forget();
        redpoint.redpointId = MainRedDot.HeroCardCollectRedpoint * 10000000 + heroID;
@@ -64,12 +73,12 @@
            var state = HeroUIManager.Instance.GetHeroBookState(heroID, quality);
            if (state == 1 || state == 3 || state == 4)
            {
                UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
                UIManager.Instance.OpenWindowAsync<HeroCollectionLvUpWin>().Forget();
            }
            else
            {
                HeroUIManager.Instance.selectForPreviewHeroID = heroID;
                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
                UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
            }
        });
        
@@ -79,5 +88,19 @@
        //     UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
        // });
    }
    private async UniTaskVoid DelayedCreateSpine(int skinID, float scale, CancellationToken ct)
    {
        // 延迟2帧,快速滚动时卡片会被复用,CTS取消后不会继续创建Spine
        await UniTask.NextFrame(ct);
        await UniTask.NextFrame(ct);
        heroModel.Create(skinID, scale).Forget();
    }
    void OnDestroy()
    {
        displayCts?.Cancel();
        displayCts?.Dispose();
    }
}
Main/System/HeroUI/HeroCollectionWin.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -20,13 +21,13 @@
    SinglePack singlePack;
    protected override void InitComponent()
    protected override async void InitComponent()
    {
        attrBtn.AddListener(() =>
        {
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            SmallTipWin.showText = Language.Get("herocard6");
            UIManager.Instance.OpenWindow<SmallTipWin>();
            UIManager.Instance.OpenWindowAsync<SmallTipWin>().Forget();
        });
        heroPackBtn.AddListener(() =>
@@ -34,7 +35,7 @@
            HeroUIManager.Instance.QueryUnLockHeroPack();
        });
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
        fiterManager = await HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
@@ -66,7 +67,7 @@
    void Display()
    {
        fiterManager.Display(0, SelectJobCountry);
        fiterManager?.Display(0, SelectJobCountry);
        // CreateScroller();
        // RefreshTotalAttr();
Main/System/HeroUI/HeroGiftEatSuccessWin.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -74,7 +75,7 @@
        var heroConfig = hero.heroConfig;
        taiziBG.SetSprite("herodz" + heroConfig.Quality);
        heroModel.Create(hero.SkinID, heroConfig.UIScale);
        heroModel.Create(hero.SkinID, heroConfig.UIScale).Forget();
        nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, hero.breakLevel);
        nameText.color = UIHelper.GetUIColorByFunc(heroConfig.Quality);
    }
Main/System/HeroUI/HeroScenePosCell.cs
@@ -29,7 +29,7 @@
        lvText.text = Language.Get("L1099", hero.heroLevel);
        var heroConfig = hero.heroConfig;
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale);
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale).Forget();
        nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, hero.breakLevel);
        posCircleImg.SetSprite("heroposcircle" + heroConfig.Quality);
Main/System/HeroUI/HeroSkinRoleCell.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
public class HeroSkinRoleCell : MonoBehaviour
@@ -12,7 +13,7 @@
    public void Display(HeroConfig heroConfig, int index)
    {
        selectImg.SetActive(HeroSkinChooseWin.selectIndex == index);
        heroModel.Create(heroConfig.SkinIDList[index], heroConfig.UIScale);
        heroModel.Create(heroConfig.SkinIDList[index], heroConfig.UIScale).Forget();
        selectBtn.AddListener(() =>
        {
            var ui = UIManager.Instance.GetUI<HeroSkinChooseWin>();
Main/System/HeroUI/HeroSkinWin.cs
@@ -1,4 +1,5 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -61,7 +62,7 @@
        });
        shopBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<StoreBaseWin>(1);
            UIManager.Instance.OpenWindowAsync<StoreBaseWin>(1).Forget();
        });
        unlockBtn.AddListener(() =>
        {
@@ -85,7 +86,7 @@
        
        changeClothBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroSkinChooseWin>();
            UIManager.Instance.OpenWindowAsync<HeroSkinChooseWin>().Forget();
        });
    }
@@ -158,8 +159,8 @@
        
        skinID = heroConfig.SkinIDList[tmpIndex];
        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(skinID, heroConfig.Country));
        roleLhModel.Create(skinID, 1, motionName: "", isLh: true);
        roleXsModel.Create(skinID, 1);
        roleLhModel.Create(skinID, 1, motionName: "", isLh: true).Forget();
        roleXsModel.Create(skinID, 1).Forget();
        HeroUIManager.Instance.PlayerLHSound(skinID);
        nameText.text = heroConfig.Name;
Main/System/HeroUI/HeroTrainBaseWin.cs
@@ -1,13 +1,14 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
// 武将功能界面
public class HeroTrainBaseWin : OneLevelWin
{
    protected override void OpenSubUIByTabIndex()
    protected override async void OpenSubUIByTabIndex()
    {
        ShowSkinBtn();
        switch (functionOrder)
@@ -19,7 +20,7 @@
                {
                    UIManager.Instance.CloseWindow<HeroTrainWin>();
                }
                currentSubUI = UIManager.Instance.OpenWindow<HeroTrainWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<HeroTrainWin>();
                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
                {
@@ -32,7 +33,7 @@
                {
                    UIManager.Instance.CloseWindow<HeroTrainWin>();
                }
                currentSubUI = UIManager.Instance.OpenWindow<HeroTrainWin>(1);
                currentSubUI = await UIManager.Instance.OpenWindowAsync<HeroTrainWin>(1);
                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
                {
@@ -41,7 +42,7 @@
                break;
            case 2:
                //皮肤
                currentSubUI = UIManager.Instance.OpenWindow<HeroSkinWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<HeroSkinWin>();
                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
                {
Main/System/HeroUI/HeroTrainWin.cs
@@ -224,7 +224,7 @@
        if (functionOrder == 0)
        {
            DisplayTrainOrBreak(hero);
            ForceRefreshLayout();
            ForceRefreshLayout().Forget();
        }
        else if (functionOrder == 1)
        {
@@ -267,9 +267,9 @@
    public void Display()
    {
        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(hero.SkinID, hero.heroConfig.Country));
        roleLhModel.Create(hero.SkinID, 1, motionName: "", isLh: true);
        roleLhModel.Create(hero.SkinID, 1, motionName: "", isLh: true).Forget();
        
        roleXsModel.Create(hero.SkinID, 1);
        roleXsModel.Create(hero.SkinID, 1).Forget();
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class));
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(hero.heroConfig.Class);
        descText.text = hero.heroConfig.Desc;
@@ -305,7 +305,7 @@
        ShowDeleteTip();
        HeroUIManager.Instance.RemoveNewHero(hero.heroId);
        ForceRefreshLayout();
        ForceRefreshLayout().Forget();
    }
Main/System/Horse/HorseController.cs
@@ -1,5 +1,6 @@
using System;
using Cysharp.Threading.Tasks;
using Spine.Unity;
using UnityEngine;
using UnityEngine.UI;
@@ -21,9 +22,10 @@
    // 创建坐骑 :id为0空坐骑也有配置
    //_skinID 坐骑的皮肤ID
    public void Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
    public async UniTask Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
    {
        pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHorse"));
        pool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHorse"));
        if (this == null) return;
        if (instanceGO == null)
        {
            instanceGO = pool.Request();
@@ -43,7 +45,7 @@
            {
                skeletonGraphic.enabled = false;
            }
            CreateHero(_heroSkinID, scale);
            await CreateHero(_heroSkinID, scale);
            //避免重复创建
            return;
        }
@@ -66,11 +68,12 @@
            //卸下坐骑的情况
            skeletonGraphic.enabled = false;
            spineAnimationState = null;
            CreateHero(_heroSkinID, scale);
        await CreateHero(_heroSkinID, scale);
            return;
        }
        skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
        skeletonGraphic.skeletonDataAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
        if (this == null) return;
        if (skeletonGraphic.skeletonDataAsset == null)
        {
@@ -92,12 +95,13 @@
        if (motionName == "")
            motionName = GetFistSpineAnim();
        PlayAnimation(motionName, true);
        CreateHero(_heroSkinID, scale);
        await CreateHero(_heroSkinID, scale);
        if (this == null) return;
        spineAnimationState.Complete -= OnAnimationComplete;
        spineAnimationState.Complete += OnAnimationComplete;
    }
    public void CreateHero(int heroSkinID, float _scale)
    public async UniTask CreateHero(int heroSkinID, float _scale)
    {
        if (instanceGO == null)
        {
@@ -122,7 +126,8 @@
            return;
        }
        hero.SetActive(true);
        hero.Create(heroSkinID, _scale);
        await hero.Create(heroSkinID, _scale);
        if (this == null) return;
        
        // 确保 BoneFollowerGraphic 引用到正确的坐骑 SkeletonGraphic
        var boneFollower = hero.GetComponent<BoneFollowerGraphic>();
Main/System/InternalAffairs/GoldRushLeader.cs
@@ -36,7 +36,7 @@
                                leaderPathPointArr[leaderPathPointArr.Length - 1].transform.localPosition;
        OnComplete = _OnComplete;
        this.SetActive(true);
        leader.Create(GoldRushManager.Instance.GetWorkerSkinID(tendID, index), leaderScale);
        leader.Create(GoldRushManager.Instance.GetWorkerSkinID(tendID, index), leaderScale).Forget();
        Go(waitTime, isBack).Forget();
    }
Main/System/InternalAffairs/GoldRushWorkCell.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -78,7 +79,7 @@
                {
                    heroModels[i].SetActive(true);
                    var skinID = GoldRushManager.Instance.GetWorkerSkinID(campID, i);
                    heroModels[i].Create(skinID, 0.6f, motionName:"run");
                    heroModels[i].Create(skinID, 0.6f, motionName:"run").Forget();
                }
                else
                {
Main/System/InternalAffairs/GoldRushWorkerCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -22,7 +23,7 @@
    {
        var config = GoldRushWorkerConfig.Get(workerID);
        nameText.text = config.Name;
        heroModel.Create(config.SkinID, 0.8f);
        heroModel.Create(config.SkinID, 0.8f).Forget();
        var lockState = GoldRushManager.Instance.GetWorkerLockState(workerID);
        if (lockState == 0)
        {
Main/System/Invest/InvestModel.cs
@@ -1,6 +1,7 @@

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine.UI;
using System.Linq;
using LitJson;
@@ -163,7 +164,7 @@
            if (count < rechargeCount.totalCount)
            {
                lastTotalBuyCountDict[type] = rechargeCount.totalCount;
                UIManager.Instance.OpenWindow<PrivilegeActiveCardWin>(type);
                UIManager.Instance.OpenWindowAsync<PrivilegeActiveCardWin>(type).Forget();
            }
        }
    }
Main/System/ItemTip/ItemTipWayWin.cs
@@ -1,6 +1,7 @@

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -102,7 +103,7 @@
                if (StoreModel.Instance.CheckPopBuyWin(shopID))
                {
                    StoreModel.Instance.buyShopID = shopID;
                    UIManager.Instance.OpenWindow<BuyItemWin>();
                    UIManager.Instance.OpenWindowAsync<BuyItemWin>().Forget();
                }
                break;
            case 2:
@@ -116,7 +117,7 @@
                }
                else
                {
                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(2).Forget();
                }
                break;
            case 3:
@@ -127,7 +128,7 @@
                }
                if (!UIManager.Instance.IsOpened<TimingGiftWin>())
                {
                    UIManager.Instance.OpenWindow<TimingGiftWin>(int.Parse(way.CustomValue));
                    UIManager.Instance.OpenWindowAsync<TimingGiftWin>(int.Parse(way.CustomValue)).Forget();
                }
                break;
            case 0:
Main/System/ItemTip/OwnMoneyCell.cs
@@ -1,4 +1,5 @@
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
//拥有的货币:数量显示,点击按钮打开对应获取界面
@@ -31,7 +32,7 @@
                                }
                                else
                                {
                                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(2).Forget();
                                }
                            }
                        }
@@ -47,7 +48,7 @@
                                }
                                else
                                {
                                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(2).Forget();
                                }
                            }
                        }
Main/System/Language/Language.cs
@@ -47,10 +47,10 @@
        languageStartDict = JsonMapper.ToObject<Dictionary<string, string[]>>(config.Numerical2);
        languageDict = JsonMapper.ToObject<Dictionary<string, string>>(config.Numerical3);
        if (languageStartDict == null || !languageStartDict.ContainsKey(VersionConfigEx.Get().appId))
        if (languageStartDict == null || !languageStartDict.ContainsKey(VersionConfigEx.config.appId))
        {
            //检查有没多语言
            Debug.Log("当前渠道未开启多语言:" + VersionConfigEx.Get().appId);
            Debug.Log("当前渠道未开启多语言:" + VersionConfigEx.config.appId);
            return;
        }
@@ -64,7 +64,7 @@
            return;
        }
        var defaultCfg = languageStartDict[VersionConfigEx.Get().appId];
        var defaultCfg = languageStartDict[VersionConfigEx.config.appId];
        string languageMark;
        if (defaultCfg[1] == "0")
        {
@@ -109,7 +109,7 @@
            {
                return "";
            }
            if (!languageStartDict.ContainsKey(VersionConfigEx.Get().appId))
            if (!languageStartDict.ContainsKey(VersionConfigEx.config.appId))
            {
                return "";
            }
Main/System/LineupRecommend/LineupRecommendItem.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
public class LineupRecommendItem : MonoBehaviour
@@ -29,15 +30,7 @@
        if (!manager.TryGetHeroSkinConfig(heroID, out HeroSkinConfig heroSkinConfig))
            return;
        var sprite = UILoader.LoadSprite("HeroHead", heroSkinConfig.SquareIcon);
        if (sprite == null)
        {
            imgHeroHead.SetSprite("herohead_default");
        }
        else
        {
            imgHeroHead.overrideSprite = sprite;
        }
        UILoader.LoadSprite("HeroHead", heroSkinConfig.SquareIcon, imgHeroHead, "herohead_default").Forget();
        imgSquareIcon.SetSprite("heroheadBG" + heroConfig.Quality);
        imgCountry.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
@@ -66,7 +59,7 @@
            else
            {
                HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
                UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>().Forget();
            }
        });
Main/System/Login/LoginWin.cs
@@ -406,6 +406,10 @@
        {
            if (isOk)
            {
#if UNITY_WEBGL
                // WebGL无本地文件系统,仅清理PlayerPrefs
                LocalSave.DeleteAll();
#else
                try
                {
                    LocalSave.DeleteAll();
@@ -441,15 +445,12 @@
                {
                    Debug.LogError("Failed to clean persistent data: " + e.Message);
                }
                finally
#endif
                Clock.AlarmAfter(0.1f, () =>
                {
                    Clock.AlarmAfter(0.1f, () =>
                    {
                        Application.Quit();
                    });
                    Debug.Log("Persistent data cleaned.");
                }
                    Application.Quit();
                });
                Debug.Log("Persistent data cleaned.");
            }
        });
Main/System/Main/HeroFightingCardCell.cs
@@ -1,4 +1,5 @@
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
@@ -95,16 +96,7 @@
        var heroConfig = HeroConfig.Get(heroID);
        qualityBG.SetSprite("herocBG" + heroConfig.Quality);
        var sprite = UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(hero.SkinID).RectangleIcon);
        if (sprite == null)
        {
            // 内网未配置时
            heroIcon.SetSprite("herohead_big_default");
        }
        else
        {
            heroIcon.overrideSprite = sprite;
        }
        UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(hero.SkinID).RectangleIcon, heroIcon, "herohead_big_default").Forget();
        if (star == 0)
        {
@@ -139,7 +131,7 @@
    {
        HeroUIManager.Instance.SortHeroList();
        HeroUIManager.Instance.selectHeroGuid = guid;
        UIManager.Instance.OpenWindow<HeroTrainBaseWin>();
        UIManager.Instance.OpenWindowAsync<HeroTrainBaseWin>().Forget();
    }
    void ClickEmpty()
@@ -158,7 +150,7 @@
            }
            return;
        }
        UIManager.Instance.OpenWindow<HeroPosWin>();
        UIManager.Instance.OpenWindowAsync<HeroPosWin>().Forget();
    }
    void OnSkillCast(bool isfighting)
    {
Main/System/Main/HomeWin.cs
@@ -217,15 +217,15 @@
        });
        osBeautyMMBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<OSBeautyMMBaseWin>();
            UIManager.Instance.OpenWindowAsync<OSBeautyMMBaseWin>().Forget();
        });
        osHeroTrainBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<OSHeroTrainBaseWin>();
            UIManager.Instance.OpenWindowAsync<OSHeroTrainBaseWin>().Forget();
        });
        osMinggeBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<OSMinggeBaseWin>();
            UIManager.Instance.OpenWindowAsync<OSMinggeBaseWin>().Forget();
        });
        DailySpecialsBtns.AddListener(() =>
        {
Main/System/Main/MainWin.cs
@@ -197,7 +197,7 @@
        playerNameText.text = PlayerDatas.Instance.baseData.PlayerName;
        powerText.text = UIHelper.ReplaceLargeArtNum(PlayerDatas.Instance.baseData.FightPower);
        officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
        officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
    }
    void PlayerDataRefresh(PlayerDataType type)
@@ -208,7 +208,7 @@
                powerText.text = UIHelper.ReplaceLargeArtNum(PlayerDatas.Instance.baseData.FightPower);
                break;
            case PlayerDataType.RealmLevel:
                officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                break;
            case PlayerDataType.Face:
            case PlayerDataType.FacePic:
@@ -220,7 +220,7 @@
                hammerText.text = UIHelper.GetMoneyCnt(41).ToString();
                break;
            case PlayerDataType.ExAttr3:
                officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                break;
        }
Main/System/Main/RightFuncInHome.cs
@@ -92,7 +92,7 @@
        });
        reviewBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<GoodReviewWin>();
            UIManager.Instance.OpenWindowAsync<GoodReviewWin>().Forget();
        });
    }
    
Main/System/MainLevel/MainBossEnterWin.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -34,7 +35,7 @@
        rankBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<PlayerRankWin>(0);
            UIManager.Instance.OpenWindowAsync<PlayerRankWin>(0).Forget();
        });
@@ -42,7 +43,7 @@
        heroRoadBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<DayMissionBaseWin>(2);
            UIManager.Instance.OpenWindowAsync<DayMissionBaseWin>(2).Forget();
        });
        funPresetBtn.AddListener(()=>
@@ -103,7 +104,7 @@
                    SmallTipWin.showText = Language.Get("SmallTipFomat",SkillConfig.Get(skillID)?.SkillName, SkillConfig.Get(skillID)?.Description) ;
                    SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
                    SmallTipWin.isDownShow = true;
                    UIManager.Instance.OpenWindow<SmallTipWin>();
                    UIManager.Instance.OpenWindowAsync<SmallTipWin>().Forget();
                });
            }
            else
@@ -112,7 +113,7 @@
            }
        }
        bossModel.Create(npcConfig.SkinID, npcConfig.ModelScale);
        bossModel.Create(npcConfig.SkinID, npcConfig.ModelScale).Forget();
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(levelConfig.FightPower);
Main/System/OSActivity/OSActivityBaseWin.cs
@@ -1,5 +1,6 @@
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
public abstract class OSActivityBaseWin : FunctionsBaseWin
{
@@ -18,23 +19,23 @@
    protected abstract int GetRankType();
    
    // 由子类实现:实例化对应的三个子窗口
    protected abstract UIBase GetRankWin();
    protected abstract UIBase GetAwardWin();
    protected abstract UIBase GetGiftWin();
    protected abstract UniTask<UIBase> GetRankWin();
    protected abstract UniTask<UIBase> GetAwardWin();
    protected abstract UniTask<UIBase> GetGiftWin();
    protected override void OpenSubUIByTabIndex()
    protected override async void OpenSubUIByTabIndex()
    {
        switch (functionOrder)
        {
            case 0:
                currentSubUI = GetRankWin();
                currentSubUI = await GetRankWin();
                break;
            case 1:
                currentSubUI = GetAwardWin();
                currentSubUI = await GetAwardWin();
                break;
            case 2:
                // 如果后续有活动没有礼包页签,只需在子类里返回 null 或不调用即可
                currentSubUI = GetGiftWin();
                currentSubUI = await GetGiftWin();
                break;
        }
    }
Main/System/OSActivity/OSBeautyMMBaseWin.cs
@@ -1,5 +1,6 @@
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
// 开服活动-红颜冲刺活动
public class OSBeautyMMBaseWin : OSActivityBaseWin
@@ -7,9 +8,9 @@
    // 红颜冲榜对应的 RankType 为 8
    protected override int GetRankType() => 8;
    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMWin>(8);
    protected override async UniTask<UIBase> GetRankWin() => await UIManager.Instance.OpenWindowAsync<OSRankBeautyMMWin>(8);
    
    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMAwardWin>();
    protected override async UniTask<UIBase> GetAwardWin() => await UIManager.Instance.OpenWindowAsync<OSRankBeautyMMAwardWin>();
    
    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMGiftWin>();
    protected override async UniTask<UIBase> GetGiftWin() => await UIManager.Instance.OpenWindowAsync<OSRankBeautyMMGiftWin>();
}
Main/System/OSActivity/OSGalaGiftCell.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -78,13 +79,13 @@
                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
Main/System/OSActivity/OSHeroCallBaseWin.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
////开服活动-武将招募活动
@@ -21,18 +22,18 @@
    }
    
    protected override void OpenSubUIByTabIndex()
    protected override async void OpenSubUIByTabIndex()
    {
        switch (functionOrder)
        {
            case 0:
                currentSubUI = UIManager.Instance.OpenWindow<OSRankWin>(4);
                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankWin>(4);
                break;
            case 1:
                currentSubUI = UIManager.Instance.OpenWindow<OSRankHeroCallAwardWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankHeroCallAwardWin>();
                break;
            case 2:
                currentSubUI = UIManager.Instance.OpenWindow<OSRankHeroCallGiftWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankHeroCallGiftWin>();
                break;
        }
    }
Main/System/OSActivity/OSHeroTrainBaseWin.cs
@@ -1,14 +1,15 @@
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
// 开服活动-武将冲榜主界面
public class OSHeroTrainBaseWin : OSActivityBaseWin
{
    protected override int GetRankType() => 7;
    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainWin>(7);
    protected override async UniTask<UIBase> GetRankWin() => await UIManager.Instance.OpenWindowAsync<OSRankHeroTrainWin>(7);
    
    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainAwardWin>();
    protected override async UniTask<UIBase> GetAwardWin() => await UIManager.Instance.OpenWindowAsync<OSRankHeroTrainAwardWin>();
    
    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainGiftWin>();
    protected override async UniTask<UIBase> GetGiftWin() => await UIManager.Instance.OpenWindowAsync<OSRankHeroTrainGiftWin>();
}
Main/System/OSActivity/OSMainLevelBaseWin.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
////开服活动-主线关卡活动
@@ -30,15 +31,15 @@
        }
    }
    protected override void OpenSubUIByTabIndex()
    protected override async void OpenSubUIByTabIndex()
    {
        switch (functionOrder)
        {
            case 0:
                currentSubUI = UIManager.Instance.OpenWindow<OSRankWin>(3);
                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankWin>(3);
                break;
            case 1:
                currentSubUI = UIManager.Instance.OpenWindow<OSRankMainLeveAwardWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankMainLeveAwardWin>();
                break;
        }
    }
Main/System/OSActivity/OSMinggeBaseWin.cs
@@ -1,14 +1,15 @@
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
// 开服活动-命格冲榜主界面
public class OSMinggeBaseWin : OSActivityBaseWin
{
    protected override int GetRankType() => 9;
    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankMinggeWin>(9);
    protected override async UniTask<UIBase> GetRankWin() => await UIManager.Instance.OpenWindowAsync<OSRankMinggeWin>(9);
    
    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankMinggeAwardWin>();
    protected override async UniTask<UIBase> GetAwardWin() => await UIManager.Instance.OpenWindowAsync<OSRankMinggeAwardWin>();
    
    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankMinggeGiftWin>();
    protected override async UniTask<UIBase> GetGiftWin() => await UIManager.Instance.OpenWindowAsync<OSRankMinggeGiftWin>();
}
Main/System/OSActivity/OSRankGiftBaseCell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -83,13 +84,13 @@
                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
Main/System/OSActivity/OSRankHeroCallGiftCell.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -78,13 +79,13 @@
                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
                    {
                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                        UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                        return;
                    }
Main/System/OSActivity/OSRankHeroTrainWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
// 开服活动-武将冲榜 排行榜界面
@@ -14,7 +15,7 @@
            OSRankTipWin.infoTextKey = "OSActivityHeroTrainRankTip";
            OSRankTipWin.isDownShow = true;
            OSRankTipWin.worldPos = title.transform.position;
            UIManager.Instance.OpenWindow<OSRankTipWin>();
            UIManager.Instance.OpenWindowAsync<OSRankTipWin>().Forget();
        });
    }
}
Main/System/OSActivity/OSRankMinggeWin.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
// 开服活动-命格冲榜 排行榜界面
@@ -14,7 +15,7 @@
            OSRankTipWin.infoTextKey = "OSActivityMinggeRankTip";
            OSRankTipWin.isDownShow = true;
            OSRankTipWin.worldPos = title.transform.position;
            UIManager.Instance.OpenWindow<OSRankTipWin>();
            UIManager.Instance.OpenWindowAsync<OSRankTipWin>().Forget();
        });
    }
}
Main/System/OfficialRank/OfficialTitleCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -9,7 +10,7 @@
    private void Awake()
    {
        //如果有需要按钮点击逻辑,在外层创建,此处不处理点击逻辑
        LoadPrefab();
        LoadPrefab().Forget();
    }
@@ -86,27 +87,34 @@
    GameObject prefab;
    protected void LoadPrefab()
    protected async UniTask<GameObject> LoadPrefab()
    {
        if (prefab != null)
            return;
            return prefab;
        var tmp = transform.Find("OfficialTitleCell");
        if (tmp != null)
        {
            prefab = tmp.gameObject;
            return;
            return prefab;
        }
        prefab = UIUtility.CreateWidget("OfficialTitleCell", "OfficialTitleCell");
        prefab = await UIUtility.CreateWidget("OfficialTitleCell", "OfficialTitleCell");
        if (this == null)
        {
            GameObject.DestroyImmediate(prefab);
            return null;
        }
        prefab.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
        prefab.transform.SetAsFirstSibling();
        return prefab;
    }
    public void InitUI(int offcialRank, int titleID, float scale = 0.6f)
    public async UniTask InitUI(int offcialRank, int titleID, float scale = 0.6f)
    {
        LoadPrefab();   //存在被卸载的可能,重新加载
        await LoadPrefab();   //存在被卸载的可能,重新加载
        if (this == null) return;
        if (!TitleConfig.HasKey(titleID))
        {
            officialRankObj.SetActive(true);
Main/System/OtherPlayerDetail/BuffInfoWin.cs
@@ -1,4 +1,5 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class BuffInfoWin : UIBase
@@ -24,16 +25,7 @@
        if (heroSkinConfig == null) return;
        teamImage.SetSprite(data.isMySide ? "OtherHeroDetailBGBlue" : "OtherHeroDetailBGRed");
         var sprite = UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(data.skinID).SquareIcon);
        if (sprite == null)
        {
            // 内网未配置时
            heroImage.SetSprite("herohead_default");
        }
        else
        {
            heroImage.overrideSprite = sprite;
        }
        UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(data.skinID).SquareIcon, heroImage, "herohead_default").Forget();
        heroNameText.text = heroConfig.Name;
        CreateScroller();
Main/System/OtherPlayerDetail/OtherNpcHeroCell.cs
@@ -131,7 +131,7 @@
        if (this == null) return;
        var heroConfig = HeroConfig.Get(heroID);
        heroModel.Create(skinID, 1.2f);
        heroModel.Create(skinID, 1.2f).Forget();
        if (star == 0)
        {
Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs
@@ -159,7 +159,7 @@
        txtServerName.text = Language.Get("PlayerProfile11", ServerListCenter.Instance.GetServerName(viewPlayerData.ServerID));
        txtLV.text = viewPlayerData.LV.ToString();
        avatarCell.InitUI(AvatarHelper.GetAvatarModel(viewPlayerData.PlayerID, viewPlayerData.Face, viewPlayerData.FacePic));
        officialTitle.InitUI(viewPlayerData.RealmLV, viewPlayerData.TitleID, 0.65f);
        officialTitle.InitUI(viewPlayerData.RealmLV, viewPlayerData.TitleID, 0.65f).Forget();
        DisplayHorseModel(viewPlayerData);
    }
Main/System/PhantasmPavilion/AvatarCell.cs
@@ -237,7 +237,9 @@
        int faceID = model.faceID;
        int facePicID = model.facePicID;
        manager.ShowFace(faceImage, faceSpine, faceUIFrame, faceMask, faceID).Forget();
        await manager.ShowFace(faceImage, faceSpine, faceUIFrame, faceMask, faceID);
        if (this == null) return;
        string str = AvatarHelper.GetAvatarBgColorStr(faceID);
        faceBGImage.SetSprite(str);
@@ -246,9 +248,6 @@
        string resourceValue = manager.GetResourceValue(PhantasmPavilionType.FacePic, facePicID);
        manager.Show(PhantasmPavilionType.FacePic, facePicImage, facePicSpine, facePicUIFrame, resourceType, resourceValue);
        faceBGImage.SetNativeSize();
        faceImage.SetNativeSize();
        facePicImage.SetNativeSize();
        BindButtonClick(model);
    }
    // 添加标志位:是否已设置自定义监听器
Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
@@ -234,17 +234,17 @@
            var sprite = await UILoader.LoadSpriteAsync("HeroHead", skinConfig.SquareIcon);
            if (sprite == null)
            {
                Show(imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask);
                Show(type, imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask);
            }
            else
            {
                Show(imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask);
                Show(type, imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask);
            }
        }
        else
        {
            resourceValue = GetResourceValue(type, id);
            Show(imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask);
            Show(type, imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask);
        }
    }
Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class PhantasmPavilionModelWin : UIBase
@@ -201,8 +202,8 @@
        ModelConfig model = ModelConfig.Get(id);
        int skinID = model.SkinID;
        lhframe.transform.localScale = new Vector3(lhSize, lhSize, lhSize);
        heroIh.Create(skinID, motionName: "", isLh: true);
        heroModel.Create(skinID, modelSize);
        heroIh.Create(skinID, motionName: "", isLh: true).Forget();
        heroModel.Create(skinID, modelSize).Forget();
        PhantasmPavilionState state = manager.GetUnLockState(type, id);
Main/System/PlayerProfile/PlayerProfileWin.cs
@@ -65,7 +65,7 @@
        });
        btnLanguage.AddListener(()=>
        {
            UIManager.Instance.OpenWindow<ChangeLanguageWin>();
            UIManager.Instance.OpenWindowAsync<ChangeLanguageWin>().Forget();
        });
    }
@@ -90,8 +90,7 @@
    {
        if (type == PlayerDataType.ExAttr3)
        {
            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f);
        }
            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f).Forget();        }
    }
    private void OnUpdateRenameResultEvent()
@@ -114,7 +113,7 @@
        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
                                                    PlayerDatas.Instance.baseData.face,
                                                    PlayerDatas.Instance.baseData.facePic));
        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f);
        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f).Forget();
        var languages = Language.GetLanguages();
        btnLanguage.SetActive(!languages.IsNullOrEmpty());
    }
Main/System/Qunying/QYBattleFailWin.cs
@@ -37,7 +37,7 @@
        tipHeroPosBtn.AddListener(() =>
        {
            CloseWindow();
            UIManager.Instance.OpenWindow<HeroPosWin>();
            UIManager.Instance.OpenWindowAsync<HeroPosWin>().Forget();
        });
    }
Main/System/Qunying/QYBattleWin.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using LitJson;
using UnityEngine;
using UnityEngine.UI;
@@ -79,7 +80,7 @@
        }
        else
        {
            UIManager.Instance.OpenWindow<MainWin>();
            UIManager.Instance.OpenWindowAsync<MainWin>().Forget();
        }
        if (isClickSkip)
Main/System/Qunying/QYFighterCell.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -149,15 +150,15 @@
            nameText.text = UIHelper.ServerStringTrim(PlayerDatas.Instance.baseData.PlayerName);
            var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetUsingHorseSkinID());
            model.Create(skinConfig.SkinID, PhantasmPavilionManager.Instance.GetMyModelSkinID(), 0.9f);
            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
            model.Create(skinConfig.SkinID, PhantasmPavilionManager.Instance.GetMyModelSkinID(), 0.9f).Forget();
            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
        }
        else
        {
            fightPowerText.text = UIHelper.ReplaceLargeArtNum(matchInfo.FightPower);
            nameText.text = UIHelper.ServerStringTrim(matchInfo.PlayerName);
            model.Create((int)matchInfo.EquipShowSwitch % 1000, heroSkinID, 0.9f);
            officialTitleCell.InitUI(matchInfo.RealmLV, (int)matchInfo.TitleID);
            model.Create((int)matchInfo.EquipShowSwitch % 1000, heroSkinID, 0.9f).Forget();
            officialTitleCell.InitUI(matchInfo.RealmLV, (int)matchInfo.TitleID).Forget();
        }
        
Main/System/Qunying/QYPlayerTop3Cell.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -34,8 +35,8 @@
        }
            
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, 0.9f);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, 0.9f).Forget();
        queryPlayerBtn.SetListener(() =>
        {
            if (GeneralDefine.IsRobot((int)rankData.id)) return;
Main/System/Qunying/QYWin.cs
@@ -42,7 +42,7 @@
        });
        achievementBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<QYAchievementWin>();
            UIManager.Instance.OpenWindowAsync<QYAchievementWin>().Forget();
        });
        defentPosBtn.AddListener(() =>
        {
@@ -59,19 +59,19 @@
        storeBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<QYStoreWin>();
            UIManager.Instance.OpenWindowAsync<QYStoreWin>().Forget();
        });
        rankBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<PlayerRankWin>(QunyingManager.rankType);
            UIManager.Instance.OpenWindowAsync<PlayerRankWin>(QunyingManager.rankType).Forget();
        });
        awardBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<QYRankAwardWin>(1);
            UIManager.Instance.OpenWindowAsync<QYRankAwardWin>(1).Forget();
        });
        noteBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<QYNoteWin>();
            UIManager.Instance.OpenWindowAsync<QYNoteWin>().Forget();
        });
    }
Main/System/Qunying/QunyingManager.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using LitJson;
using System;
@@ -253,7 +254,7 @@
                itemInfos.Add(itemInfo);
            }
        }
        UIManager.Instance.OpenWindow<QYBattleVictoryWin>();
        UIManager.Instance.OpenWindowAsync<QYBattleVictoryWin>().Forget();
    }
    //是否本周开启,周几开启
Main/System/Settlement/BattleSettlementManager.cs
@@ -110,11 +110,11 @@
            case BattleConst.QYBattleField:
                if (isWin)
                {
                    UIManager.Instance.OpenWindow<QYBattleVictoryWin>();
                    UIManager.Instance.OpenWindowAsync<QYBattleVictoryWin>().Forget();
                }
                else
                {
                    UIManager.Instance.OpenWindow<QYBattleFailWin>();
                    UIManager.Instance.OpenWindowAsync<QYBattleFailWin>().Forget();
                }
                break;
            default:
Main/System/SpineUpdateManager.cs
New file
@@ -0,0 +1,109 @@
using System.Collections.Generic;
using Spine.Unity;
using UnityEngine;
/// <summary>
/// Spine批量更新管理器(参考UWA优化方案)
/// 禁用SkeletonGraphic的Update/LateUpdate自动回调,
/// 由Manager统一批量调用,减少大量Spine对象的跨语言调用开销。
/// 支持隔帧更新Mesh,进一步降低CPU开销。
/// </summary>
public class SpineUpdateManager : MonoBehaviour
{
    private static SpineUpdateManager instance;
    public static SpineUpdateManager Instance
    {
        get
        {
            if (instance == null)
            {
                var go = new GameObject("[SpineUpdateManager]");
                DontDestroyOnLoad(go);
                instance = go.AddComponent<SpineUpdateManager>();
            }
            return instance;
        }
    }
    private readonly List<SkeletonGraphic> managedSpines = new List<SkeletonGraphic>();
    private readonly HashSet<SkeletonGraphic> managedSet = new HashSet<SkeletonGraphic>();
    private int frameCount;
    /// <summary>
    /// 注册一个SkeletonGraphic到批量更新管理器。
    /// 注册后会禁用其自身的Update/LateUpdate(通过设置freeze=true),
    /// 改由Manager统一驱动。
    /// </summary>
    public void Register(SkeletonGraphic sg)
    {
        if (sg == null || managedSet.Contains(sg)) return;
        managedSpines.Add(sg);
        managedSet.Add(sg);
        sg.freeze = true; // 禁用SkeletonGraphic自身的Update/LateUpdate
    }
    /// <summary>
    /// 从管理器中移除一个SkeletonGraphic,恢复其自身更新。
    /// </summary>
    public void Unregister(SkeletonGraphic sg)
    {
        if (sg == null || !managedSet.Contains(sg)) return;
        managedSpines.Remove(sg);
        managedSet.Remove(sg);
        sg.freeze = false; // 恢复自身更新
    }
    void Update()
    {
        frameCount++;
        float dt = Time.deltaTime;
        for (int i = managedSpines.Count - 1; i >= 0; i--)
        {
            var sg = managedSpines[i];
            if (sg == null)
            {
                managedSpines.RemoveAt(i);
                managedSet.Remove(sg);
                continue;
            }
            if (!sg.isActiveAndEnabled) continue;
            // 手动驱动动画更新:Update(float)不检查freeze,直接更新动画状态
            sg.Update(dt);
        }
    }
    void LateUpdate()
    {
        // 隔帧更新Mesh:动画状态每帧更新保证事件准确,但Mesh重建(开销大)隔帧即可
        // 数量少时每帧都更新,数量多于8个时隔帧更新以减少CPU负担
        bool skipMesh = managedSpines.Count > 8 && (frameCount & 1) == 0;
        for (int i = managedSpines.Count - 1; i >= 0; i--)
        {
            var sg = managedSpines[i];
            if (sg == null)
            {
                managedSpines.RemoveAt(i);
                managedSet.Remove(sg);
                continue;
            }
            if (!sg.isActiveAndEnabled) continue;
            if (skipMesh) continue;
            // 手动驱动Mesh更新:直接调用UpdateMesh(),不经过LateUpdate()的freeze检查
            sg.UpdateMesh();
        }
    }
    void OnDestroy()
    {
        // 恢复所有被管理的Spine自身更新
        foreach (var sg in managedSpines)
        {
            if (sg != null)
                sg.freeze = false;
        }
        managedSpines.Clear();
        managedSet.Clear();
        instance = null;
    }
}
Main/System/SpineUpdateManager.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 174da832a7db0f74d9e049555d1edbe5
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Store/SkinStoreCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -60,13 +61,13 @@
        {
            HeroUIManager.Instance.selectForPreviewHeroID = heroID;
            HeroUIManager.Instance.selectSkinIndex = HeroDebutManager.Instance.GetSkinIndexInHeroConfig(heroID, skinID);
            UIManager.Instance.OpenWindow<HeroBestBaseWin>(1);
            UIManager.Instance.OpenWindowAsync<HeroBestBaseWin>(1).Forget();
        });
    }
    void BuyGoods(int shopID)
    {
        StoreModel.Instance.buyShopID = shopID;
        UIManager.Instance.OpenWindow<SkinStoreBuyTipWin>();
        UIManager.Instance.OpenWindowAsync<SkinStoreBuyTipWin>().Forget();
    }
}
Main/System/Store/SkinStoreWin.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -14,7 +15,7 @@
    {
        giftBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroSkinGiftWin>();
            UIManager.Instance.OpenWindowAsync<HeroSkinGiftWin>().Forget();
        });
    }
Main/System/Store/StoreBaseWin.cs
@@ -16,7 +16,7 @@
                break;
            case 1:
                //时装
                currentSubUI = UIManager.Instance.OpenWindow<SkinStoreWin>();
                currentSubUI = await UIManager.Instance.OpenWindowAsync<SkinStoreWin>();
                break;
            case 2:
                // 充值界面
Main/System/Store/StoreModel.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using LitJson;
using System.Collections;
@@ -591,7 +591,7 @@
        if (!TryGetIsSellOut(cfg, out var cnt))
        {
            buyShopID = shopID;
            UIManager.Instance.OpenWindow<BuyItemWin>();
            UIManager.Instance.OpenWindowAsync<BuyItemWin>().Forget();
        }
        else
        {
Main/System/TianziBillborad/TianziBillboradPlayerRankCell.cs
@@ -2,6 +2,7 @@
//    [Author]:           玩个游戏
//    [  Date ]:           Wednesday, September 26, 2018
//--------------------------------------------------------
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -37,7 +38,7 @@
                rankText.text = Language.Get("L1045");
                rankValueText.text = "0";//Language.Get("L1125");
                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                return;
            }
            rank = rankData.rank;
@@ -52,7 +53,7 @@
        else
        {
            officialTitleCell.SetActive(true);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
            avatarCell.SetActive(true);
            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
            viewPlayerId = (int)rankData.id;
Main/System/TianziBillborad/TianziBillboradPlayerTop3Cell.cs
@@ -30,7 +30,7 @@
        officialTitleCell.SetActive(true);
        rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue2 + rankData.cmpValue * Constants.ExpPointValue));
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.SetActive(true);
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f).Forget();
        queryPlayerBtn.SetListener(() =>
Main/System/TianziBillborad/TianziBillboradWin.cs
@@ -194,7 +194,7 @@
    {
        txtBossName.text = npcConfig.NPCName;
        uiEffectPlayer.Play();
        bossModel.Create(npcConfig.SkinID, modelSize);
        bossModel.Create(npcConfig.SkinID, modelSize).Forget();
        txtHistoryHurt.text = Language.Get("TianziBillborad01", UIHelper.ReplaceLargeNum(model.historyHurt));
        txtTodayHurt.text = Language.Get("TianziBillborad02", UIHelper.ReplaceLargeNum(model.todayHurt));
    }
Main/System/TimeRush/TimeRushGiftCell.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class TimeRushGiftCell : MonoBehaviour
@@ -81,13 +82,13 @@
            if (config.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
            {
                SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                return;
            }
            if (config.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
            {
                SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
                UIManager.Instance.OpenWindowAsync<PrivilegeCardWin>().Forget();
                return;
            }
Main/System/UIBase/UIBase.cs
@@ -334,7 +334,7 @@
            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
        }
        ApplyClickEmptySpaceClose();
        ApplyClickEmptySpaceClose().Forget();
        ExecuteNextFrame(() =>
        {
Main/System/UIBase/UIJumpManager.cs
@@ -94,7 +94,7 @@
            if (UIManager.Instance.IsOpened(config.WinName))
            {
                UIManager.Instance.CloseWindow(config.WinName);
                UIManager.Instance.OpenWindow(config.WinName);
                UIManager.Instance.OpenWindowAsync(config.WinName).Forget();
            }
        }
Main/System/Video/UIVideoPlayer.cs
@@ -63,6 +63,7 @@
        // 通过 ResManager 加载 VideoClip 资源(支持 AB 打包)
        _loadedClip = await ResManager.Instance.LoadAssetAsync<VideoClip>(directory, videoName, false);
        if (this == null) return;
        
        // 检查是否在加载过程中被取消
        if (!_isLoading)
@@ -173,6 +174,7 @@
        // 通过 ResManager 加载 VideoClip 资源(支持 AB 打包)
        _loadedClip = await ResManager.Instance.LoadAssetAsync<VideoClip>(directory, videoName, false);
        if (this == null) return;
        
        // 检查是否在加载过程中被取消
        if (!_isLoading)
Main/System/ViewNPC/ViewBuffManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using LitJson;
@@ -21,7 +22,7 @@
        currentBuffData = data;
        if (!UIManager.Instance.IsOpened<BuffInfoWin>())
        {
            UIManager.Instance.OpenWindow<BuffInfoWin>();
            UIManager.Instance.OpenWindowAsync<BuffInfoWin>().Forget();
        }
    }
}
Main/System/WarlordPavilion/WarlordPavilionNPCItem.cs
@@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
public class WarlordPavilionNPCItem : MonoBehaviour
@@ -26,7 +27,7 @@
            return;
        HeroConfig heroConfig = HeroConfig.Get(heroID);
        uiHeroController.Create(npcConfig.SkinID, modelSize);
        uiHeroController.Create(npcConfig.SkinID, modelSize).Forget();
        Color color = UIHelper.GetUIColorByFunc(heroConfig.Quality);
        string name = UIHelper.AppendColor(color, heroConfig.Name);
Main/System/WarlordPavilion/WarlordPavilionPlayerRankCell.cs
@@ -1,4 +1,5 @@
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
public class WarlordPavilionPlayerRankCell : MonoBehaviour
@@ -32,7 +33,7 @@
                rankText.text = Language.Get("L1045");
                rankValueText.text = "";//Language.Get("L1125");
                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID).Forget();
                return;
            }
            rank = rankData.rank;
@@ -47,7 +48,7 @@
        else
        {
            officialTitleCell.SetActive(true);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
            avatarCell.SetActive(true);
            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
            viewPlayerId = (int)rankData.id;
Main/System/WarlordPavilion/WarlordPavilionPlayerTop3Cell.cs
@@ -30,7 +30,7 @@
        manager.AnalysisFinishProgress((int)rankData.cmpValue, out int layerNum, out int levelNum);
        rankValueText.text = Language.Get("WarlordPavilion23", layerNum, levelNum);
        nameText.text = rankData.name1;
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2).Forget();
        model.SetActive(true);
        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f).Forget();
        queryPlayerBtn.SetListener(() =>
Main/Utility/ComponentExtersion.cs
@@ -539,11 +539,17 @@
            return;
        }
        _image.enabled = false;
        UILoader.LoadTexture2DPNGAsync(_id).ContinueWith(texture =>
        {
            if (_image != null && texture != null)
            if (_image == null) return;
            if (texture != null)
            {
                _image.texture = texture;
                _image.SetNativeSize();
                _image.enabled = true;
            }
        }).Forget();
    }
Main/Utility/DeviceUtility.cs
@@ -1,13 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.NetworkInformation;
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text.RegularExpressions;
using Cysharp.Threading.Tasks;
using UnityEngine.Networking;
#if !UNITY_WEBGL
using System.Net.NetworkInformation;
using System.Net;
using System.IO;
#endif
#if UNITY_IOS
using UnityEngine.iOS;
@@ -20,6 +23,7 @@
    static string mac = string.Empty;
    public static string GetMac()
    {
#if !UNITY_WEBGL
        if (string.IsNullOrEmpty(mac))
        {
            try
@@ -35,12 +39,13 @@
                Debug.Log(ex);
            }
        }
#endif
        return mac;
    }
    static string ipPattern = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";
    static string ip = string.Empty;
    public static string GetCachedIp() => ip;
    public static async UniTask<string> GetIp()
    {
        try
@@ -48,24 +53,20 @@
            if (string.IsNullOrEmpty(ip))
            {
                string url = "http://pv.sohu.com/cityjson";
                WebRequest wRequest = WebRequest.Create(url);
                wRequest.Method = "GET";
                wRequest.ContentType = "text/html;charset=UTF-8";
                WebResponse wResponse = await wRequest.GetResponseAsync();
                Stream stream = wResponse.GetResponseStream();
                StreamReader reader = new StreamReader(stream, System.Text.Encoding.Default);
                string str = await reader.ReadToEndAsync();
                reader.Close();
                wResponse.Close();
                var match = Regex.Match(str, ipPattern);
                if (match != null)
                using (var request = UnityWebRequest.Get(url))
                {
                    ip = match.Value;
                    await request.SendWebRequest();
                    if (request.result == UnityWebRequest.Result.Success)
                    {
                        string str = request.downloadHandler.text;
                        var match = Regex.Match(str, ipPattern);
                        if (match != null)
                        {
                            ip = match.Value;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
Main/Utility/OperationLogCollect.cs
@@ -8,7 +8,7 @@
public class OperationLogCollect : Singleton<OperationLogCollect>
{
    const string bugReportUrl = "http://xssgcenter.secondworld.net.cn:11000/center/eventreport.php?";
    const string bugReportUrl = "http://gamecenter.secondworld.net.cn:11000/center/eventreport.php?";
    public void BugReport(string _title, string _content)
    {
@@ -19,7 +19,7 @@
        tables["EventID"] = 9002.ToString();
        tables["ProductID"] = VersionConfig.Get().gameId;
        tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        tables["IP"] = DeviceUtility.GetIp();
        tables["IP"] = DeviceUtility.GetCachedIp();
        tables["AccountID"] = LoginManager.Instance.sdkLoginResult.account;
        tables["Level"] = PlayerDatas.Instance.baseData.LV.ToString();
        tables["RoleID"] = PlayerDatas.Instance.baseData.PlayerName;
@@ -54,7 +54,7 @@
            tables["EventID"] = 9002.ToString();
            tables["ProductID"] = VersionConfig.Get().gameId;
            tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            tables["IP"] = DeviceUtility.GetIp();
            tables["IP"] = DeviceUtility.GetCachedIp();
            tables["AccountID"] = "system";
            tables["Level"] = "1";
            tables["RoleID"] = "system";
@@ -88,7 +88,7 @@
    }
    const string chatReportUrl = "http://xssgcenter.secondworld.net.cn:11000/center/eventreport.php?";
    const string chatReportUrl = "http://gamecenter.secondworld.net.cn:11000/center/eventreport.php?";
    public void ChatReport(string content, string channelName, string toPlayer, int chatType)
    {
#if !UNITY_EDITOR
@@ -101,7 +101,7 @@
        tables["RegionID"] = ServerListCenter.Instance.currentServer.region_flag.ToString();
        tables["EventID"] = 9003.ToString();
        tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        tables["IP"] = DeviceUtility.GetIp();
        tables["IP"] = DeviceUtility.GetCachedIp();
        tables["ChatChannel"] = channelName;
        var sdkLoginResult = LoginManager.Instance.sdkLoginResult;
        tables["AccountID"] = sdkLoginResult == null ? LoginManager.Instance.accountBuf : sdkLoginResult.account;
Main/Utility/RunTimeExceptionUtility.cs
@@ -24,7 +24,11 @@
            return;
        }
        if (Application.platform == RuntimePlatform.Android)
        if (Application.platform == RuntimePlatform.WebGLPlayer)
        {
            return; // WebGL不支持文件系统写入
        }
        else if (Application.platform == RuntimePlatform.Android)
        {
            logFileRoot = Path.GetDirectoryName(Application.persistentDataPath);
        }
Main/Utility/SystemCMD.cs
@@ -11,6 +11,10 @@
    /// <returns></returns>
    public static string RunCmd(string command)
    {
#if UNITY_WEBGL
        UnityEngine.Debug.LogWarning("SystemCMD.RunCmd is not supported on WebGL");
        return string.Empty;
#else
        System.Diagnostics.Process p = new System.Diagnostics.Process();
        p.StartInfo.FileName = "cmd.exe";           //确定程序名
        p.StartInfo.Arguments = "/c " + command;    //确定程式命令行
@@ -31,6 +35,7 @@
        {
            return err;        //输出出流取得命令行结果果
        }
#endif
    }
}
Main/Utility/UIHelper.cs
@@ -1533,7 +1533,12 @@
    //获取剪切板内容
    public static string GetClipboardText()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        // WebGL下浏览器安全限制,无法同步读取剪贴板
        return string.Empty;
#else
        return GUIUtility.systemCopyBuffer;
#endif
    }
    /// <summary>
Main/Utility/WebGLDebug.cs
New file
@@ -0,0 +1,18 @@
using UnityEngine;
/// <summary>
/// WebGL 环境下直接调用浏览器 console.error,不受 Unity Release Build 日志抑制影响。
/// 非 WebGL 平台回退到 Debug.LogError。
/// </summary>
public static class WebGLDebug
{
    public static void LogError(string msg)
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        string escaped = msg.Replace("\\", "\\\\").Replace("'", "\\'").Replace("\n", "\\n").Replace("\r", "");
        Application.ExternalEval("console.error('" + escaped + "')");
#else
        Debug.LogError(msg);
#endif
    }
}
Main/Utility/WebGLDebug.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 242dde706571701498a0d9f6d02937a5
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant: