From a7f4c5ecc5268c49f6a6caf769b3ebee6f237662 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 04 六月 2025 18:52:55 +0800
Subject: [PATCH] 目录迁移 整理
---
Main/Manager/UIManager.cs | 1842 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 921 insertions(+), 921 deletions(-)
diff --git a/Main/UI/UIManager.cs b/Main/Manager/UIManager.cs
similarity index 99%
rename from Main/UI/UIManager.cs
rename to Main/Manager/UIManager.cs
index 05a0d37..7063ca0 100644
--- a/Main/UI/UIManager.cs
+++ b/Main/Manager/UIManager.cs
@@ -1,921 +1,921 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using System.Linq;
-
-/// <summary>
-/// UI绠$悊鍣� - 璐熻矗绠$悊鎵�鏈塙I鐣岄潰鐨勬樉绀恒�侀殣钘忓拰灞傜骇
-/// </summary>
-public class UIManager : ManagerBase<UIManager>
-{
- #region 甯搁噺鍜屾灇涓�
-
- // 鍩虹鎺掑簭椤哄簭
- private const int BASE_SORTING_ORDER = 10;
-
- #endregion
-
- #region 瀛楁鍜屽睘鎬�
-
- // UI鏍硅妭鐐�
- private Transform uiRoot;
-
- // 鍚勫眰绾х殑Transform
- private Transform staticTrans;
- private Transform bottomTrans;
- private Transform midTrans;
- private Transform topTrans;
- private Transform systemTrans;
-
- // 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>();
-
- // 褰撳墠鏈�楂樼殑鎺掑簭椤哄簭
- private int currentHighestSortingOrder = 0;
-
- // 褰撳墠鍥炲悎鏁帮紝鐢ㄤ簬璁板綍UI鐨勪娇鐢ㄦ儏鍐�
- private int currentRound = 0;
-
- // 缂撳瓨灞傜骇瀵瑰簲鐨勬帓搴忛『搴�
- 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;
-
- public Action<UIBase> OnOpenWindow;
-
- public Action<UIBase> OnCloseWindow;
-
- #endregion
-
- #region 鍒濆鍖�
-
- /// <summary>
- /// 鍒濆鍖朥I绠$悊鍣�
- /// </summary>
- public override void Init()
- {
- base.Init();
-
- // 鍒濆鍖朥I鏍硅妭鐐�
- InitUIRoot();
-
- // 鍒濆鍖栫紦瀛�
- layerSortingOrderCache.Clear();
- layerTransformCache.Clear();
- uiInstanceCounter.Clear();
-
- Debug.Log("UI绠$悊鍣ㄥ垵濮嬪寲瀹屾垚");
- }
-
- /// <summary>
- /// 鍒濆鍖朥I鏍硅妭鐐�
- /// </summary>
- private void InitUIRoot()
- {
- // 鏌ユ壘UI鏍硅妭鐐�
- GameObject root = GameObject.Find("UIRoot");
-
- // 濡傛灉鍦烘櫙涓病鏈塙I鏍硅妭鐐癸紝鍒欏垱寤轰竴涓�
- if (root == null)
- {
- root = GameObject.Instantiate(BuiltInLoader.LoadPrefab("UIRoot"));
- root.name = "UIRoot";
- if (root == null)
- {
- Debug.LogError("鏃犳硶鎵惧埌UI鏍硅妭鐐�");
- return;
- }
-
- // 娣诲姞DontDestroyOnLoad缁勪欢锛岀‘淇漊I鏍硅妭鐐瑰湪鍦烘櫙鍒囨崲鏃朵笉琚攢姣�
- GameObject.DontDestroyOnLoad(root);
- }
-
- uiRoot = root.transform;
- uiRoot.position = Vector3.zero;
-
- staticTrans = uiRoot.Find("Static");
- bottomTrans = uiRoot.Find("Bottom");
- midTrans = uiRoot.Find("Middle");
- topTrans = uiRoot.Find("Top");
- systemTrans = uiRoot.Find("System");
-
- 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
-
- #region 杈呭姪鏂规硶
-
- // 鑾峰彇UI灞傜骇瀵瑰簲鐨勫熀纭�鎺掑簭椤哄簭
- private int GetBaseSortingOrderForLayer(UILayer layer)
- {
- // 灏濊瘯浠庣紦瀛樹腑鑾峰彇鎺掑簭椤哄簭
- if (layerSortingOrderCache.TryGetValue(layer, out int order))
- return order;
-
- // 濡傛灉缂撳瓨涓病鏈夛紝浣跨敤鍘熸潵鐨勬柟娉曡绠楀苟缂撳瓨缁撴灉
- int result;
- switch (layer)
- {
- case UILayer.Static:
- result = BASE_SORTING_ORDER;
- break;
- case UILayer.Bottom:
- result = BASE_SORTING_ORDER * 10;
- break;
- case UILayer.Mid:
- result = BASE_SORTING_ORDER * 100;
- break;
- case UILayer.Top:
- result = BASE_SORTING_ORDER * 1000;
- break;
- case UILayer.System:
- result = BASE_SORTING_ORDER * 10000;
- break;
- default:
- result = BASE_SORTING_ORDER * 10;
- break;
- }
-
- // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
- layerSortingOrderCache[layer] = result;
- return result;
- }
-
- // 鑾峰彇灞傜骇瀵瑰簲鐨凾ransform
- private Transform GetTransForLayer(UILayer layer)
- {
- // 灏濊瘯浠庣紦瀛樹腑鑾峰彇Transform
- if (layerTransformCache.TryGetValue(layer, out Transform trans))
- return trans;
-
- // 濡傛灉缂撳瓨涓病鏈夛紝浣跨敤鍘熸潵鐨勬柟娉曡幏鍙栧苟缂撳瓨缁撴灉
- Transform result;
- switch (layer)
- {
- case UILayer.Static:
- result = staticTrans;
- break;
- case UILayer.Bottom:
- result = bottomTrans;
- break;
- case UILayer.Mid:
- result = midTrans;
- break;
- case UILayer.Top:
- result = topTrans;
- break;
- case UILayer.System:
- result = systemTrans;
- break;
- default:
- result = bottomTrans;
- break;
- }
-
- // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
- layerTransformCache[layer] = result;
- return result;
- }
-
- // 鑾峰彇UI瀹炰緥锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
- public T GetUI<T>() where T : UIBase
- {
- // 鑾峰彇UI绫诲瀷鍚嶇О
- string uiName = typeof(T).Name;
- if (string.IsNullOrEmpty(uiName))
- {
- // 璁板綍閿欒鏃ュ織
- Debug.LogError("UI鍚嶇О涓虹┖");
- return null;
- }
-
- // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
- if (uiDict.TryGetValue(uiName, out List<UIBase> uiList) && uiList.Count > 0)
- {
- // 杩斿洖绗竴涓疄渚�
- return uiList[0] as T;
- }
-
- // 濡傛灉涓嶅瓨鍦紝杩斿洖null
- return null;
- }
-
- public List<T> GetUIList<T>() where T : UIBase
- {
- List<T> uiList = new List<T>();
-
- // 鑾峰彇UI绫诲瀷鍚嶇О
- string uiName = typeof(T).Name;
- if (string.IsNullOrEmpty(uiName))
- {
- // 璁板綍閿欒鏃ュ織
- Debug.LogError("UI鍚嶇О涓虹┖");
- return uiList;
- }
-
- // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
- List<UIBase> tempList = null;
- uiDict.TryGetValue(uiName, out tempList);
-
- if (tempList != null)
- {
- for (int i = 0; i < tempList.Count; i++)
- {
- UIBase ui = tempList[i];
- if (null != ui)
- {
- uiList.Add(ui as T);
- }
- }
- }
-
- return uiList;
- }
-
- public bool IsOpenedInList<T>() where T : UIBase
- {
- List<T> uiList = GetUIList<T>();
-
- foreach (T ui in uiList)
- {
- if (ui.IsActive())
- {
- return true;
- }
- }
-
- return false;
- }
-
- public bool IsOpened<T>() where T : UIBase
- {
- T ui = GetUI<T>();
-
- if (null != ui)
- {
- return ui.IsActive();
- }
-
- return false;
- }
-
- // 鑾峰彇鎸囧畾绫诲瀷鐨勬墍鏈塙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)
- {
- // 濡傛灉UI涓虹┖鎴栦笉鏀寔鐖跺瓙鍏崇郴锛岀洿鎺ヨ繑鍥�
- if (ui == null || !ui.supportParentChildRelation)
- return;
-
- // 鑾峰彇鐖剁骇UI
- UIBase parentUI = ui.parentUI;
- // 閬嶅巻鎵�鏈夌埗绾I锛屾洿鏂板洖鍚堟暟
- while (parentUI != null)
- {
- // 鏇存柊鐖剁骇UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
- parentUI.lastUsedRound = currentRound;
- // 缁х画鍚戜笂鏌ユ壘鐖剁骇UI
- parentUI = parentUI.parentUI;
- }
- }
-
- // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
- private void CollectChildrenUI(UIBase ui, List<UIBase> result)
- {
- // 濡傛灉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);
- }
- }
- }
-
- /// <summary>
- /// 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
- /// </summary>
- public void CheckAndCloseIdleUI()
- {
- // 濡傛灉娌℃湁UI锛岀洿鎺ヨ繑鍥�
- if (uiDict.Count == 0 && closedUIDict.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;
-
- if (ui.IsActive())
- continue;
-
- // 璁$畻UI绌洪棽鐨勫洖鍚堟暟
- int idleRounds = currentRound - ui.lastUsedRound;
-
- // 濡傛灉绌洪棽鍥炲悎鏁拌秴杩囨渶澶х┖闂插洖鍚堟暟锛屾坊鍔犲埌鍏抽棴鍒楄〃
- if (idleRounds > ui.maxIdleRounds)
- {
- uiToClose.Add(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($"閿�姣侀暱鏃堕棿鏈娇鐢ㄧ殑UI: {ui.uiName}, 绌洪棽鍥炲悎鏁�: {currentRound - ui.lastUsedRound}");
- // 閿�姣乁I瀵硅薄
- GameObject.Destroy(ui.gameObject);
- }
- }
-
- // // 鐢熸垚UI瀹炰緥鐨勫敮涓�鏍囪瘑
- // private string GenerateUIInstanceID(string uiName)
- // {
- // // 濡傛灉璁℃暟鍣ㄤ腑涓嶅瓨鍦ㄨUI绫诲瀷锛屽垵濮嬪寲涓�0
- // if (!uiInstanceCounter.ContainsKey(uiName))
- // {
- // uiInstanceCounter[uiName] = 0;
- // }
-
- // // 閫掑璁℃暟鍣�
- // uiInstanceCounter[uiName]++;
-
- // // 杩斿洖甯︽湁璁℃暟鐨勫敮涓�鏍囪瘑
- // return $"{uiName}_{uiInstanceCounter[uiName]}";
- // }
-
- #endregion
-
- #region UI璧勬簮绠$悊
-
- private UIBase LoadUIResource(string uiName)
- {
- // 浠庤祫婧愮鐞嗗櫒鍔犺浇UI棰勫埗浣�
- GameObject prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
-
- // 妫�鏌ラ鍒朵綋鏄惁鍔犺浇鎴愬姛
- if (prefab == null)
- {
- // 璁板綍閿欒鏃ュ織
- Debug.LogError($"鍔犺浇UI棰勫埗浣撳け璐�: {uiName}");
- return null;
- }
-
- // 瀹炰緥鍖朥I瀵硅薄
- GameObject uiObject = GameObject.Instantiate(prefab);
- // 璁剧疆瀵硅薄鍚嶇О
- uiObject.name = uiName;
-
- // 閫氳繃uiName鏄犲皠Type
- Type uiType = Type.GetType(uiName);
- if (uiType == null)
- {
- Debug.LogError($"鎵句笉鍒癠I绫诲瀷: {uiName}");
- return null;
- }
-
- // 鑾峰彇UI鍩虹被缁勪欢
- UIBase uiBase = uiObject.GetComponent(uiType) as UIBase;
-
- // 妫�鏌I鍩虹被缁勪欢鏄惁瀛樺湪
- if (uiBase == null)
- {
- // 璁板綍閿欒鏃ュ織
- Debug.LogError($"UI棰勫埗浣� {uiName} 娌℃湁 UIBase 缁勪欢鎴栫被鍨嬩笉鍖归厤");
- return null;
- }
-
- // 璁剧疆UI鍚嶇О
- uiBase.uiName = uiName;
-
- // 璁剧疆鐖惰妭鐐逛负UI鏍硅妭鐐�
- Transform parentTrans = GetTransForLayer(uiBase.uiLayer);
-
- uiObject.transform.SetParent(parentTrans, false);
-
- // 璁剧疆鎺掑簭椤哄簭
- int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
- uiBase.SetSortingOrder(baseSortingOrder);
-
- return uiBase;
- }
-
- // 鍔犺浇UI棰勫埗浣�
- private T LoadUIResource<T>(string uiName) where T : UIBase
- {
- return LoadUIResource(uiName) as T;
- }
-
- #endregion
-
- #region UI鎺掑簭绠$悊
-
- // 鏇存柊UI鎺掑簭椤哄簭
- private void UpdateUISortingOrder()
- {
- // 閲嶇疆褰撳墠鏈�楂樻帓搴忛『搴�
- currentHighestSortingOrder = 0;
-
- // 閬嶅巻UI鏍堬紝璁剧疆鎺掑簭椤哄簭
- UIBase[] uiArray = new UIBase[uiStack.Count];
- uiStack.CopyTo(uiArray, 0);
-
- // 鍏堟寜鐓ILayer杩涜鎺掑簭锛岀劧鍚庡啀鎸夌収鏍堥『搴忔帓搴�
- Array.Sort(uiArray, (a, b) => {
- // 姣旇緝UI灞傜骇
- int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
- if (layerCompare != 0)
- return layerCompare;
-
- // 鍚屽眰绾у唴锛屾寜鐓ф爤涓殑椤哄簭鎺掑簭
- return Array.IndexOf(uiArray, a).CompareTo(Array.IndexOf(uiArray, b));
- });
-
- // 閬嶅巻鎺掑簭鍚庣殑UI鏁扮粍锛岃缃帓搴忛『搴�
- foreach (var ui in uiArray)
- {
- // 鑾峰彇鍩虹鎺掑簭椤哄簭
- int baseSortingOrder = GetBaseSortingOrderForLayer(ui.uiLayer);
- // 璁$畻褰撳墠UI鐨勬帓搴忛『搴�
- int sortingOrder = baseSortingOrder + currentHighestSortingOrder;
- // 璁剧疆UI鐨勬帓搴忛『搴�
- ui.SetSortingOrder(sortingOrder);
- // 鏇存柊褰撳墠鏈�楂樻帓搴忛『搴�
- currentHighestSortingOrder += 10;
- }
- }
-
- #endregion
-
- #region UI鎿嶄綔
-
-
-
- private UIBase GetLastSupportParentChildRelationUI()
- {
- List<UIBase> tempList = new List<UIBase>();
-
- UIBase target = null;
-
- while (target == null && uiStack.Count > 0)
- {
- UIBase uiBase = uiStack.Pop();
-
- if (uiBase != null && uiBase.supportParentChildRelation && !uiBase.isMainUI)
- {
- target = uiBase;
- }
-
- tempList.Add(uiBase);
- }
-
- for (int i = tempList.Count - 1; i >= 0; i--)
- {
- uiStack.Push(tempList[i]);
- }
-
- return target;
- }
-
- public UIBase OpenWindow(string uiName)
- {
- // 浼樺厛浠巆losedUIDict涓幏鍙�
- UIBase parentUI = null;
-
- UIBase returnValue = null;
-
- if (closedUIDict.TryGetValue(uiName, out List<UIBase> closedUIList) && closedUIList.Count > 0)
- {
- returnValue = closedUIList[0] as UIBase;
- closedUIList.RemoveAt(0);
-
- if (closedUIList.Count == 0)
- {
- closedUIDict.Remove(uiName);
- }
- }
- else
- {
- returnValue = LoadUIResource(uiName);
- if (returnValue == null)
- {
- // 璁板綍閿欒鏃ュ織
- Debug.LogError($"鎵撳紑UI澶辫触: {uiName}");
- return null;
- }
- }
-
- returnValue.gameObject.SetActive(true);
-
- // 鑷姩璁剧疆鐖剁骇UI锛堝鏋滄湭鎸囧畾涓旀敮鎸佺埗瀛愬叧绯伙級
- if (returnValue.supportParentChildRelation && uiStack.Count > 0)
- {
- // 鑾峰彇鏍堥《UI
- parentUI = GetLastSupportParentChildRelationUI();
- }
-
- // 璁剧疆鐖剁骇UI
- if (parentUI != null)
- {
- // 璁剧疆鐖跺瓙鍏崇郴
- returnValue.parentUI = parentUI;
- if (parentUI.childrenUI == null)
- {
- // 鍒濆鍖栫埗绾I鐨勫瓙UI鍒楄〃
- parentUI.childrenUI = new List<UIBase>();
- }
- // 娣诲姞鍒扮埗绾I鐨勫瓙UI鍒楄〃
- parentUI.childrenUI.Add(returnValue);
- }
-
- // 鏇存柊鍥炲悎鏁�
- currentRound++;
- // 璁剧疆UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
- returnValue.lastUsedRound = currentRound;
- // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
- UpdateParentUIRounds(returnValue);
-
- // 灏哢I娣诲姞鍒板瓧鍏镐腑
- if (!uiDict.ContainsKey(uiName))
- {
- // 濡傛灉瀛楀吀涓笉瀛樺湪璇ョ被鍨嬬殑UI锛屽垱寤烘柊鍒楄〃
- uiDict[uiName] = new List<UIBase>();
- }
- // 娣诲姞鍒癠I鍒楄〃
- uiDict[uiName].Add(returnValue);
-
- // 灏哢I娣诲姞鍒版爤涓�
- uiStack.Push(returnValue);
-
- // 鏇存柊UI鎺掑簭椤哄簭
- UpdateUISortingOrder();
-
- // 鎵撳紑UI
- returnValue.HandleOpen();
-
- OnOpenWindow?.Invoke(returnValue);
-
- // 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
- CheckAndCloseIdleUI();
-
- return returnValue;
- }
-
- /// <summary>
- /// 鎵撳紑UI
- /// </summary>
- public T OpenWindow<T>() where T : UIBase
- {
- // 鑾峰彇UI绫诲瀷鍚嶇О
- string uiName = typeof(T).Name;
- return OpenWindow(uiName) as T;
- }
-
- /// <summary>
- /// 鍏抽棴UI
- /// </summary>
- public void CloseWindow<T>(bool destroy = false) where T : UIBase
- {
- // 鑾峰彇UI绫诲瀷鍚嶇О
- string uiName = typeof(T).Name;
-
- CloseWindow(uiName, destroy);
-
- }
-
- public void CloseWindow(string uiName, bool destroy = false)
- {
- // 妫�鏌I鏄惁瀛樺湪
- if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
- {
- // 璁板綍璀﹀憡鏃ュ織
- Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
- return;
- }
-
- // 鑾峰彇绗竴涓猆I瀹炰緥
- UIBase ui = uiDict[uiName][0];
-
- // 鍏抽棴UI
- CloseWindow(ui, destroy);
- }
-
- /// <summary>
- /// 鍏抽棴鎸囧畾鐨刄I瀹炰緥
- /// </summary>
- public void CloseWindow(UIBase ui, bool destroy = false)
- {
- // 妫�鏌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, destroy);
- }
-
- // 浠庢爤涓Щ闄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());
- }
-
- // 浠庡瓧鍏镐腑绉婚櫎UI
- if (uiDict.ContainsKey(uiName))
- {
- // 浠嶶I鍒楄〃涓Щ闄�
- uiDict[uiName].Remove(ui);
- // 濡傛灉鍒楄〃涓虹┖锛屼粠瀛楀吀涓Щ闄よ绫诲瀷
- if (uiDict[uiName].Count == 0)
- {
- uiDict.Remove(uiName);
- }
- }
-
- // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
- if (ui.supportParentChildRelation && ui.parentUI != null && ui.parentUI.childrenUI != null)
- {
- // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
- ui.parentUI.childrenUI.Remove(ui);
- }
-
- // 鍏抽棴UI
- ui.HandleClose();
- OnCloseWindow?.Invoke(ui);
-
- 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();
- }
-
- /// <summary>
- /// 鍏抽棴鎸囧畾绫诲瀷鐨勬墍鏈塙I瀹炰緥
- /// </summary>
- public void CloseAllWindows<T>() where T : UIBase
- {
- // 鑾峰彇UI绫诲瀷鍚嶇О
- string uiName = typeof(T).Name;
-
- // 妫�鏌I鏄惁瀛樺湪
- if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
- {
- // 璁板綍璀﹀憡鏃ュ織
- Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
- return;
- }
-
- // 鍒涘缓UI瀹炰緥鍒楄〃鐨勫壇鏈紝鍥犱负鍦ㄥ叧闂繃绋嬩腑浼氫慨鏀瑰師鍒楄〃
- List<UIBase> uiListCopy = new List<UIBase>(uiDict[uiName]);
-
- // 鍏抽棴鎵�鏈塙I瀹炰緥
- foreach (var ui in uiListCopy)
- {
- // 鍏抽棴UI瀹炰緥
- CloseWindow(ui, false);
- }
- }
-
- /// <summary>
- /// 鍏抽棴鎵�鏈塙I
- /// </summary>
- public void DestroyAllUI()
- {
- // 鍒涘缓UI鏍堢殑鍓湰锛屽洜涓哄湪鍏抽棴杩囩▼涓細淇敼鍘熸爤
- UIBase[] uiArray = new UIBase[uiStack.Count];
- uiStack.CopyTo(uiArray, 0);
-
- // 鍏抽棴鎵�鏈塙I
- foreach (var ui in uiArray)
- {
- // 鍏抽棴UI
- CloseWindow(ui, true);
- }
-
- // 娓呯┖UI瀛楀吀鍜屾爤
- uiDict.Clear();
- uiStack.Clear();
- closedUIDict.Clear();
- }
-
- /// <summary>
- /// 鍒锋柊UI
- /// </summary>
- public void RefreshUI<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瀹炰緥
- 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)
- {
- // 鍒锋柊UI
- ui.Refresh();
- }
- }
- }
-
- private void Update()
- {
- // 濡傛灉璺濈涓婃妫�鏌ョ殑鏃堕棿瓒呰繃浜嗘鏌ラ棿闅�
- if (Time.time - lastCheckTime > CHECK_INTERVAL)
- {
- // 鏇存柊涓婃妫�鏌ユ椂闂�
- 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
-}
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+
+/// <summary>
+/// UI绠$悊鍣� - 璐熻矗绠$悊鎵�鏈塙I鐣岄潰鐨勬樉绀恒�侀殣钘忓拰灞傜骇
+/// </summary>
+public class UIManager : ManagerBase<UIManager>
+{
+ #region 甯搁噺鍜屾灇涓�
+
+ // 鍩虹鎺掑簭椤哄簭
+ private const int BASE_SORTING_ORDER = 10;
+
+ #endregion
+
+ #region 瀛楁鍜屽睘鎬�
+
+ // UI鏍硅妭鐐�
+ private Transform uiRoot;
+
+ // 鍚勫眰绾х殑Transform
+ private Transform staticTrans;
+ private Transform bottomTrans;
+ private Transform midTrans;
+ private Transform topTrans;
+ private Transform systemTrans;
+
+ // 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>();
+
+ // 褰撳墠鏈�楂樼殑鎺掑簭椤哄簭
+ private int currentHighestSortingOrder = 0;
+
+ // 褰撳墠鍥炲悎鏁帮紝鐢ㄤ簬璁板綍UI鐨勪娇鐢ㄦ儏鍐�
+ private int currentRound = 0;
+
+ // 缂撳瓨灞傜骇瀵瑰簲鐨勬帓搴忛『搴�
+ 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;
+
+ public Action<UIBase> OnOpenWindow;
+
+ public Action<UIBase> OnCloseWindow;
+
+ #endregion
+
+ #region 鍒濆鍖�
+
+ /// <summary>
+ /// 鍒濆鍖朥I绠$悊鍣�
+ /// </summary>
+ public override void Init()
+ {
+ base.Init();
+
+ // 鍒濆鍖朥I鏍硅妭鐐�
+ InitUIRoot();
+
+ // 鍒濆鍖栫紦瀛�
+ layerSortingOrderCache.Clear();
+ layerTransformCache.Clear();
+ uiInstanceCounter.Clear();
+
+ Debug.Log("UI绠$悊鍣ㄥ垵濮嬪寲瀹屾垚");
+ }
+
+ /// <summary>
+ /// 鍒濆鍖朥I鏍硅妭鐐�
+ /// </summary>
+ private void InitUIRoot()
+ {
+ // 鏌ユ壘UI鏍硅妭鐐�
+ GameObject root = GameObject.Find("UIRoot");
+
+ // 濡傛灉鍦烘櫙涓病鏈塙I鏍硅妭鐐癸紝鍒欏垱寤轰竴涓�
+ if (root == null)
+ {
+ root = GameObject.Instantiate(BuiltInLoader.LoadPrefab("UIRoot"));
+ root.name = "UIRoot";
+ if (root == null)
+ {
+ Debug.LogError("鏃犳硶鎵惧埌UI鏍硅妭鐐�");
+ return;
+ }
+
+ // 娣诲姞DontDestroyOnLoad缁勪欢锛岀‘淇漊I鏍硅妭鐐瑰湪鍦烘櫙鍒囨崲鏃朵笉琚攢姣�
+ GameObject.DontDestroyOnLoad(root);
+ }
+
+ uiRoot = root.transform;
+ uiRoot.position = Vector3.zero;
+
+ staticTrans = uiRoot.Find("Static");
+ bottomTrans = uiRoot.Find("Bottom");
+ midTrans = uiRoot.Find("Middle");
+ topTrans = uiRoot.Find("Top");
+ systemTrans = uiRoot.Find("System");
+
+ 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
+
+ #region 杈呭姪鏂规硶
+
+ // 鑾峰彇UI灞傜骇瀵瑰簲鐨勫熀纭�鎺掑簭椤哄簭
+ private int GetBaseSortingOrderForLayer(UILayer layer)
+ {
+ // 灏濊瘯浠庣紦瀛樹腑鑾峰彇鎺掑簭椤哄簭
+ if (layerSortingOrderCache.TryGetValue(layer, out int order))
+ return order;
+
+ // 濡傛灉缂撳瓨涓病鏈夛紝浣跨敤鍘熸潵鐨勬柟娉曡绠楀苟缂撳瓨缁撴灉
+ int result;
+ switch (layer)
+ {
+ case UILayer.Static:
+ result = BASE_SORTING_ORDER;
+ break;
+ case UILayer.Bottom:
+ result = BASE_SORTING_ORDER * 10;
+ break;
+ case UILayer.Mid:
+ result = BASE_SORTING_ORDER * 100;
+ break;
+ case UILayer.Top:
+ result = BASE_SORTING_ORDER * 1000;
+ break;
+ case UILayer.System:
+ result = BASE_SORTING_ORDER * 10000;
+ break;
+ default:
+ result = BASE_SORTING_ORDER * 10;
+ break;
+ }
+
+ // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
+ layerSortingOrderCache[layer] = result;
+ return result;
+ }
+
+ // 鑾峰彇灞傜骇瀵瑰簲鐨凾ransform
+ private Transform GetTransForLayer(UILayer layer)
+ {
+ // 灏濊瘯浠庣紦瀛樹腑鑾峰彇Transform
+ if (layerTransformCache.TryGetValue(layer, out Transform trans))
+ return trans;
+
+ // 濡傛灉缂撳瓨涓病鏈夛紝浣跨敤鍘熸潵鐨勬柟娉曡幏鍙栧苟缂撳瓨缁撴灉
+ Transform result;
+ switch (layer)
+ {
+ case UILayer.Static:
+ result = staticTrans;
+ break;
+ case UILayer.Bottom:
+ result = bottomTrans;
+ break;
+ case UILayer.Mid:
+ result = midTrans;
+ break;
+ case UILayer.Top:
+ result = topTrans;
+ break;
+ case UILayer.System:
+ result = systemTrans;
+ break;
+ default:
+ result = bottomTrans;
+ break;
+ }
+
+ // 灏嗙粨鏋滃瓨鍏ョ紦瀛�
+ layerTransformCache[layer] = result;
+ return result;
+ }
+
+ // 鑾峰彇UI瀹炰緥锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
+ public T GetUI<T>() where T : UIBase
+ {
+ // 鑾峰彇UI绫诲瀷鍚嶇О
+ string uiName = typeof(T).Name;
+ if (string.IsNullOrEmpty(uiName))
+ {
+ // 璁板綍閿欒鏃ュ織
+ Debug.LogError("UI鍚嶇О涓虹┖");
+ return null;
+ }
+
+ // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
+ if (uiDict.TryGetValue(uiName, out List<UIBase> uiList) && uiList.Count > 0)
+ {
+ // 杩斿洖绗竴涓疄渚�
+ return uiList[0] as T;
+ }
+
+ // 濡傛灉涓嶅瓨鍦紝杩斿洖null
+ return null;
+ }
+
+ public List<T> GetUIList<T>() where T : UIBase
+ {
+ List<T> uiList = new List<T>();
+
+ // 鑾峰彇UI绫诲瀷鍚嶇О
+ string uiName = typeof(T).Name;
+ if (string.IsNullOrEmpty(uiName))
+ {
+ // 璁板綍閿欒鏃ュ織
+ Debug.LogError("UI鍚嶇О涓虹┖");
+ return uiList;
+ }
+
+ // 灏濊瘯浠庡瓧鍏镐腑鑾峰彇UI瀹炰緥鍒楄〃
+ List<UIBase> tempList = null;
+ uiDict.TryGetValue(uiName, out tempList);
+
+ if (tempList != null)
+ {
+ for (int i = 0; i < tempList.Count; i++)
+ {
+ UIBase ui = tempList[i];
+ if (null != ui)
+ {
+ uiList.Add(ui as T);
+ }
+ }
+ }
+
+ return uiList;
+ }
+
+ public bool IsOpenedInList<T>() where T : UIBase
+ {
+ List<T> uiList = GetUIList<T>();
+
+ foreach (T ui in uiList)
+ {
+ if (ui.IsActive())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool IsOpened<T>() where T : UIBase
+ {
+ T ui = GetUI<T>();
+
+ if (null != ui)
+ {
+ return ui.IsActive();
+ }
+
+ return false;
+ }
+
+ // 鑾峰彇鎸囧畾绫诲瀷鐨勬墍鏈塙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)
+ {
+ // 濡傛灉UI涓虹┖鎴栦笉鏀寔鐖跺瓙鍏崇郴锛岀洿鎺ヨ繑鍥�
+ if (ui == null || !ui.supportParentChildRelation)
+ return;
+
+ // 鑾峰彇鐖剁骇UI
+ UIBase parentUI = ui.parentUI;
+ // 閬嶅巻鎵�鏈夌埗绾I锛屾洿鏂板洖鍚堟暟
+ while (parentUI != null)
+ {
+ // 鏇存柊鐖剁骇UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
+ parentUI.lastUsedRound = currentRound;
+ // 缁х画鍚戜笂鏌ユ壘鐖剁骇UI
+ parentUI = parentUI.parentUI;
+ }
+ }
+
+ // 閫掑綊鏀堕泦鎵�鏈夊瓙UI
+ private void CollectChildrenUI(UIBase ui, List<UIBase> result)
+ {
+ // 濡傛灉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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+ /// </summary>
+ public void CheckAndCloseIdleUI()
+ {
+ // 濡傛灉娌℃湁UI锛岀洿鎺ヨ繑鍥�
+ if (uiDict.Count == 0 && closedUIDict.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;
+
+ if (ui.IsActive())
+ continue;
+
+ // 璁$畻UI绌洪棽鐨勫洖鍚堟暟
+ int idleRounds = currentRound - ui.lastUsedRound;
+
+ // 濡傛灉绌洪棽鍥炲悎鏁拌秴杩囨渶澶х┖闂插洖鍚堟暟锛屾坊鍔犲埌鍏抽棴鍒楄〃
+ if (idleRounds > ui.maxIdleRounds)
+ {
+ uiToClose.Add(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($"閿�姣侀暱鏃堕棿鏈娇鐢ㄧ殑UI: {ui.uiName}, 绌洪棽鍥炲悎鏁�: {currentRound - ui.lastUsedRound}");
+ // 閿�姣乁I瀵硅薄
+ GameObject.Destroy(ui.gameObject);
+ }
+ }
+
+ // // 鐢熸垚UI瀹炰緥鐨勫敮涓�鏍囪瘑
+ // private string GenerateUIInstanceID(string uiName)
+ // {
+ // // 濡傛灉璁℃暟鍣ㄤ腑涓嶅瓨鍦ㄨUI绫诲瀷锛屽垵濮嬪寲涓�0
+ // if (!uiInstanceCounter.ContainsKey(uiName))
+ // {
+ // uiInstanceCounter[uiName] = 0;
+ // }
+
+ // // 閫掑璁℃暟鍣�
+ // uiInstanceCounter[uiName]++;
+
+ // // 杩斿洖甯︽湁璁℃暟鐨勫敮涓�鏍囪瘑
+ // return $"{uiName}_{uiInstanceCounter[uiName]}";
+ // }
+
+ #endregion
+
+ #region UI璧勬簮绠$悊
+
+ private UIBase LoadUIResource(string uiName)
+ {
+ // 浠庤祫婧愮鐞嗗櫒鍔犺浇UI棰勫埗浣�
+ GameObject prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
+
+ // 妫�鏌ラ鍒朵綋鏄惁鍔犺浇鎴愬姛
+ if (prefab == null)
+ {
+ // 璁板綍閿欒鏃ュ織
+ Debug.LogError($"鍔犺浇UI棰勫埗浣撳け璐�: {uiName}");
+ return null;
+ }
+
+ // 瀹炰緥鍖朥I瀵硅薄
+ GameObject uiObject = GameObject.Instantiate(prefab);
+ // 璁剧疆瀵硅薄鍚嶇О
+ uiObject.name = uiName;
+
+ // 閫氳繃uiName鏄犲皠Type
+ Type uiType = Type.GetType(uiName);
+ if (uiType == null)
+ {
+ Debug.LogError($"鎵句笉鍒癠I绫诲瀷: {uiName}");
+ return null;
+ }
+
+ // 鑾峰彇UI鍩虹被缁勪欢
+ UIBase uiBase = uiObject.GetComponent(uiType) as UIBase;
+
+ // 妫�鏌I鍩虹被缁勪欢鏄惁瀛樺湪
+ if (uiBase == null)
+ {
+ // 璁板綍閿欒鏃ュ織
+ Debug.LogError($"UI棰勫埗浣� {uiName} 娌℃湁 UIBase 缁勪欢鎴栫被鍨嬩笉鍖归厤");
+ return null;
+ }
+
+ // 璁剧疆UI鍚嶇О
+ uiBase.uiName = uiName;
+
+ // 璁剧疆鐖惰妭鐐逛负UI鏍硅妭鐐�
+ Transform parentTrans = GetTransForLayer(uiBase.uiLayer);
+
+ uiObject.transform.SetParent(parentTrans, false);
+
+ // 璁剧疆鎺掑簭椤哄簭
+ int baseSortingOrder = GetBaseSortingOrderForLayer(uiBase.uiLayer);
+ uiBase.SetSortingOrder(baseSortingOrder);
+
+ return uiBase;
+ }
+
+ // 鍔犺浇UI棰勫埗浣�
+ private T LoadUIResource<T>(string uiName) where T : UIBase
+ {
+ return LoadUIResource(uiName) as T;
+ }
+
+ #endregion
+
+ #region UI鎺掑簭绠$悊
+
+ // 鏇存柊UI鎺掑簭椤哄簭
+ private void UpdateUISortingOrder()
+ {
+ // 閲嶇疆褰撳墠鏈�楂樻帓搴忛『搴�
+ currentHighestSortingOrder = 0;
+
+ // 閬嶅巻UI鏍堬紝璁剧疆鎺掑簭椤哄簭
+ UIBase[] uiArray = new UIBase[uiStack.Count];
+ uiStack.CopyTo(uiArray, 0);
+
+ // 鍏堟寜鐓ILayer杩涜鎺掑簭锛岀劧鍚庡啀鎸夌収鏍堥『搴忔帓搴�
+ Array.Sort(uiArray, (a, b) => {
+ // 姣旇緝UI灞傜骇
+ int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
+ if (layerCompare != 0)
+ return layerCompare;
+
+ // 鍚屽眰绾у唴锛屾寜鐓ф爤涓殑椤哄簭鎺掑簭
+ return Array.IndexOf(uiArray, a).CompareTo(Array.IndexOf(uiArray, b));
+ });
+
+ // 閬嶅巻鎺掑簭鍚庣殑UI鏁扮粍锛岃缃帓搴忛『搴�
+ foreach (var ui in uiArray)
+ {
+ // 鑾峰彇鍩虹鎺掑簭椤哄簭
+ int baseSortingOrder = GetBaseSortingOrderForLayer(ui.uiLayer);
+ // 璁$畻褰撳墠UI鐨勬帓搴忛『搴�
+ int sortingOrder = baseSortingOrder + currentHighestSortingOrder;
+ // 璁剧疆UI鐨勬帓搴忛『搴�
+ ui.SetSortingOrder(sortingOrder);
+ // 鏇存柊褰撳墠鏈�楂樻帓搴忛『搴�
+ currentHighestSortingOrder += 10;
+ }
+ }
+
+ #endregion
+
+ #region UI鎿嶄綔
+
+
+
+ private UIBase GetLastSupportParentChildRelationUI()
+ {
+ List<UIBase> tempList = new List<UIBase>();
+
+ UIBase target = null;
+
+ while (target == null && uiStack.Count > 0)
+ {
+ UIBase uiBase = uiStack.Pop();
+
+ if (uiBase != null && uiBase.supportParentChildRelation && !uiBase.isMainUI)
+ {
+ target = uiBase;
+ }
+
+ tempList.Add(uiBase);
+ }
+
+ for (int i = tempList.Count - 1; i >= 0; i--)
+ {
+ uiStack.Push(tempList[i]);
+ }
+
+ return target;
+ }
+
+ public UIBase OpenWindow(string uiName)
+ {
+ // 浼樺厛浠巆losedUIDict涓幏鍙�
+ UIBase parentUI = null;
+
+ UIBase returnValue = null;
+
+ if (closedUIDict.TryGetValue(uiName, out List<UIBase> closedUIList) && closedUIList.Count > 0)
+ {
+ returnValue = closedUIList[0] as UIBase;
+ closedUIList.RemoveAt(0);
+
+ if (closedUIList.Count == 0)
+ {
+ closedUIDict.Remove(uiName);
+ }
+ }
+ else
+ {
+ returnValue = LoadUIResource(uiName);
+ if (returnValue == null)
+ {
+ // 璁板綍閿欒鏃ュ織
+ Debug.LogError($"鎵撳紑UI澶辫触: {uiName}");
+ return null;
+ }
+ }
+
+ returnValue.gameObject.SetActive(true);
+
+ // 鑷姩璁剧疆鐖剁骇UI锛堝鏋滄湭鎸囧畾涓旀敮鎸佺埗瀛愬叧绯伙級
+ if (returnValue.supportParentChildRelation && uiStack.Count > 0)
+ {
+ // 鑾峰彇鏍堥《UI
+ parentUI = GetLastSupportParentChildRelationUI();
+ }
+
+ // 璁剧疆鐖剁骇UI
+ if (parentUI != null)
+ {
+ // 璁剧疆鐖跺瓙鍏崇郴
+ returnValue.parentUI = parentUI;
+ if (parentUI.childrenUI == null)
+ {
+ // 鍒濆鍖栫埗绾I鐨勫瓙UI鍒楄〃
+ parentUI.childrenUI = new List<UIBase>();
+ }
+ // 娣诲姞鍒扮埗绾I鐨勫瓙UI鍒楄〃
+ parentUI.childrenUI.Add(returnValue);
+ }
+
+ // 鏇存柊鍥炲悎鏁�
+ currentRound++;
+ // 璁剧疆UI鐨勬渶鍚庝娇鐢ㄥ洖鍚堟暟
+ returnValue.lastUsedRound = currentRound;
+ // 鏇存柊鐖剁骇UI鐨勫洖鍚堟暟
+ UpdateParentUIRounds(returnValue);
+
+ // 灏哢I娣诲姞鍒板瓧鍏镐腑
+ if (!uiDict.ContainsKey(uiName))
+ {
+ // 濡傛灉瀛楀吀涓笉瀛樺湪璇ョ被鍨嬬殑UI锛屽垱寤烘柊鍒楄〃
+ uiDict[uiName] = new List<UIBase>();
+ }
+ // 娣诲姞鍒癠I鍒楄〃
+ uiDict[uiName].Add(returnValue);
+
+ // 灏哢I娣诲姞鍒版爤涓�
+ uiStack.Push(returnValue);
+
+ // 鏇存柊UI鎺掑簭椤哄簭
+ UpdateUISortingOrder();
+
+ // 鎵撳紑UI
+ returnValue.HandleOpen();
+
+ OnOpenWindow?.Invoke(returnValue);
+
+ // 妫�鏌ュ苟鍏抽棴闀挎椂闂存湭浣跨敤鐨刄I
+ CheckAndCloseIdleUI();
+
+ return returnValue;
+ }
+
+ /// <summary>
+ /// 鎵撳紑UI
+ /// </summary>
+ public T OpenWindow<T>() where T : UIBase
+ {
+ // 鑾峰彇UI绫诲瀷鍚嶇О
+ string uiName = typeof(T).Name;
+ return OpenWindow(uiName) as T;
+ }
+
+ /// <summary>
+ /// 鍏抽棴UI
+ /// </summary>
+ public void CloseWindow<T>(bool destroy = false) where T : UIBase
+ {
+ // 鑾峰彇UI绫诲瀷鍚嶇О
+ string uiName = typeof(T).Name;
+
+ CloseWindow(uiName, destroy);
+
+ }
+
+ public void CloseWindow(string uiName, bool destroy = false)
+ {
+ // 妫�鏌I鏄惁瀛樺湪
+ if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
+ {
+ // 璁板綍璀﹀憡鏃ュ織
+ Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
+ return;
+ }
+
+ // 鑾峰彇绗竴涓猆I瀹炰緥
+ UIBase ui = uiDict[uiName][0];
+
+ // 鍏抽棴UI
+ CloseWindow(ui, destroy);
+ }
+
+ /// <summary>
+ /// 鍏抽棴鎸囧畾鐨刄I瀹炰緥
+ /// </summary>
+ public void CloseWindow(UIBase ui, bool destroy = false)
+ {
+ // 妫�鏌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, destroy);
+ }
+
+ // 浠庢爤涓Щ闄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());
+ }
+
+ // 浠庡瓧鍏镐腑绉婚櫎UI
+ if (uiDict.ContainsKey(uiName))
+ {
+ // 浠嶶I鍒楄〃涓Щ闄�
+ uiDict[uiName].Remove(ui);
+ // 濡傛灉鍒楄〃涓虹┖锛屼粠瀛楀吀涓Щ闄よ绫诲瀷
+ if (uiDict[uiName].Count == 0)
+ {
+ uiDict.Remove(uiName);
+ }
+ }
+
+ // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
+ if (ui.supportParentChildRelation && ui.parentUI != null && ui.parentUI.childrenUI != null)
+ {
+ // 浠庣埗绾I鐨勫瓙UI鍒楄〃涓Щ闄�
+ ui.parentUI.childrenUI.Remove(ui);
+ }
+
+ // 鍏抽棴UI
+ ui.HandleClose();
+ OnCloseWindow?.Invoke(ui);
+
+ 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();
+ }
+
+ /// <summary>
+ /// 鍏抽棴鎸囧畾绫诲瀷鐨勬墍鏈塙I瀹炰緥
+ /// </summary>
+ public void CloseAllWindows<T>() where T : UIBase
+ {
+ // 鑾峰彇UI绫诲瀷鍚嶇О
+ string uiName = typeof(T).Name;
+
+ // 妫�鏌I鏄惁瀛樺湪
+ if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
+ {
+ // 璁板綍璀﹀憡鏃ュ織
+ Debug.LogWarning($"灏濊瘯鍏抽棴涓嶅瓨鍦ㄧ殑UI: {uiName}");
+ return;
+ }
+
+ // 鍒涘缓UI瀹炰緥鍒楄〃鐨勫壇鏈紝鍥犱负鍦ㄥ叧闂繃绋嬩腑浼氫慨鏀瑰師鍒楄〃
+ List<UIBase> uiListCopy = new List<UIBase>(uiDict[uiName]);
+
+ // 鍏抽棴鎵�鏈塙I瀹炰緥
+ foreach (var ui in uiListCopy)
+ {
+ // 鍏抽棴UI瀹炰緥
+ CloseWindow(ui, false);
+ }
+ }
+
+ /// <summary>
+ /// 鍏抽棴鎵�鏈塙I
+ /// </summary>
+ public void DestroyAllUI()
+ {
+ // 鍒涘缓UI鏍堢殑鍓湰锛屽洜涓哄湪鍏抽棴杩囩▼涓細淇敼鍘熸爤
+ UIBase[] uiArray = new UIBase[uiStack.Count];
+ uiStack.CopyTo(uiArray, 0);
+
+ // 鍏抽棴鎵�鏈塙I
+ foreach (var ui in uiArray)
+ {
+ // 鍏抽棴UI
+ CloseWindow(ui, true);
+ }
+
+ // 娓呯┖UI瀛楀吀鍜屾爤
+ uiDict.Clear();
+ uiStack.Clear();
+ closedUIDict.Clear();
+ }
+
+ /// <summary>
+ /// 鍒锋柊UI
+ /// </summary>
+ public void RefreshUI<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瀹炰緥
+ 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)
+ {
+ // 鍒锋柊UI
+ ui.Refresh();
+ }
+ }
+ }
+
+ private void Update()
+ {
+ // 濡傛灉璺濈涓婃妫�鏌ョ殑鏃堕棿瓒呰繃浜嗘鏌ラ棿闅�
+ if (Time.time - lastCheckTime > CHECK_INTERVAL)
+ {
+ // 鏇存柊涓婃妫�鏌ユ椂闂�
+ 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