From 3f2cd27c5dfb3b450245bf1a37fc1b3414031c7c Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 11 二月 2026 11:03:58 +0800
Subject: [PATCH] 小游戏适配 资源系统改造

---
 Main/Manager/UIManager.cs |  243 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 243 insertions(+), 0 deletions(-)

diff --git a/Main/Manager/UIManager.cs b/Main/Manager/UIManager.cs
index 2343c08..b574a97 100644
--- a/Main/Manager/UIManager.cs
+++ b/Main/Manager/UIManager.cs
@@ -4,6 +4,7 @@
 using UnityEngine;
 using System.Linq;
 using DG.Tweening;
+using Cysharp.Threading.Tasks;
 
 /// <summary>
 /// UI绠$悊鍣� - 璐熻矗绠$悊鎵�鏈塙I鐣岄潰鐨勬樉绀恒�侀殣钘忓拰灞傜骇
@@ -562,7 +563,9 @@
         }
         else
         {
+            #pragma warning disable CS0618 // Obsolete 鈥� sync legacy fallback, use LoadUIResourceAsync
             prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
+            #pragma warning restore CS0618
         }
 
         // 妫�鏌ラ鍒朵綋鏄惁鍔犺浇鎴愬姛
@@ -617,6 +620,246 @@
     {
         return LoadUIResource(uiName) as T;
     }
