| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System.Linq; |
| | | using DG.Tweening; |
| | | |
| | | /// <summary> |
| | | /// UI管理器 - 负责管理所有UI界面的显示、隐藏和层级 |
| | |
| | | private Transform loadingTrans; |
| | | |
| | | // UI字典,存储所有已加载的UI,键为UI名称,值为UI实例 |
| | | private Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | | #if UNITY_EDITOR |
| | | public |
| | | #else |
| | | private |
| | | #endif |
| | | Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | | // 存储关闭但未销毁的UI,键为UI名称,值为UI实例 |
| | | private Dictionary<string, List<UIBase>> closedUIDict = new Dictionary<string, List<UIBase>>(); |
| | | |
| | |
| | | #endregion |
| | | |
| | | #region 初始化 |
| | | |
| | | |
| | | /// <summary> |
| | | /// 初始化UI管理器 |
| | | /// </summary> |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | |
| | | |
| | | // 初始化UI根节点 |
| | | InitUIRoot(); |
| | | |
| | | |
| | | // 初始化缓存 |
| | | layerSortingOrderCache.Clear(); |
| | | layerTransformCache.Clear(); |
| | | uiInstanceCounter.Clear(); |
| | | |
| | | |
| | | DOTween.SetTweensCapacity(500, 50); |
| | | Debug.Log("UI管理器初始化完成"); |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | // 返回第一个实例 |
| | | return uiList[0] as T; |
| | | } |
| | | |
| | | // 如果不存在,返回null |
| | | return null; |
| | | } |
| | | |
| | | public UIBase GetUI(string uiName) |
| | | { |
| | | if (string.IsNullOrEmpty(uiName)) |
| | | { |
| | | // 记录错误日志 |
| | | Debug.LogError("UI名称为空"); |
| | | return null; |
| | | } |
| | | |
| | | // 尝试从字典中获取UI实例列表 |
| | | if (uiDict.TryGetValue(uiName, out List<UIBase> uiList) && uiList.Count > 0) |
| | | { |
| | | // 返回第一个实例 |
| | | return uiList[0]; |
| | | } |
| | | |
| | | // 如果不存在,返回null |
| | |
| | | foreach (var ui in uiToClose) |
| | | { |
| | | // 记录日志 |
| | | #if UNITY_EDITOR |
| | | Debug.Log($"销毁长时间未使用的UI: {ui.uiName}, 空闲回合数: {currentRound - ui.lastUsedRound}"); |
| | | #endif |
| | | // 销毁UI对象 |
| | | GameObject.Destroy(ui.gameObject); |
| | | } |
| | |
| | | ui.SetSortingOrder(sortingOrder); |
| | | // 更新当前最高排序顺序 |
| | | currentHighestSortingOrder += 10; |
| | | |
| | | // Debug.Log(ui.uiName + " order is " + sortingOrder + " " + currentHighestSortingOrder); |
| | | } |
| | | } |
| | | |
| | |
| | | return target; |
| | | } |
| | | |
| | | public UIBase OpenWindow(string uiName) |
| | | public UIBase OpenWindow(string uiName, int functionOrder = 0) |
| | | { |
| | | // 优先从closedUIDict中获取 |
| | | UIBase parentUI = null; |
| | | |
| | | UIBase returnValue = null; |
| | | |
| | | Debug.Log("OpenWindow " + uiName); |
| | | |
| | | 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); |
| | |
| | | } |
| | | else |
| | | { |
| | | #if UNITY_EDITOR |
| | | Debug.Log("OpenWindow getNewLoad " + uiName); |
| | | #endif |
| | | returnValue = LoadUIResource(uiName); |
| | | if (returnValue == null) |
| | | { |
| | |
| | | UpdateUISortingOrder(); |
| | | |
| | | // 打开UI |
| | | returnValue.functionOrder = functionOrder; |
| | | returnValue.HandleOpen(); |
| | | |
| | | OnOpenWindow?.Invoke(returnValue); |
| | |
| | | /// <summary> |
| | | /// 打开UI |
| | | /// </summary> |
| | | public T OpenWindow<T>() where T : UIBase |
| | | public T OpenWindow<T>(int functionOrder = 0) where T : UIBase |
| | | { |
| | | // 获取UI类型名称 |
| | | string uiName = typeof(T).Name; |
| | | return OpenWindow(uiName) as T; |
| | | return OpenWindow(uiName, functionOrder) as T; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | // 获取UI类型名称 |
| | | string uiName = ui.uiName; |
| | | |
| | | #if UNITY_EDITOR |
| | | Debug.Log("CloseWindow " + uiName + " destroy : " + destroy.ToString()); |
| | | #endif |
| | | |
| | | // 收集所有子UI |
| | | List<UIBase> childrenUI = new List<UIBase>(); |
| | |
| | | // 关闭UI |
| | | ui.HandleClose(); |
| | | OnCloseWindow?.Invoke(ui); |
| | | |
| | | |
| | | if (destroy) |
| | | { |
| | | // 销毁UI对象 |
| | |
| | | closedUIDict[uiName] = new List<UIBase>(); |
| | | } |
| | | closedUIDict[uiName].Add(ui); |
| | | |
| | | |
| | | #if UNITY_EDITOR |
| | | Debug.Log("CloseWindow " + uiName + " destroy : " + destroy.ToString() + " push to closedUIDict"); |
| | | #endif |
| | | |
| | | // 隐藏UI (交给handle close内部自己去做) |
| | | // ui.gameObject.SetActive(false); |