lcy
2025-11-06 09bc892c7283df8757a07b646d5af21ddaa263d1
Main/Manager/UIManager.cs
@@ -50,7 +50,7 @@
    private int currentRound = 0;
    
    // 缓存层级对应的排序顺序
    private Dictionary<UILayer, int> layerSortingOrderCache = new Dictionary<UILayer, int>();
    private static Dictionary<UILayer, int> layerSortingOrderCache = new Dictionary<UILayer, int>();
    
    // 缓存层级对应的Transform
    private Dictionary<UILayer, Transform> layerTransformCache = new Dictionary<UILayer, Transform>();
@@ -131,17 +131,22 @@
        layerTransformCache.Add(UILayer.Loading, loadingTrans);
    }
    
    public Transform GetUIRoot()
    {
        return uiRoot;
    }
    #endregion
    #region 辅助方法
    // 获取UI层级对应的基础排序顺序
    private int GetBaseSortingOrderForLayer(UILayer layer)
    public static int GetBaseSortingOrderForLayer(UILayer layer)
    {
        // 尝试从缓存中获取排序顺序
        if (layerSortingOrderCache.TryGetValue(layer, out int order))
            return order;
        // 如果缓存中没有,使用原来的方法计算并缓存结果
        int result;
        switch (layer)
@@ -156,23 +161,23 @@
                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;
                break;
        }
        // 将结果存入缓存
        layerSortingOrderCache[layer] = result;
        return result;
    }
    // 获取层级对应的Transform
    private Transform GetTransForLayer(UILayer layer)
    public Transform GetTransForLayer(UILayer layer)
    {
        // 尝试从缓存中获取Transform
        if (layerTransformCache.TryGetValue(layer, out Transform trans))
@@ -308,6 +313,72 @@
        return false;
    }
    public bool IsOpened(string uiName)
    {
        UIBase ui = GetUI(uiName);
        if (null != ui)
        {
            return ui.IsActive();
        }
        return false;
    }
    // 检查是否存在任何全屏或遮罩窗口, 有screenMask 即可代表全屏
    public bool ExistAnyFullScreenOrMaskWin(string excludeUIName)
    {
        var exist = false;
        foreach (var uiList in uiDict.Values)
        {
            // 遍历该类型的所有UI实例
            foreach (var ui in uiList)
            {
                // 刷新UI
                if (ui.IsActive() && ui.name != excludeUIName)
                {
                    if (ui.screenMask != null)
                    {
                        exist = true;
                        break;
                    }
                }
            }
        }
        return exist;
    }
    //在此界面上有没任何全屏或遮罩窗口
    public bool ExistAnyFullScreenOrMaskWinAbove(string uiName)
    {
        var ui = GetUI(uiName);
        if (ui == null || !ui.IsActive())
        {
            // 如果UI不存在或未打开,默认为有被挡住
            return true;
        }
        foreach (var uiBase in uiStack)
        {
            if (uiBase == null)
            {
                continue;
            }
            if (uiBase.name == uiName)
            {
                break;
            }
            if (uiBase.IsActive() && uiBase.screenMask != null)
            {
                return true;
            }
        }
        return false;
    }
    
    // 获取指定类型的所有UI实例
    public List<T> GetAllUI<T>() where T : UIBase
@@ -481,8 +552,17 @@
    private UIBase LoadUIResource(string uiName)
    {
        // 从资源管理器加载UI预制体
        GameObject prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
        GameObject prefab;
        if (uiName == "LaunchWin" || uiName == "DownLoadWin" || uiName == "RequestSecretWin" || uiName == "GameAgeWarnWin")
        {
            prefab = BuiltInLoader.LoadPrefab(uiName);
        }
        else
        {
            prefab = ResManager.Instance.LoadAsset<GameObject>("UI", uiName);
        }
        // 检查预制体是否加载成功
        if (prefab == null)
@@ -552,14 +632,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数组,设置排序顺序
@@ -572,7 +657,7 @@
            // 设置UI的排序顺序
            ui.SetSortingOrder(sortingOrder);
            // 更新当前最高排序顺序
            currentHighestSortingOrder += 10;
            currentHighestSortingOrder += ui.uiLayer == UILayer.Static ? 155/*这里是角色+特效之上的层级*/ : 10;
            // Debug.Log(ui.uiName + " order is " + sortingOrder + " " + currentHighestSortingOrder);
        }
@@ -586,28 +671,16 @@
    private UIBase GetLastSupportParentChildRelationUI()
    {
        List<UIBase> tempList = new List<UIBase>();
        UIBase target = null;
        while (target == null && uiStack.Count > 0)
        foreach (var uiBase in uiStack)
        {
            UIBase uiBase = uiStack.Pop();
            if (uiBase != null && uiBase.supportParentChildRelation && !uiBase.isMainUI)
            if (uiBase != null && uiBase.supportParentChildRelation)
            {
                target = uiBase;
                return uiBase;
            }
            tempList.Add(uiBase);
        }
        for (int i = tempList.Count - 1; i >= 0; i--)
        {
            uiStack.Push(tempList[i]);
        }
        return target;
        return null;
    }
    public UIBase OpenWindow(string uiName, int functionOrder = 0)
@@ -649,8 +722,8 @@
        
        returnValue.gameObject.SetActive(true);
        
        // 自动设置父级UI(如果未指定且支持父子关系)
        if (returnValue.supportParentChildRelation && uiStack.Count > 0)
        // 自动设置父级UI, 如果勾选了ismainui 则不需要找父级UI
        if (returnValue.supportParentChildRelation && uiStack.Count > 0 && !returnValue.isMainUI)
        {
            // 获取栈顶UI
            parentUI = GetLastSupportParentChildRelationUI();
@@ -685,7 +758,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);
        
@@ -792,6 +872,10 @@
            {
                tempStack.Push(tempUI);
            }
            else
            {
                break;
            }
        }
        
        // 将临时栈中的UI重新压入栈中
@@ -876,19 +960,6 @@
        }
    }
    public void ReturnMainUI()
    {
        List<UIBase> allUI = new List<UIBase>(uiStack);
        for (int i = 0; i < allUI.Count; i++)
        {
            UIBase uiBase = allUI[i];
            if (!uiBase.isMainUI && uiBase.uiLayer < UILayer.System)
            {
                CloseWindow(uiBase);
            }
        }
    }
    
    /// <summary>
    /// 关闭所有UI