From ece5fc6192739ec18692cc9ef0000b09ba1bf154 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 04 六月 2025 15:08:57 +0800
Subject: [PATCH] 18 子 2D卡牌客户端搭建 / 2D卡牌客户端搭建 备注: 1.资源加载统一入口 2.创建组件层级改为UI

---
 Main/UI/UIManager.cs |  213 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 162 insertions(+), 51 deletions(-)

diff --git a/Main/UI/UIManager.cs b/Main/UI/UIManager.cs
index 5abeecc..7babf03 100644
--- a/Main/UI/UIManager.cs
+++ b/Main/UI/UIManager.cs
@@ -31,6 +31,9 @@
     // UI瀛楀吀锛屽瓨鍌ㄦ墍鏈夊凡鍔犺浇鐨刄I锛岄敭涓篣I鍚嶇О锛屽�间负UI瀹炰緥
     private Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>();
     
+    // 瀛樺偍鍏抽棴浣嗘湭閿�姣佺殑UI锛岄敭涓篣I鍚嶇О锛屽�间负UI瀹炰緥
+    private Dictionary<string, List<UIBase>> closedUIDict = new Dictionary<string, List<UIBase>>();
+
     // UI鏍堬紝鐢ㄤ簬绠$悊UI鐨勬樉绀洪『搴�
     private Stack<UIBase> uiStack = new Stack<UIBase>();
     
@@ -91,56 +94,33 @@
         // 濡傛灉鍦烘櫙涓病鏈塙I鏍硅妭鐐癸紝鍒欏垱寤轰竴涓�
         if (root == null)
         {
-            root = new GameObject("UIRoot");
-            
-            // 娣诲姞DontDestroyOnLoad缁勪欢锛岀‘淇漊I鏍硅妭鐐瑰湪鍦烘櫙鍒囨崲鏃朵笉琚攢姣�
-            GameObject.DontDestroyOnLoad(root);
-            
-            // 鍒涘缓鍚勫眰绾ц妭鐐�
-            GameObject staticNode = new GameObject("Static");
-            GameObject bottomNode = new GameObject("Bottom");
-            GameObject midNode = new GameObject("Mid");
-            GameObject topNode = new GameObject("Top");
-            GameObject systemNode = new GameObject("System");
-            
-            // 璁剧疆鐖惰妭鐐�
-            staticNode.transform.SetParent(root.transform, false);
-            bottomNode.transform.SetParent(root.transform, false);
-            midNode.transform.SetParent(root.transform, false);
-            topNode.transform.SetParent(root.transform, false);
-            systemNode.transform.SetParent(root.transform, false);
-            
+            root = GameObject.Instantiate(BuiltInLoader.LoadPrefab("UIRoot"));
+
             if (root == null)
             {
                 Debug.LogError("鏃犳硶鎵惧埌UI鏍硅妭鐐�");
                 return;
             }
+
+            // 娣诲姞DontDestroyOnLoad缁勪欢锛岀‘淇漊I鏍硅妭鐐瑰湪鍦烘櫙鍒囨崲鏃朵笉琚攢姣�
+            GameObject.DontDestroyOnLoad(root);
         }
 
         uiRoot = root.transform;
         uiRoot.position = Vector3.zero;
 
-        // 鍒濆鍖栧悇灞傜骇鐨凾ransform
         staticTrans = uiRoot.Find("Static");
         bottomTrans = uiRoot.Find("Bottom");
         midTrans = uiRoot.Find("Middle");
         topTrans = uiRoot.Find("Top");
         systemTrans = uiRoot.Find("System");
 
-        // // 娣诲姞鍩虹Canvas
-        // Canvas rootCanvas = root.AddComponent<Canvas>();
-        // rootCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
-        // rootCanvas.sortingOrder = 0;
-
-        // // 娣诲姞CanvasScaler
-        // UnityEngine.UI.CanvasScaler scaler = root.AddComponent<UnityEngine.UI.CanvasScaler>();
-        // scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
-        // scaler.referenceResolution = new Vector2(1920, 1080);
-        // scaler.screenMatchMode = UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
-        // scaler.matchWidthOrHeight = 1.0f;
-
-        // // 娣诲姞GraphicRaycaster
-        // root.AddComponent<UnityEngine.UI.GraphicRaycaster>();
+        layerTransformCache.Clear();
+        layerTransformCache.Add(UILayer.Static, staticTrans);
+        layerTransformCache.Add(UILayer.Bottom, bottomTrans);
+        layerTransformCache.Add(UILayer.Mid, midTrans);
+        layerTransformCache.Add(UILayer.Top, topTrans);
+        layerTransformCache.Add(UILayer.System, systemTrans);
     }
     
     #endregion