+
+    // ====================================================================
+    // US2: Async variants 鈥� InitUIRootAsync, LoadUIResourceAsync, OpenWindowAsync
+    // ====================================================================
+
+    /// <summary>
+    /// US2: 寮傛鍒濆鍖� UI 鏍硅妭鐐广��
+    /// </summary>
+    public async UniTask InitUIRootAsync()
+    {
+        GameObject root = GameObject.Find("UIRoot");
+        if (root == null)
+        {
+            var prefab = await BuiltInLoader.LoadPrefabAsync("UIRoot");
+            root = GameObject.Instantiate(prefab);
+            root.name = "UIRoot";
+            if (root == null)
+            {
+                Debug.LogError("鏃犳硶鍔犺浇UI鏍硅妭鐐�");
+                return;
+            }
+            GameObject.DontDestroyOnLoad(root);
+        }
+    }
+
+    /// <summary>
+    /// US2: 寮傛鍔犺浇 UI 璧勬簮銆�
+    /// </summary>
+    private async UniTask<UIBase> LoadUIResourceAsync(string uiName)
+    {
+        GameObject prefab;
+        if (uiName == "LaunchWin" || uiName == "DownLoadWin" || uiName == "RequestSecretWin" || uiName == "GameAgeWarnWin")
+        {
+            prefab = await BuiltInLoader.LoadPrefabAsync(uiName);
+        }
+        else
+        {
+            prefab = await ResManager.Instance.LoadAssetAsync<GameObject>("UI", uiName);
+        }
+
+        if (prefab == null)
+        {
+            Debug.LogError($"鍔犺浇UI棰勫埗浣撳け璐�: {uiName}");
+            return null;
+        }
+
+        GameObject uiObject = GameObject.Instantiate(prefab);
+        uiObject.name = uiName;
+
+        Type uiType = Type.GetType(uiName);
+        if (uiType == null)
+        {
+            Debug.LogError($"鎵句笉鍒癠I绫诲瀷: {uiName}");
+            return null;
+        }
+
+        UIBase uiBase = uiObject.GetComponent(uiType) as UIBase;
+        if (uiBase == null)
+        {
+            Debug.LogError($"UI棰勫埗浣� {uiName} 娌℃湁 UIBase 缁勪欢鎴栫被鍨嬩笉鍖归厤");
+            return null;
+        }
+
+        uiBase.uiName = uiName;
+
+        Transform parentTrans = GetTransForLayer(uiBase.uiLayer);
+        uiObject.transform.SetParent(parentTrans, false);
+
+        int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
+        uiBase.SetSortingOrder(baseSortingOrder);
+
+        return uiBase;
+    }
+
+    /// <summary>
+    /// US2: 寮傛鎵撳紑绐楀彛銆�
+    /// </summary>
+    public async UniTask<UIBase> OpenWindowAsync(string uiName, int functionOrder = 0)
+    {
+        UIBase returnValue = null;
+        UIBase parentUI = null;
+
+        // Check closed cache
+        if (closedUIDict.TryGetValue(uiName, out var closedUIList) && closedUIList.Count > 0)
+        {
+            returnValue = closedUIList[0] as UIBase;
+            closedUIList.RemoveAt(0);
+            if (closedUIList.Count == 0)
+            {
+                closedUIDict.Remove(uiName);
+            }
+        }
+        else
+        {
+            // US3: Show loading indicator while loading UI prefab (auto-hide after load)
+            ShowLoadingIndicator();
+            try
+            {
+                returnValue = await LoadUIResourceAsync(uiName);
+            }
+            finally
+            {
+                HideLoadingIndicator();
+            }
+
+            if (returnValue == null)
+            {
+                Debug.LogError($"鎵撳紑UI澶辫触: {uiName}");
+                return null;
+            }
+        }
+
+        returnValue.gameObject.SetActive(true);
+
+        if (returnValue.supportParentChildRelation && uiStack.Count > 0 && !returnValue.isMainUI)
+        {
+            parentUI = GetLastSupportParentChildRelationUI();
+        }
+
+        if (parentUI != null)
+        {
+            returnValue.parentUI = parentUI;
+            if (parentUI.childrenUI == null)
+            {
+                parentUI.childrenUI = new List<UIBase>();
+            }
+            parentUI.childrenUI.Add(returnValue);
+        }
+
+        currentRound++;
+        returnValue.lastUsedRound = currentRound;
+        UpdateParentUIRounds(returnValue);
+
+        if (!uiDict.ContainsKey(uiName))
+        {
+            uiDict[uiName] = new List<UIBase>();
+        }
+        uiDict[uiName].Add(returnValue);
+
+        uiStack.Push(returnValue);
+        UpdateUISortingOrder();
+
+        returnValue.functionOrder = functionOrder;
+        returnValue.HandleOpen();
+        OnOpenWindow?.Invoke(returnValue);
+        CheckAndCloseIdleUI();
+
+        return returnValue;
+    }
+
+    /// <summary>
+    /// US2: 娉涘瀷 寮傛鎵撳紑绐楀彛銆�
+    /// </summary>
+    public async UniTask<T> OpenWindowAsync<T>(int functionOrder = 0) where T : UIBase
+    {
+        string uiName = typeof(T).Name;
+        var result = await OpenWindowAsync(uiName, functionOrder);
+        return result as T;
+    }
+
+    // ====================================================================
+    // US3: Loading indicator for async UI loading
+    // ====================================================================
+
+    private GameObject _loadingIndicatorGO;
+    private int _loadingRefCount;
+
+    /// <summary>
+    /// US3: 鏄剧ず鍔犺浇鎸囩ず鍣紙寮曠敤璁℃暟锛屾敮鎸侀噸鍏ワ級銆�
+    /// </summary>
+    public void ShowLoadingIndicator()
+    {
+        _loadingRefCount++;
+        if (_loadingRefCount == 1)
+        {
+            EnsureLoadingIndicator();
+            if (_loadingIndicatorGO != null)
+            {
+                _loadingIndicatorGO.SetActive(true);
+            }
+        }
+    }
+
+    /// <summary>
+    /// US3: 闅愯棌鍔犺浇鎸囩ず鍣ㄣ��
+    /// </summary>
+    public void HideLoadingIndicator()
+    {
+        _loadingRefCount = Mathf.Max(0, _loadingRefCount - 1);
+        if (_loadingRefCount == 0 && _loadingIndicatorGO != null)
+        {
+            _loadingIndicatorGO.SetActive(false);
+        }
+    }
+
+    private void EnsureLoadingIndicator()
+    {
+        if (_loadingIndicatorGO != null) return;
+
+        // 鍒涘缓绠�鏄撳姞杞芥寚绀哄櫒: 鍗婇�忔槑閬僵 + 鏃嬭浆鍥炬爣
+        var canvas = uiRoot != null ? uiRoot.GetComponentInChildren<Canvas>() : null;
+        if (canvas == null) return;
+
+        _loadingIndicatorGO = new GameObject("UILoadingIndicator");
+        _loadingIndicatorGO.transform.SetParent(canvas.transform, false);
+
+        // 鍏ㄥ睆鍗婇�忔槑閬僵
+        var maskRT = _loadingIndicatorGO.AddComponent<RectTransform>();
+        maskRT.anchorMin = Vector2.zero;
+        maskRT.anchorMax = Vector2.one;
+        maskRT.offsetMin = Vector2.zero;
+        maskRT.offsetMax = Vector2.zero;
+
+        var maskImage = _loadingIndicatorGO.AddComponent<UnityEngine.UI.Image>();
+        maskImage.color = new Color(0, 0, 0, 0.3f);
+        maskImage.raycastTarget = true; // 鎷︽埅鐐瑰嚮
+
+        // 鍔犺浇鎻愮ず鏂囧瓧
+        var textGO = new GameObject("LoadingText");
+        textGO.transform.SetParent(_loadingIndicatorGO.transform, false);
+        var textRT = textGO.AddComponent<RectTransform>();
+        textRT.anchorMin = new Vector2(0.5f, 0.5f);
+        textRT.anchorMax = new Vector2(0.5f, 0.5f);
+        textRT.sizeDelta = new Vector2(300, 60);
+
+        var text = textGO.AddComponent<UnityEngine.UI.Text>();
+        text.text = "Loading...";
+        text.alignment = TextAnchor.MiddleCenter;
+        text.fontSize = 28;
+        text.color = Color.white;
+        text.font = UnityEngine.Font.CreateDynamicFontFromOSFont("Arial", 28);
+
+        // 纭繚鍦ㄦ渶涓婂眰
+        var sortCanvas = _loadingIndicatorGO.AddComponent<Canvas>();
+        sortCanvas.overrideSorting = true;
+        sortCanvas.sortingOrder = 30000;
+        _loadingIndicatorGO.AddComponent<UnityEngine.UI.GraphicRaycaster>();
+
+        _loadingIndicatorGO.SetActive(false);
+    }
     
     #endregion
 

--
Gitblit v1.8.0