hch
2025-09-15 5119041cf7042a6681c4df44437b282472733d77
Main/Manager/UIManager.cs
@@ -30,8 +30,13 @@
    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>>();
@@ -151,10 +156,10 @@
                result = BASE_SORTING_ORDER * 1000;
                break;
            case UILayer.System:
                result = BASE_SORTING_ORDER * 10000;
                result = BASE_SORTING_ORDER * 2000;
                break;
            case UILayer.Loading:
                result = BASE_SORTING_ORDER * 100000;
                result = BASE_SORTING_ORDER * 3000;
                break;
            default:
                result = BASE_SORTING_ORDER * 10;
@@ -446,7 +451,9 @@
        foreach (var ui in uiToClose)
        {
            // 记录日志
#if UNITY_EDITOR
            Debug.Log($"销毁长时间未使用的UI: {ui.uiName}, 空闲回合数: {currentRound - ui.lastUsedRound}");
#endif
            // 销毁UI对象
            GameObject.Destroy(ui.gameObject);
        }
@@ -474,8 +481,17 @@
    private UIBase LoadUIResource(string uiName)
    {
        // 从资源管理器加载UI预制体
        GameObject prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
        GameObject prefab;
        if (uiName == "LaunchWin")
        {
            prefab = BuiltInLoader.LoadPrefab(uiName);
        }
        else
        {
            prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
        }
        // 检查预制体是否加载成功
        if (prefab == null)
@@ -545,14 +561,19 @@
        uiStack.CopyTo(uiArray, 0);
        
        // 先按照UILayer进行排序,然后再按照栈顺序排序
        Array.Sort(uiArray, (a, b) => {
            // 比较UI层级
        Dictionary<UIBase, int> uiOrderDict = new Dictionary<UIBase, int>();
        for (int i = 0; i < uiArray.Length; i++)
        {
            uiOrderDict[uiArray[i]] = i;
        }
        Array.Sort(uiArray, (a, b) =>
        {
            int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
            if (layerCompare != 0)
                return layerCompare;
            // 同层级内,按照栈中的顺序排序
            return Array.IndexOf(uiArray, b).CompareTo(Array.IndexOf(uiArray, a));
            return uiOrderDict[b].CompareTo(uiOrderDict[a]);
        });
        
        // 遍历排序后的UI数组,设置排序顺序
@@ -614,7 +635,9 @@
        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);
@@ -626,7 +649,9 @@
        }
        else
        {
            #if UNITY_EDITOR
            Debug.Log("OpenWindow getNewLoad " + uiName);
            #endif
            returnValue = LoadUIResource(uiName);
            if (returnValue == null)
            {
@@ -674,7 +699,14 @@
        }
        // 添加到UI列表
        uiDict[uiName].Add(returnValue);
#if UNITY_EDITOR
        if (uiDict[uiName].Count > 5)
        {
            Debug.LogError("已打开" + uiDict[uiName].Count + "个界面:" + uiName);
        }
#endif
        // 将UI添加到栈中
        uiStack.Push(returnValue);
        
@@ -752,8 +784,9 @@
        
        // 获取UI类型名称
        string uiName = ui.uiName;
#if UNITY_EDITOR
        Debug.Log("CloseWindow " + uiName + " destroy : " + destroy.ToString());
#endif
        // 收集所有子UI
        List<UIBase> childrenUI = new List<UIBase>();
@@ -810,7 +843,7 @@
        // 关闭UI
        ui.HandleClose();
        OnCloseWindow?.Invoke(ui);
        if (destroy)
        {
            // 销毁UI对象
@@ -824,8 +857,10 @@
                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);