@@ -370,13 +350,13 @@
     public void CheckAndCloseIdleUI()
     {
         // 濡傛灉娌℃湁UI锛岀洿鎺ヨ繑鍥�
-        if (uiDict.Count == 0)
+        if (uiDict.Count == 0 && closedUIDict.Count == 0)
             return;
             
         // 鍒涘缓闇�瑕佸叧闂殑UI鍒楄〃
         List<UIBase> uiToClose = new List<UIBase>();
         
-        // 閬嶅巻鎵�鏈塙I
+        // 閬嶅巻鎵�鏈夋椿璺僓I
         foreach (var uiList in uiDict.Values)
         {
             foreach (var ui in uiList)
@@ -385,6 +365,9 @@
                 if (ui.isPersistent)
                     continue;
                     
+                if (ui.IsActive())
+                    continue;
+
                 // 璁$畻UI绌洪棽鐨勫洖鍚堟暟
                 int idleRounds = currentRound - ui.lastUsedRound;
                 
@@ -396,13 +379,53 @@
             }
         }
         
-        // 鍏抽棴鎵�鏈夐渶瑕佸叧闂殑UI
+        // 閬嶅巻鎵�鏈夊叧闂殑UI
+        List<string> emptyKeys = new List<string>();
+        foreach (var kvp in closedUIDict)
+        {
+            string uiName = kvp.Key;
+            List<UIBase> uiList = kvp.Value;
+            List<UIBase> uiToRemove = new List<UIBase>();
+            
+            foreach (var ui in uiList)
+            {
+                // 璁$畻UI绌洪棽鐨勫洖鍚堟暟
+                int idleRounds = currentRound - ui.lastUsedRound;
+                
+                // 濡傛灉绌洪棽鍥炲悎鏁拌秴杩囨渶澶х┖闂插洖鍚堟暟锛屾坊鍔犲埌鍏抽棴鍒楄〃
+                if (idleRounds > ui.maxIdleRounds)
+                {
+                    uiToClose.Add(ui);
+                    uiToRemove.Add(ui);
+                }
+            }
+            
+            // 浠庡叧闂垪琛ㄤ腑绉婚櫎闇�瑕侀攢姣佺殑UI
+            foreach (var ui in uiToRemove)
+            {
+                uiList.Remove(ui);
+            }
+            
+            // 濡傛灉鍒楄〃涓虹┖锛岃褰曢渶瑕佷粠瀛楀吀涓Щ闄ょ殑閿�
+            if (uiList.Count == 0)
+            {
+                emptyKeys.Add(uiName);
+            }
+        }
+        
+        // 浠庡瓧鍏镐腑绉婚櫎绌哄垪琛�
+        foreach (var key in emptyKeys)
+        {
+            closedUIDict.Remove(key);
+        }
+        
+        // 閿�姣佹墍鏈夐渶瑕佸叧闂殑UI
         foreach (var ui in uiToClose)
         {
             // 璁板綍鏃ュ織
-            Debug.Log($"鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I: {ui.uiName}, 绌洪棽鍥炲悎鏁�: {currentRound - ui.lastUsedRound}");
-            // 鍏抽棴UI
-            CloseWindow(ui);
+            Debug.Log($"閿�姣侀暱鏃堕棿鏈娇鐢ㄧ殑UI: {ui.uiName}, 绌洪棽鍥炲悎鏁�: {currentRound - ui.lastUsedRound}");
+            // 閿�姣乁I瀵硅薄
+            GameObject.Destroy(ui.gameObject);
         }
     }
     
@@ -525,8 +548,80 @@
         // 鑾峰彇UI绫诲瀷鍚嶇О
         string uiName = typeof(T).Name;
   
