From 6efea71970f560e5486b43de70bc441aedbd9e0a Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期二, 13 五月 2025 18:01:59 +0800
Subject: [PATCH] 配置/UI相关的一些修改

---
 Main/UI/UIManager.cs          |  792 ++++++++++++++++++++++++++++++++------------------------
 Main/Manager/ConfigManager.cs |    8 
 Main/UI/UIBase.cs             |    6 
 Main/UI/Main/MainWin.cs       |    8 
 4 files changed, 464 insertions(+), 350 deletions(-)

diff --git a/Main/Manager/ConfigManager.cs b/Main/Manager/ConfigManager.cs
index f9de79d..61d235e 100644
--- a/Main/Manager/ConfigManager.cs
+++ b/Main/Manager/ConfigManager.cs
@@ -53,11 +53,15 @@
     private async UniTask LoadConfigByType(Type configType)
     {
         string configName = configType.Name;
+        if (configName.EndsWith("Config"))
+        {
+            configName = configName.Substring(0, configName.Length - 6);
+        }
         TextAsset textAsset = await ResManager.Instance.LoadAsset<TextAsset>("Config", configName);
         if (textAsset != null)
         {
             string[] lines = textAsset.text.Split('\n');
-            var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+            var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
             if (methodInfo != null)
             {
                 methodInfo.Invoke(null, new object[] { lines });
@@ -91,7 +95,7 @@
             var methodInfo = typeof(T).GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
             if (methodInfo != null)
             {
-                methodInfo.Invoke(null, new object[] { lines });
+                methodInfo.Invoke(null, lines);
                 // 璁剧疆鍒濆鍖栨爣蹇�
                 var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                 if (isInitField != null)
diff --git a/Main/UI/Main/MainWin.cs b/Main/UI/Main/MainWin.cs
index 5164b2e..6b059df 100644
--- a/Main/UI/Main/MainWin.cs
+++ b/Main/UI/Main/MainWin.cs
@@ -154,7 +154,7 @@
         if (currentSubUI != null)
         {
             // 鍏抽棴褰撳墠鐣岄潰
-            UIManager.Instance.CloseWindow(currentSubUI);
+            currentSubUI.CloseWindow();
             currentSubUI = null;
         }
     }
@@ -164,10 +164,10 @@
     /// </summary>
     private void OpenSubUIByTabIndex(int index)
     {
+
         Debug.Log("鎵撳紑瀛愮晫闈� : " + index);
-
         // 涓诲煄 闃靛 鍚岀洘 绂忓埄 鍐掗櫓
-
+        windowBackground.SetActive(index != 4);
         //鏍规嵁绱㈠紩鎵撳紑涓嶅悓鐨勭晫闈�
          switch (index)
         {
@@ -195,8 +195,6 @@
                 // 渚嬪锛氭墦寮�璁剧疆鐣岄潰
                 currentSubUI = UIManager.Instance.OpenWindow<PlaceWin>();
                 Debug.Log("鎵撳紑鍐掗櫓鐣岄潰");
-
-                windowBackground.SetActive(false);
                 break;
             default:
                 Debug.LogWarning("鏈煡鐨勬爣绛剧储寮�: " + index);
diff --git a/Main/UI/UIBase.cs b/Main/UI/UIBase.cs
index d007547..cf514ea 100644
--- a/Main/UI/UIBase.cs
+++ b/Main/UI/UIBase.cs
@@ -36,6 +36,7 @@
     [SerializeField] public UILayer uiLayer = UILayer.Mid;
     [SerializeField][HideInInspector] public string uiName;
     [SerializeField] public bool isMainUI = false;
+    [SerializeField] public bool supportParentChildRelation = true; // 鏂板锛氭槸鍚︽敮鎸佺埗瀛愬叧绯�
 
     // 鎸佷箙鍖栫浉鍏�
     [SerializeField] public bool isPersistent = false;
@@ -725,6 +726,11 @@
         childrenUI.Clear();
     }
 
+    public bool IsActive()
+    {
+        return isActive;
+    }
+
     #endregion
 
     #region 鍥炶皟鏂规硶
diff --git a/Main/UI/UIManager.cs b/Main/UI/UIManager.cs
index 19037f0..cf10141 100644
--- a/Main/UI/UIManager.cs
+++ b/Main/UI/UIManager.cs
@@ -1,88 +1,111 @@
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
-using System;
+using System.Linq;
 
-public class UIManager : Singleton<UIManager>
+/// <summary>
+/// UI绠$悊鍣� - 璐熻矗绠$悊鎵�鏈塙I鐣岄潰鐨勬樉绀恒�侀殣钘忓拰灞傜骇
+/// </summary>
+public class UIManager : ManagerBase<UIManager>
 {
-    // 鍗曚緥瀹炰緥
+    #region 甯搁噺鍜屾灇涓�
+    
+    // 鍩虹鎺掑簭椤哄簭
+    private const int BASE_SORTING_ORDER = 10;
+    
+    #endregion
 
-    #region 鍙橀噺瀹氫箟
+    #region 瀛楁鍜屽睘鎬�
     
     // UI鏍硅妭鐐�
     private Transform uiRoot;
+    
+    // 鍚勫眰绾х殑Transform
     private Transform staticTrans;
     private Transform bottomTrans;
     private Transform midTrans;
     private Transform topTrans;
-    private Transform systemTrans;  
+    private Transform systemTrans;
     
-    // 鍩虹鎺掑簭椤哄簭
-    private const int BASE_SORTING_ORDER = 10;
-    private const int SORTING_ORDER_STEP = 10;
+    // UI瀛楀吀锛屽瓨鍌ㄦ墍鏈夊凡鍔犺浇鐨刄I锛岄敭涓篣I鍚嶇О锛屽�间负UI瀹炰緥
+    private Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>();
     
-    // 宸插姞杞界殑UI瀛楀吀
-    private Dictionary<string, UIBase> uiDict = new Dictionary<string, UIBase>();
-    
-    // 褰撳墠鎵撳紑鐨刄I鏍�
+    // UI鏍堬紝鐢ㄤ簬绠$悊UI鐨勬樉绀洪『搴�
     private Stack<UIBase> uiStack = new Stack<UIBase>();
     
     // 褰撳墠鏈�楂樼殑鎺掑簭椤哄簭
     private int currentHighestSortingOrder = 0;
     
-    // 褰撳墠鍥炲悎鏁�
+    // 褰撳墠鍥炲悎鏁帮紝鐢ㄤ簬璁板綍UI鐨勪娇鐢ㄦ儏鍐�
     private int currentRound = 0;
     
-    #endregion
-
-    #region 鍒濆鍖栨柟娉�
-    
-
-    #region 缂撳瓨鍙橀噺
-    
-    // 缂撳瓨Transform鏌ユ壘缁撴灉
-    private Dictionary<UILayer, Transform> layerTransformCache = new Dictionary<UILayer, Transform>();
-    
-    // 缂撳瓨灞傜骇瀵瑰簲鐨勫熀纭�鎺掑簭椤哄簭
+    // 缂撳瓨灞傜骇瀵瑰簲鐨勬帓搴忛『搴�
     private Dictionary<UILayer, int> layerSortingOrderCache = new Dictionary<UILayer, int>();
     
+    // 缂撳瓨灞傜骇瀵瑰簲鐨凾ransform
+    private Dictionary<UILayer, Transform> layerTransformCache = new Dictionary<UILayer, Transform>();
+    
+    // UI瀹炰緥璁℃暟鍣紝鐢ㄤ簬涓哄悓绫诲瀷UI鐢熸垚鍞竴鏍囪瘑
+    private Dictionary<string, int> uiInstanceCounter = new Dictionary<string, int>();
+    
+    // 涓婃妫�鏌ユ椂闂�
+    private float lastCheckTime = 0f;
+    // 妫�鏌ラ棿闅旓紙绉掞級
+    private const float CHECK_INTERVAL = 5f;
+    
     #endregion
+
+    #region 鍒濆鍖�
     
-    // 鍒濆鍖栫紦瀛�
-    private void InitCache()
+    /// <summary>
+    /// 鍒濆鍖朥I绠$悊鍣�
+    /// </summary>
+    public override void Init()
     {
-        // 鍒濆鍖栧眰绾ransform缂撳瓨
-        layerTransformCache.Clear();
-        layerTransformCache[UILayer.Static] = staticTrans;
-        layerTransformCache[UILayer.Bottom] = bottomTrans;
-        layerTransformCache[UILayer.Mid] = midTrans;
-        layerTransformCache[UILayer.Top] = topTrans;
-        layerTransformCache[UILayer.System] = systemTrans;
+        base.Init();
         
-        // 鍒濆鍖栧眰绾ф帓搴忛『搴忕紦瀛�
-        layerSortingOrderCache.Clear();
-        layerSortingOrderCache[UILayer.Static] = BASE_SORTING_ORDER;
-        layerSortingOrderCache[UILayer.Bottom] = BASE_SORTING_ORDER * 10;
-        layerSortingOrderCache[UILayer.Mid] = BASE_SORTING_ORDER * 100;
-        layerSortingOrderCache[UILayer.Top] = BASE_SORTING_ORDER * 1000;
-        layerSortingOrderCache[UILayer.System] = BASE_SORTING_ORDER * 10000;
-    }
-
-
-    // 鍒濆鍖�
-    public void Init()
-    {
+        // 鍒濆鍖朥I鏍硅妭鐐�
         InitUIRoot();
+        
+        // 鍒濆鍖栫紦瀛�
+        layerSortingOrderCache.Clear();
+        layerTransformCache.Clear();
+        uiInstanceCounter.Clear();
+        
+        Debug.Log("UI绠$悊鍣ㄥ垵濮嬪寲瀹屾垚");
     }
     
-    // 鍒涘缓UI鏍硅妭鐐�
+    /// <summary>
+    /// 鍒濆鍖朥I鏍硅妭鐐�
+    /// </summary>
     private void InitUIRoot()
     {
+        // 鏌ユ壘UI鏍硅妭鐐�
         GameObject root = GameObject.Find("UIRoot");
+        
+        // 濡傛灉鍦烘櫙涓病鏈塙I鏍硅妭鐐癸紝鍒欏垱寤轰竴涓�
         if (root == null)
         {
-            root = GameObject.Instantiate(Resources.Load<GameObject>("UI/UIRoot"));
-
+            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);
+            
             if (root == null)
             {
                 Debug.LogError("鏃犳硶鎵惧埌UI鏍硅妭鐐�");
@@ -123,6 +146,7 @@
     // 鑾峰彇UI灞傜骇瀵瑰簲鐨勫熀纭�鎺掑簭椤哄簭
     private int GetBaseSortingOrderForLayer(UILayer layer)
     {
+        // 灏濊瘯浠庣紦瀛樹腑鑾峰彇鎺掑簭椤哄簭
         if (layerSortingOrderCache.TryGetValue(layer, out int order))
             return order;
             
@@ -150,6 +174,7 @@
                 break;
         }
         
+        // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
         layerSortingOrderCache[layer] = result;
         return result;
     }
@@ -157,6 +182,7 @@
     // 鑾峰彇灞傜骇瀵瑰簲鐨凾ransform
     private Transform GetTransForLayer(UILayer layer)
     {
+        // 灏濊瘯浠庣紦瀛樹腑鑾峰彇Transform
         if (layerTransformCache.TryGetValue(layer, out Transform trans))
             return trans;
             
@@ -184,6 +210,7 @@
                 break;
         }
         
+        // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
         layerTransformCache[layer] = result;
         return result;
     }
@@ -191,32 +218,64 @@
     // 鑾峰彇UI瀹炰緥锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
     public T GetUI<T>() where T : UIBase
     {
+        // 鑾峰彇UI绫诲瀷鍚嶇О
         string uiName = typeof(T).Name;
         if (string.IsNullOrEmpty(uiName))
         {
+            // 璁板綍閿欒鏃ュ織
             Debug.LogError("UI鍚嶇О涓虹┖");
             return null;
         }
 
-        UIBase ui;
-        if (uiDict.TryGetValue(uiName, out ui))
+        // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
+        if (uiDict.TryGetValue(uiName, out List<UIBase> uiList) && uiList.Count > 0)
         {
-            return ui as T;
+            // 杩斿洖绗竴涓疄渚�
+            return uiList[0] as T;
         }
 
+        // 濡傛灉涓嶅瓨鍦紝杩斿洖null
         return null;
+    }
+    
+    // 鑾峰彇鎸囧畾绫诲瀷鐨勬墍鏈塙I瀹炰緥
+    public List<T> GetAllUI<T>() where T : UIBase
+    {
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = typeof(T).Name;
+        if (string.IsNullOrEmpty(uiName))
+        {
+            // 璁板綍閿欒鏃ュ織
+            Debug.LogError("UI鍚嶇О涓虹┖");
+            return new List<T>();
+        }
+
+        // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
+        if (uiDict.TryGetValue(uiName, out List<UIBase> uiList) && uiList.Count > 0)
+        {
+            // 灏嗗垪琛ㄤ腑鐨勬墍鏈夊疄渚嬭浆鎹负鎸囧畾绫诲瀷骞惰繑鍥�
+            return uiList.Cast<T>().ToList();
+        }
+
+        // 濡傛灉涓嶅瓨鍦紝杩斿洖绌哄垪琛�
+        return new List<T>();
     }
     
     // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
     private void UpdateParentUIRounds(UIBase ui)
     {
-        if (ui == null)
+        // 濡傛灉UI涓虹┖鎴栦笉鏀寔鐖跺瓙鍏崇郴锛岀洿鎺ヨ繑鍥�
+        if (ui == null || !ui.supportParentChildRelation)
             return;
             
+        // 鑾峰彇鐖剁骇UI
         UIBase parentUI = ui.parentUI;
+        // 閬嶅巻鎵�鏈夌埗绾I锛屾洿鏂板洖鍚堟暟
         while (parentUI != null)
         {
+            // 鏇存柊鐖剁骇UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
             parentUI.lastUsedRound = currentRound;
+            // 缁х画鍚戜笂鏌ユ壘鐖剁骇UI
             parentUI = parentUI.parentUI;
         }
     }
@@ -224,13 +283,17 @@
     // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
     private void CollectChildrenUI(UIBase ui, List<UIBase> result)
     {
-        if (ui == null || ui.childrenUI == null || ui.childrenUI.Count == 0)
+        // 濡傛灉UI涓虹┖鎴栨病鏈夊瓙UI鎴栦笉鏀寔鐖跺瓙鍏崇郴锛岀洿鎺ヨ繑鍥�
+        if (ui == null || !ui.supportParentChildRelation || ui.childrenUI == null || ui.childrenUI.Count == 0)
             return;
         
+        // 閬嶅巻鎵�鏈夊瓙UI
         foreach (var childUI in ui.childrenUI)
         {
+            // 濡傛灉缁撴灉鍒楄〃涓笉鍖呭惈褰撳墠瀛怳I锛屽垯娣诲姞
             if (!result.Contains(childUI))
             {
+                // 娣诲姞鍒扮粨鏋滃垪琛�
                 result.Add(childUI);
                 // 閫掑綊鏀堕泦瀛怳I鐨勫瓙UI
                 CollectChildrenUI(childUI, result);
@@ -238,37 +301,104 @@
         }
     }
     
+    /// <summary>
+    /// 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+    /// </summary>
+    public void CheckAndCloseIdleUI()
+    {
+        // 濡傛灉娌℃湁UI锛岀洿鎺ヨ繑鍥�
+        if (uiDict.Count == 0)
+            return;
+            
+        // 鍒涘缓闇�瑕佸叧闂殑UI鍒楄〃
+        List<UIBase> uiToClose = new List<UIBase>();
+        
+        // 閬嶅巻鎵�鏈塙I
+        foreach (var uiList in uiDict.Values)
+        {
+            foreach (var ui in uiList)
+            {
+                // 濡傛灉UI鏄寔涔呭寲鐨勶紝璺宠繃
+                if (ui.isPersistent)
+                    continue;
+                    
+                // 璁$畻UI绌洪棽鐨勫洖鍚堟暟
+                int idleRounds = currentRound - ui.lastUsedRound;
+                
+                // 濡傛灉绌洪棽鍥炲悎鏁拌秴杩囨渶澶х┖闂插洖鍚堟暟锛屾坊鍔犲埌鍏抽棴鍒楄〃
+                if (idleRounds > ui.maxIdleRounds)
+                {
+                    uiToClose.Add(ui);
+                }
+            }
+        }
+        
+        // 鍏抽棴鎵�鏈夐渶瑕佸叧闂殑UI
+        foreach (var ui in uiToClose)
+        {
+            // 璁板綍鏃ュ織
+            Debug.Log($"鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I: {ui.uiName}, 绌洪棽鍥炲悎鏁�: {currentRound - ui.lastUsedRound}");
+            // 鍏抽棴UI
+            CloseWindow(ui);
+        }
+    }
+    
+    // // 鐢熸垚UI瀹炰緥鐨勫敮涓�鏍囪瘑
+    // private string GenerateUIInstanceID(string uiName)
+    // {
+    //     // 濡傛灉璁℃暟鍣ㄤ腑涓嶅瓨鍦ㄨUI绫诲瀷锛屽垵濮嬪寲涓�0
+    //     if (!uiInstanceCounter.ContainsKey(uiName))
+    //     {
+    //         uiInstanceCounter[uiName] = 0;
+    //     }
+        
+    //     // 閫掑璁℃暟鍣�
+    //     uiInstanceCounter[uiName]++;
+        
+    //     // 杩斿洖甯︽湁璁℃暟鐨勫敮涓�鏍囪瘑
+    //     return $"{uiName}_{uiInstanceCounter[uiName]}";
+    // }
+    
     #endregion
 
     #region UI璧勬簮绠$悊
     
     // 鍔犺浇UI棰勫埗浣�
     private T LoadUIResource<T>(string uiName) where T : UIBase
-
     {
+        // 浠庤祫婧愮鐞嗗櫒鍔犺浇UI棰勫埗浣�
         GameObject prefab = ResManager.Instance.LoadUI(uiName);
 
+        // 妫�鏌ラ鍒朵綋鏄惁鍔犺浇鎴愬姛
         if (prefab == null)
         {
+            // 璁板綍閿欒鏃ュ織
             Debug.LogError($"鍔犺浇UI棰勫埗浣撳け璐�: {uiName}");
             return null;
         }
 
+        // 瀹炰緥鍖朥I瀵硅薄
         GameObject uiObject = GameObject.Instantiate(prefab);
+        // 璁剧疆瀵硅薄鍚嶇О
         uiObject.name = uiName;
+        // 鑾峰彇UI鍩虹被缁勪欢
         T uiBase = uiObject.GetComponent<T>();
 
+        // 妫�鏌I鍩虹被缁勪欢鏄惁瀛樺湪
         if (uiBase == null)
         {
+            // 璁板綍閿欒鏃ュ織
             Debug.LogError($"UI棰勫埗浣� {uiName} 娌℃湁 UIBase 缁勪欢");
             return null;
         }
 
+        // 璁剧疆UI鍚嶇О
         uiBase.uiName = uiName;
+        // // 璁剧疆UI瀹炰緥ID
+        // uiBase.instanceID = GenerateUIInstanceID(uiName);
 
         // 璁剧疆鐖惰妭鐐逛负UI鏍硅妭鐐�
         uiObject.transform.SetParent(GetTransForLayer(uiBase.uiLayer), false);
-
 
         // 璁剧疆鎺掑簭椤哄簭
         int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
@@ -284,6 +414,7 @@
     // 鏇存柊UI鎺掑簭椤哄簭
     private void UpdateUISortingOrder()
     {
+        // 閲嶇疆褰撳墠鏈�楂樻帓搴忛『搴�
         currentHighestSortingOrder = 0;
         
         // 閬嶅巻UI鏍堬紝璁剧疆鎺掑簭椤哄簭
@@ -292,353 +423,328 @@
         
         // 鍏堟寜鐓ILayer杩涜鎺掑簭锛岀劧鍚庡啀鎸夌収鏍堥『搴忔帓搴�
         Array.Sort(uiArray, (a, b) => {
+            // 姣旇緝UI灞傜骇
             int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
             if (layerCompare != 0)
                 return layerCompare;
                 
             // 鍚屽眰绾у唴锛屾寜鐓ф爤涓殑椤哄簭鎺掑簭
-            int aIndex = Array.IndexOf(uiArray, a);
-            int bIndex = Array.IndexOf(uiArray, b);
-            return aIndex.CompareTo(bIndex);
+            return Array.IndexOf(uiArray, a).CompareTo(Array.IndexOf(uiArray, b));
         });
         
-        for (int i = 0; i < uiArray.Length; i++)
+        // 閬嶅巻鎺掑簭鍚庣殑UI鏁扮粍锛岃缃帓搴忛『搴�
+        foreach (var ui in uiArray)
         {
-            UIBase ui = uiArray[i];
+            // 鑾峰彇鍩虹鎺掑簭椤哄簭
             int baseSortingOrder = GetBaseSortingOrderForLayer(ui.uiLayer);
-            int sortingOrder = baseSortingOrder + i * SORTING_ORDER_STEP;
-            
+            // 璁$畻褰撳墠UI鐨勬帓搴忛『搴�
+            int sortingOrder = baseSortingOrder + currentHighestSortingOrder;
+            // 璁剧疆UI鐨勬帓搴忛『搴�
             ui.SetSortingOrder(sortingOrder);
-            
-            if (sortingOrder > currentHighestSortingOrder)
-            {
-                currentHighestSortingOrder = sortingOrder;
-            }
+            // 鏇存柊褰撳墠鏈�楂樻帓搴忛『搴�
+            currentHighestSortingOrder += 10;
         }
     }
     
     #endregion
 
-    #region UI鏍堢鐞�
+    #region UI鎿嶄綔
     
-    // 浠嶶I鏍堜腑绉婚櫎鎸囧畾UI
-    private void RemoveFromUIStack(UIBase ui)
+    /// <summary>
+    /// 鎵撳紑UI
+    /// </summary>
+    public T OpenWindow<T>(UIBase parentUI = null) where T : UIBase
     {
-        if (ui == null || !uiStack.Contains(ui))
-            return;
-            
-        RemoveFromUIStack(new List<UIBase> { ui });
-    }
-
-    // 浠嶶I鏍堜腑绉婚櫎澶氫釜UI
-    private void RemoveFromUIStack(List<UIBase> uisToRemove)
-    {
-        if (uisToRemove == null || uisToRemove.Count == 0)
-            return;
-            
-        Stack<UIBase> tempStack = new Stack<UIBase>();
-        while (uiStack.Count > 0)
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = typeof(T).Name;
+        
+        // 鍔犺浇UI璧勬簮
+        T ui = LoadUIResource<T>(uiName);
+        if (ui == null)
         {
-            UIBase topUI = uiStack.Pop();
-            if (!uisToRemove.Contains(topUI))
+            // 璁板綍閿欒鏃ュ織
+            Debug.LogError($"鎵撳紑UI澶辫触: {uiName}");
+            return null;
+        }
+        
+        // 鑷姩璁剧疆鐖剁骇UI锛堝鏋滄湭鎸囧畾涓旀敮鎸佺埗瀛愬叧绯伙級
+        if (parentUI == null && ui.supportParentChildRelation && uiStack.Count > 0)
+        {
+            // 鑾峰彇鏍堥《UI
+            UIBase topUI = uiStack.Peek();
+            // 濡傛灉鏍堥《UI涔熸敮鎸佺埗瀛愬叧绯讳笖涓嶆槸涓籙I锛屽垯灏嗗叾璁句负鐖剁骇
+            if (topUI != null && topUI.supportParentChildRelation && !topUI.isMainUI)
             {
-                tempStack.Push(topUI);
+                parentUI = topUI;
             }
         }
         
-        // 鎭㈠UI鏍�
+        // 璁剧疆鐖剁骇UI
+        if (parentUI != null && ui.supportParentChildRelation && !parentUI.isMainUI)
+        {
+            // 璁剧疆鐖跺瓙鍏崇郴
+            ui.parentUI = parentUI;
+            if (parentUI.childrenUI == null)
+            {
+                // 鍒濆鍖栫埗绾I鐨勫瓙UI鍒楄〃
+                parentUI.childrenUI = new List<UIBase>();
+            }
+            // 娣诲姞鍒扮埗绾I鐨勫瓙UI鍒楄〃
+            parentUI.childrenUI.Add(ui);
+        }
+        
+        // 鏇存柊鍥炲悎鏁�
+        currentRound++;
+        // 璁剧疆UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
+        ui.lastUsedRound = currentRound;
+        // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
+        UpdateParentUIRounds(ui);
+        
+        // 灏哢I娣诲姞鍒板瓧鍏镐腑
+        if (!uiDict.ContainsKey(uiName))
+        {
+            // 濡傛灉瀛楀吀涓笉瀛樺湪璇ョ被鍨嬬殑UI锛屽垱寤烘柊鍒楄〃
+            uiDict[uiName] = new List<UIBase>();
+        }
+        // 娣诲姞鍒癠I鍒楄〃
+        uiDict[uiName].Add(ui);
+        
+        // 灏哢I娣诲姞鍒版爤涓�
+        uiStack.Push(ui);
+        
+        // 鏇存柊UI鎺掑簭椤哄簭
+        UpdateUISortingOrder();
+        
+        // 鎵撳紑UI
+        ui.HandleOpen();
+        
+        // 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+        CheckAndCloseIdleUI();
+        
+        return ui;
+    }
+    
+    /// <summary>
+    /// 鍏抽棴UI
+    /// </summary>
+    public void CloseWindow<T>() where T : UIBase
+    {
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = typeof(T).Name;
+        
+        // 妫�鏌I鏄惁瀛樺湪
+        if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
+        {
+            // 璁板綍璀﹀憡鏃ュ織
+            Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
+            return;
+        }
+        
+        // 鑾峰彇绗竴涓猆I瀹炰緥
+        UIBase ui = uiDict[uiName][0];
+        
+        // 鍏抽棴UI
+        CloseWindow(ui);
+    }
+    
+    /// <summary>
+    /// 鍏抽棴鎸囧畾鐨刄I瀹炰緥
+    /// </summary>
+    public void CloseWindow(UIBase ui)
+    {
+        // 妫�鏌I鏄惁涓虹┖
+        if (ui == null)
+        {
+            // 璁板綍璀﹀憡鏃ュ織
+            Debug.LogWarning("灏濊瘯鍏抽棴绌篣I");
+            return;
+        }
+        
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = ui.uiName;
+        
+        // 鏀堕泦鎵�鏈夊瓙UI
+        List<UIBase> childrenUI = new List<UIBase>();
+        if (ui.supportParentChildRelation)
+        {
+            CollectChildrenUI(ui, childrenUI);
+        }
+        
+        // 鍏堝叧闂墍鏈夊瓙UI
+        foreach (var childUI in childrenUI)
+        {
+            // 鍏抽棴瀛怳I
+            CloseWindow(childUI);
+        }
+        
+        // 浠庢爤涓Щ闄I
+        Stack<UIBase> tempStack = new Stack<UIBase>();
+        while (uiStack.Count > 0)
+        {
+            // 寮瑰嚭鏍堥《UI
+            UIBase tempUI = uiStack.Pop();
+            // 濡傛灉涓嶆槸瑕佸叧闂殑UI锛屽垯淇濆瓨鍒颁复鏃舵爤涓�
+            if (tempUI != ui)
+            {
+                tempStack.Push(tempUI);
+            }
+        }
+        
+        // 灏嗕复鏃舵爤涓殑UI閲嶆柊鍘嬪叆鏍堜腑
         while (tempStack.Count > 0)
         {
             uiStack.Push(tempStack.Pop());
         }
         
-        // 鏇存柊鎺掑簭椤哄簭
-        UpdateUISortingOrder();
-    }
-    
-    #endregion
-
-    #region 鍏叡鎺ュ彛鏂规硶
-    
-    // 鎵撳紑鍗曚釜UI绐楀彛
-    public T OpenWindow<T>() where T : UIBase
-    {
-        string uiName = typeof(T).Name;
-        if (string.IsNullOrEmpty(uiName))
+        // 浠庡瓧鍏镐腑绉婚櫎UI
+        if (uiDict.ContainsKey(uiName))
         {
-            Debug.LogError("灏濊瘯鎵撳紑绌哄悕绉扮殑UI绐楀彛");
-            return null;
-        }
-        
-        // 澧炲姞鍥炲悎鏁�
-        currentRound++;
-        
-        // 鍏堝皾璇曡幏鍙栧凡鍔犺浇鐨刄I
-        T ui = GetUI<T>();
-        
-        // 濡傛灉UI涓嶅瓨鍦紝鍒欏姞杞�
-        if (ui == null)
-        {
-            ui = LoadUIResource<T>(uiName);
-            if (ui == null)
-                return null;
-                
-            // 灏嗘柊鍔犺浇鐨刄I娣诲姞鍒板瓧鍏镐腑
-            uiDict[uiName] = ui;
-        }
-        
-        // 鏇存柊UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
-        ui.lastUsedRound = currentRound;
-        
-        // 鏇存柊鎵�鏈夌埗绾I鐨勫洖鍚堟暟
-        UpdateParentUIRounds(ui);
-        
-        if (ui.uiLayer != UILayer.System && !ui.isMainUI)
-        {
-            if (uiStack.Contains(ui))
+            // 浠嶶I鍒楄〃涓Щ闄�
+            uiDict[uiName].Remove(ui);
+            // 濡傛灉鍒楄〃涓虹┖锛屼粠瀛楀吀涓Щ闄よ绫诲瀷
+            if (uiDict[uiName].Count == 0)
             {
-                // 鍦∣penWindow鏂规硶涓慨鏀瑰叧闂璘I鐨勯�昏緫
-                // 鎵惧埌UI鍦ㄦ爤涓殑浣嶇疆
-                List<UIBase> uiList = new List<UIBase>(uiStack);
-                int index = uiList.IndexOf(ui);
-
-                // 鍏抽棴璇I涔嬪悗鐨勭浉鍏砋I锛屼絾淇濈暀System灞傜骇鐨刄I
-                Stack<UIBase> tempStack = new Stack<UIBase>();
-                while (uiStack.Count > index)
-                {
-                    UIBase topUI = uiStack.Pop();
-
-                    // 濡傛灉鏄疭ystem灞傜骇鐨刄I锛屼繚鐣欏畠
-                    if (topUI.uiLayer == UILayer.System || topUI.isMainUI)
-                    {
-                        tempStack.Push(topUI);
-                        continue;
-                    }
-
-                    // 濡傛灉涓嶆槸褰撳墠UI閾句笂鐨刄I锛屼篃淇濈暀瀹�
-                    // 鍒ゆ柇鏄惁灞炰簬褰撳墠UI閾剧殑閫昏緫锛氭鏌ユ槸鍚︽湁鐖跺瓙鍏崇郴
-                    bool isInCurrentChain = false;
-                    UIBase parent = ui;
-                    while (parent != null)
-                    {
-                        if (parent == topUI || parent.childrenUI.Contains(topUI))
-                        {
-                            isInCurrentChain = true;
-                            break;
-                        }
-                        parent = parent.parentUI;
-                    }
-
-                    if (!isInCurrentChain)
-                    {
-                        tempStack.Push(topUI);
-                        continue;
-                    }
-
-                    // 鍏抽棴褰撳墠UI閾句笂鐨勯潪System灞俇I
-                    topUI.HandleClose();
-
-                    // 娓呯悊鐖跺瓙鍏崇郴
-                    if (topUI.parentUI != null)
-                    {
-                        topUI.parentUI.RemoveChildUI(topUI);
-                        topUI.parentUI = null; // 娓呯悊鑷繁瀵圭埗UI鐨勫紩鐢�
-                    }
-                    topUI.ClearChildrenUI();
-                }
-
-                // 鎭㈠淇濈暀鐨刄I鍒版爤涓�
-                while (tempStack.Count > 0)
-                {
-                    uiStack.Push(tempStack.Pop());
-                }
-            }
-        }
-
-        ui.HandleOpen();
-        
-        // 濡傛灉鏍堜腑鏈夊叾浠朥I锛屽垯灏嗘爤椤禪I璁句负鐖禪I
-        if (!ui.isMainUI && ui.uiLayer != UILayer.System && uiStack.Count > 0)
-        {
-            UIBase topUI = uiStack.Peek();
-            
-            if (topUI != null)
-            {
-                // System灞傜骇UI涓嶅簲璇ユ垚涓哄叾浠朥I鐨勭埗UI锛屼篃涓嶅簲璇ユ垚涓哄叾浠朥I鐨勫瓙UI
-                if (topUI.uiLayer != UILayer.System)
-                {
-                    // 娓呯悊鏃х殑鐖跺瓙鍏崇郴
-                    if (ui.parentUI != null && ui.parentUI != topUI)
-                    {
-                        ui.parentUI.RemoveChildUI(ui);
-                    }
-                    
-                    // 璁剧疆鏂扮殑鐖跺瓙鍏崇郴
-                    topUI.AddChildUI(ui);
-                }
+                uiDict.Remove(uiName);
             }
         }
         
-        // 娣诲姞鍒癠I鏍�
-        uiStack.Push(ui);
-        
-        // 鏇存柊鎺掑簭椤哄簭
-        UpdateUISortingOrder();
-        
-        // 鍦ㄦ墦寮�鐣岄潰鍚庢鏌I鐢熷懡鍛ㄦ湡
-        CheckUILifecycle();
-        
-        return ui;
-    }
-
-    // 鎸夐『搴忔墦寮�澶氱骇UI绐楀彛
-    public UIBase OpenWindow(params string[] uiNames)
-    {
-        if (uiNames == null || uiNames.Length == 0)
-            return null;
-
-        UIBase ui = null;
-
-        for (int i = 0; i < uiNames.Length; i++)
+        // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
+        if (ui.supportParentChildRelation && ui.parentUI != null && ui.parentUI.childrenUI != null)
         {
-            string uiName = uiNames[i];
-            ui = OpenWindow(uiName);
-        }
-
-        return ui;
-    }
-    
-    // 鍏抽棴鎸囧畾UI绐楀彛
-    public void CloseWindow(UIBase ui)
-    {
-        if (ui == null)
-            return;
-        
-        // 鍒涘缓涓�涓垪琛ㄦ潵瀛樺偍闇�瑕佸叧闂殑UI
-        List<UIBase> uisToClose = new List<UIBase>
-        {
-            ui
-        };
-        
-        // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
-        CollectChildrenUI(ui, uisToClose);
-        
-        // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
-        if (ui.parentUI != null)
-        {
-            UpdateParentUIRounds(ui.parentUI);
+            // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
+            ui.parentUI.childrenUI.Remove(ui);
         }
         
-        // 鍏抽棴鎵�鏈夋敹闆嗗埌鐨刄I
-        foreach (var uiToClose in uisToClose)
-        {
-            // 鍏抽棴UI
-            uiToClose.HandleClose();
-            
-            // 娓呯悊鐖跺瓙鍏崇郴
-            if (uiToClose.parentUI != null)
-            {
-                uiToClose.parentUI.RemoveChildUI(uiToClose);
-                uiToClose.parentUI = null;
-            }
-            
-            // 妫�鏌ユ槸鍚﹂渶瑕佺珛鍗抽攢姣�
-            // 濡傛灉鏄潪鎸佷箙鍖朥I涓旇秴杩囦簡鏈�澶х┖闂插洖鍚堟暟锛岀珛鍗抽攢姣�
-            if (!uiToClose.isPersistent && (currentRound - uiToClose.lastUsedRound) > uiToClose.maxIdleRounds)
-            {
-                DestroyUI(uiToClose);
-            }
-        }
-        
-        // 浣跨敤鍏叡鏂规硶浠嶶I鏍堜腑绉婚櫎鎵�鏈夊叧闂殑UI
-        RemoveFromUIStack(uisToClose);
-    }
-    
-
-    // 杩斿洖涓婁竴绾I
-    public void GoBack()
-    {
-        if (uiStack.Count <= 1)
-            return;
-        
-        // 鍏抽棴褰撳墠UI
-        UIBase currentUI = uiStack.Pop();
-
-        CloseWindow(currentUI);
-        
-        // 鏇存柊鎺掑簭椤哄簭
-        UpdateUISortingOrder();
-    }
-    
-    // 閿�姣佹寚瀹歎I瀵硅薄
-    public void DestroyUI(UIBase ui)
-    {
-        if (ui == null)
-            return;
-    
         // 鍏抽棴UI
-        ui.Destroy();
-    
-        uiDict.Remove(ui.uiName);
+        ui.HandleClose();
         
-        // 浣跨敤鍏叡鏂规硶浠嶶I鏍堜腑绉婚櫎UI
-        RemoveFromUIStack(ui);
+        // 閿�姣乁I瀵硅薄
+        GameObject.Destroy(ui.gameObject);
+        
+        // 鏇存柊UI鎺掑簭椤哄簭
+        UpdateUISortingOrder();
     }
-
-    // 閿�姣佹寚瀹氬悕绉扮殑UI
-    public void DestroyUI(string uiName)
+    
+    /// <summary>
+    /// 鍏抽棴鎸囧畾绫诲瀷鐨勬墍鏈塙I瀹炰緥
+    /// </summary>
+    public void CloseAllWindows<T>() where T : UIBase
     {
-        if (string.IsNullOrEmpty(uiName))
-            return;
-
-        UIBase ui;
-        if (uiDict.TryGetValue(uiName, out ui))
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = typeof(T).Name;
+        
+        // 妫�鏌I鏄惁瀛樺湪
+        if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
         {
-            DestroyUI(ui);
+            // 璁板綍璀﹀憡鏃ュ織
+            Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
+            return;
+        }
+        
+        // 鍒涘缓UI瀹炰緥鍒楄〃鐨勫壇鏈紝鍥犱负鍦ㄥ叧闂繃绋嬩腑浼氫慨鏀瑰師鍒楄〃
+        List<UIBase> uiListCopy = new List<UIBase>(uiDict[uiName]);
+        
+        // 鍏抽棴鎵�鏈塙I瀹炰緥
+        foreach (var ui in uiListCopy)
+        {
+            // 鍏抽棴UI瀹炰緥
+            CloseWindow(ui);
         }
     }
-
-    // 閿�姣佹墍鏈塙I
+    
+    /// <summary>
+    /// 鍏抽棴鎵�鏈塙I
+    /// </summary>
     public void DestroyAllUI()
     {
-        List<string> uiNames = new List<string>(uiDict.Keys);
-
-        foreach (var ui in uiNames)
+        // 鍒涘缓UI鏍堢殑鍓湰锛屽洜涓哄湪鍏抽棴杩囩▼涓細淇敼鍘熸爤
+        UIBase[] uiArray = new UIBase[uiStack.Count];
+        uiStack.CopyTo(uiArray, 0);
+        
+        // 鍏抽棴鎵�鏈塙I
+        foreach (var ui in uiArray)
         {
-            if (ui != null)
-            {
-                DestroyUI(ui);
-            }
+            // 鍏抽棴UI
+            CloseWindow(ui);
         }
         
+        // 娓呯┖UI瀛楀吀鍜屾爤
         uiDict.Clear();
         uiStack.Clear();
     }
     
-    #endregion
-
-    #region 鐢熷懡鍛ㄦ湡绠$悊
-    
-    // 妫�鏌I鐢熷懡鍛ㄦ湡
-    private void CheckUILifecycle()
+    /// <summary>
+    /// 鍒锋柊UI
+    /// </summary>
+    public void RefreshUI<T>() where T : UIBase
     {
-        // 浣跨敤涓存椂鍒楄〃瀛樺偍闇�瑕侀攢姣佺殑UI鍚嶇О锛岄伩鍏嶅湪杩唬杩囩▼涓慨鏀瑰瓧鍏�
-        List<string> uiToDestroy = new List<string>();
+        // 鑾峰彇UI绫诲瀷鍚嶇О
+        string uiName = typeof(T).Name;
         
-        foreach (var pair in uiDict)
+        // 妫�鏌I鏄惁瀛樺湪
+        if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
         {
-            if (!pair.Value.isPersistent && !uiStack.Contains(pair.Value) && 
-                (currentRound - pair.Value.lastUsedRound) > pair.Value.maxIdleRounds)
+            // 璁板綍璀﹀憡鏃ュ織
+            Debug.LogWarning($"灏濊瘯鍒锋柊涓嶅瓨鍦ㄧ殑UI: {uiName}");
+            return;
+        }
+        
+        // 鍒锋柊鎵�鏈夎绫诲瀷鐨刄I瀹炰緥
+        foreach (var ui in uiDict[uiName])
+        {
+            // 鍒锋柊UI
+            ui.Refresh();
+        }
+    }
+    
+    /// <summary>
+    /// 鍒锋柊鎵�鏈塙I
+    /// </summary>
+    public void RefreshAllUI()
+    {
+        // 閬嶅巻鎵�鏈塙I绫诲瀷
+        foreach (var uiList in uiDict.Values)
+        {
+            // 閬嶅巻璇ョ被鍨嬬殑鎵�鏈塙I瀹炰緥
+            foreach (var ui in uiList)
             {
-                uiToDestroy.Add(pair.Key);
+                // 鍒锋柊UI
+                ui.Refresh();
             }
         }
-        
-        foreach (var uiName in uiToDestroy)
+    }
+    
+    private void Update()
+    {
+        // 濡傛灉璺濈涓婃妫�鏌ョ殑鏃堕棿瓒呰繃浜嗘鏌ラ棿闅�
+        if (Time.time - lastCheckTime > CHECK_INTERVAL)
         {
-            DestroyUI(uiName);
+            // 鏇存柊涓婃妫�鏌ユ椂闂�
+            lastCheckTime = Time.time;
+            // 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+            CheckAndCloseIdleUI();
         }
     }
     
     #endregion
+
+    #region 閲婃斁璧勬簮
+    
+    /// <summary>
+    /// 閲婃斁璧勬簮
+    /// </summary>
+    public override void Release()
+    {
+        // 鍏抽棴鎵�鏈塙I
+        DestroyAllUI();
+        
+        // 娓呯┖缂撳瓨
+        layerSortingOrderCache.Clear();
+        layerTransformCache.Clear();
+        uiInstanceCounter.Clear();
+        
+        Debug.Log("UI绠$悊鍣ㄨ祫婧愰噴鏀惧畬鎴�");
+    }
+    
+    #endregion
 }

--
Gitblit v1.8.0