-        // Debug.LogError("鎵撳紑ui " + uiName);
+        // 浼樺厛浠巆losedUIDict涓幏鍙�
+        if (closedUIDict.TryGetValue(uiName, out List<UIBase> closedUIList) && closedUIList.Count > 0)
+        {
+            T recycledUI = closedUIList[0] as T;
+            closedUIList.RemoveAt(0);
+            
+            if (closedUIList.Count == 0)
+            {
+                closedUIDict.Remove(uiName);
+            }
+            
+            recycledUI.gameObject.SetActive(true);
+            
+            // 鑷姩璁剧疆鐖剁骇UI锛堝鏋滄湭鎸囧畾涓旀敮鎸佺埗瀛愬叧绯伙級
+            if (parentUI == null && recycledUI.supportParentChildRelation && uiStack.Count > 0)
+            {
+                // 鑾峰彇鏍堥《UI
+                UIBase topUI = uiStack.Peek();
+                // 濡傛灉鏍堥《UI涔熸敮鎸佺埗瀛愬叧绯讳笖涓嶆槸涓籙I锛屽垯灏嗗叾璁句负鐖剁骇
+                if (topUI != null && topUI.supportParentChildRelation && !topUI.isMainUI)
+                {
+                    parentUI = topUI;
+                }
+            }
+            
+            // 璁剧疆鐖剁骇UI
+            if (parentUI != null && recycledUI.supportParentChildRelation && !parentUI.isMainUI)
+            {
+                // 璁剧疆鐖跺瓙鍏崇郴
+                recycledUI.parentUI = parentUI;
+                if (parentUI.childrenUI == null)
+                {
+                    // 鍒濆鍖栫埗绾I鐨勫瓙UI鍒楄〃
+                    parentUI.childrenUI = new List<UIBase>();
+                }
+                // 娣诲姞鍒扮埗绾I鐨勫瓙UI鍒楄〃
+                parentUI.childrenUI.Add(recycledUI);
+            }
+            
+            // 鏇存柊鍥炲悎鏁�
+            currentRound++;
+            // 璁剧疆UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
+            recycledUI.lastUsedRound = currentRound;
+            // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
+            UpdateParentUIRounds(recycledUI);
+            
+            // 灏哢I娣诲姞鍒板瓧鍏镐腑
+            if (!uiDict.ContainsKey(uiName))
+            {
+                // 濡傛灉瀛楀吀涓笉瀛樺湪璇ョ被鍨嬬殑UI锛屽垱寤烘柊鍒楄〃
+                uiDict[uiName] = new List<UIBase>();
+            }
+            // 娣诲姞鍒癠I鍒楄〃
+            uiDict[uiName].Add(recycledUI);
+            
+            // 灏哢I娣诲姞鍒版爤涓�
+            uiStack.Push(recycledUI);
+            
+            // 鏇存柊UI鎺掑簭椤哄簭
+            UpdateUISortingOrder();
+            
+            // 鎵撳紑UI
+            recycledUI.HandleOpen();
 
+            OnOpenWindow?.Invoke(recycledUI);
+            
+            // 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+            CheckAndCloseIdleUI();
+            
+            return recycledUI;
+        }
+
+        // 濡傛灉closedUIDict涓病鏈夊彲鐢ㄧ殑UI瀹炰緥锛屽垯鍔犺浇鏂扮殑UI璧勬簮
+        // Debug.LogError("鎵撳紑ui " + uiName);
 
         // 鍔犺浇UI璧勬簮
         T ui = LoadUIResource<T>(uiName);
@@ -601,16 +696,16 @@
     /// <summary>
     /// 鍏抽棴UI
     /// </summary>
-    public void CloseWindow<T>() where T : UIBase
+    public void CloseWindow<T>(bool destroy = false) where T : UIBase
     {
         // 鑾峰彇UI绫诲瀷鍚嶇О
         string uiName = typeof(T).Name;
         
-        CloseWindow(uiName);
+        CloseWindow(uiName, destroy);
         
     }
 
-    public void CloseWindow(string uiName)
+    public void CloseWindow(string uiName, bool destroy = false)
     {
         // 妫�鏌I鏄惁瀛樺湪
         if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
@@ -624,13 +719,13 @@
         UIBase ui = uiDict[uiName][0];
         
         // 鍏抽棴UI
-        CloseWindow(ui);
+        CloseWindow(ui, destroy);
     }
     
     /// <summary>
     /// 鍏抽棴鎸囧畾鐨刄I瀹炰緥
     /// </summary>
-    public void CloseWindow(UIBase ui)
+    public void CloseWindow(UIBase ui, bool destroy = false)
     {
         // 妫�鏌I鏄惁涓虹┖
         if (ui == null)
@@ -654,7 +749,7 @@
         foreach (var childUI in childrenUI)
         {
             // 鍏抽棴瀛怳I
-            CloseWindow(childUI);
+            CloseWindow(childUI, destroy);
         }
         
         // 浠庢爤涓Щ闄I
@@ -699,8 +794,23 @@
         ui.HandleClose();
         OnCloseWindow?.Invoke(ui);
         
-        // 閿�姣乁I瀵硅薄
-        GameObject.Destroy(ui.gameObject);
+        if (destroy)
+        {
+            // 閿�姣乁I瀵硅薄
+            GameObject.Destroy(ui.gameObject);
+        }
+        else
+        {
+            // 娣诲姞鍒癱losedUIDict
+            if (!closedUIDict.ContainsKey(uiName))
+            {
+                closedUIDict[uiName] = new List<UIBase>();
+            }
+            closedUIDict[uiName].Add(ui);
+            
+            // 闅愯棌UI
+            ui.gameObject.SetActive(false);
+        }
         
         // 鏇存柊UI鎺掑簭椤哄簭
         UpdateUISortingOrder();
@@ -729,7 +839,7 @@
         foreach (var ui in uiListCopy)
         {
             // 鍏抽棴UI瀹炰緥
-            CloseWindow(ui);
+            CloseWindow(ui, false);
         }
     }
     
@@ -746,12 +856,13 @@
         foreach (var ui in uiArray)
         {
             // 鍏抽棴UI
-            CloseWindow(ui);
+            CloseWindow(ui, true);
         }
         
         // 娓呯┖UI瀛楀吀鍜屾爤
         uiDict.Clear();
         uiStack.Clear();
+        closedUIDict.Clear();
     }
     
     /// <summary>

--
Gitblit v1.8.0