yyl
2026-03-26 1ab047b5fdd933c38ba0519ec2e83a44512ea8d7
Main/Manager/UIManager.cs
@@ -5,6 +5,7 @@
using System.Linq;
using DG.Tweening;
using Cysharp.Threading.Tasks;
using UnityEngine.EventSystems;
/// <summary>
/// UI管理器 - 负责管理所有UI界面的显示、隐藏和层级
@@ -105,8 +106,10 @@
                Debug.LogError("无法找到UI根节点");
                return;
            }
            GameObject.DontDestroyOnLoad(root);
        }
        // 无论是从场景找到还是新实例化的,都确保跨场景不被销毁
        GameObject.DontDestroyOnLoad(root);
        uiRoot = root.transform;
        uiRoot.position = Vector3.zero;
@@ -123,6 +126,8 @@
        layerTransformCache.Add(UILayer.Mid, midTrans);
        layerTransformCache.Add(UILayer.System, systemTrans);
        layerTransformCache.Add(UILayer.Loading, loadingTrans);
        LogUIRootEventSystemState("InitUIRoot");
    }
    
    public Transform GetUIRoot()
@@ -632,8 +637,10 @@
                Debug.LogError("无法加载UI根节点");
                return;
            }
            GameObject.DontDestroyOnLoad(root);
        }
        // 无论是从场景找到还是新实例化的,都确保跨场景不被销毁
        GameObject.DontDestroyOnLoad(root);
    }
    /// <summary>
@@ -806,6 +813,48 @@
        }
    }
    public void DumpUIDiagnostics(string context)
    {
        var eventSystem = EventSystem.current;
        Debug.Log($"[UIManager][Diag] {context} EventSystem={(eventSystem != null ? eventSystem.name : "<null>")} selected={(eventSystem != null && eventSystem.currentSelectedGameObject != null ? eventSystem.currentSelectedGameObject.name : "<null>")} loadingIndicatorActive={(_loadingIndicatorGO != null && _loadingIndicatorGO.activeSelf)} loadingRefCount={_loadingRefCount} uiStackCount={uiStack.Count}");
        LogUIRootEventSystemState(context);
        var uiArray = new UIBase[uiStack.Count];
        uiStack.CopyTo(uiArray, 0);
        foreach (var ui in uiArray)
        {
            if (ui == null)
            {
                continue;
            }
            var uiCanvas = ui.GetComponent<Canvas>();
            var uiCanvasGroup = ui.GetComponent<CanvasGroup>();
            Debug.Log($"[UIManager][Diag] {context} ui={ui.GetType().Name} active={ui.gameObject.activeInHierarchy} layer={ui.uiLayer} sortingOrder={(uiCanvas != null ? uiCanvas.sortingOrder : -1)} siblingIndex={ui.transform.GetSiblingIndex()} canvasGroup.blocksRaycasts={(uiCanvasGroup != null ? uiCanvasGroup.blocksRaycasts : false)} canvasGroup.interactable={(uiCanvasGroup != null ? uiCanvasGroup.interactable : false)}");
        }
    }
    private void LogUIRootEventSystemState(string context)
    {
        if (uiRoot == null)
        {
            Debug.Log($"[UIManager][Diag] {context} uiRoot=<null>");
            return;
        }
        var eventSystemTransform = uiRoot.Find("EventSystem");
        if (eventSystemTransform == null)
        {
            Debug.Log($"[UIManager][Diag] {context} uiRoot.EventSystem child=<null>");
            return;
        }
        var eventSystemComponent = eventSystemTransform.GetComponent<EventSystem>();
        var standaloneInputModule = eventSystemTransform.GetComponent<StandaloneInputModule>();
        var baseInputModule = eventSystemTransform.GetComponent<BaseInputModule>();
        Debug.Log($"[UIManager][Diag] {context} uiRoot.EventSystem childExists=true activeSelf={eventSystemTransform.gameObject.activeSelf} activeInHierarchy={eventSystemTransform.gameObject.activeInHierarchy} eventSystemComponent={(eventSystemComponent != null)} standaloneInputModule={(standaloneInputModule != null)} baseInputModuleType={(baseInputModule != null ? baseInputModule.GetType().Name : "<null>")} currentMatchesChild={(EventSystem.current == eventSystemComponent)}");
    }
    private void EnsureLoadingIndicator()
    {
        if (_loadingIndicatorGO != null) return;
@@ -865,6 +914,10 @@
        // 遍历UI栈,设置排序顺序
        UIBase[] uiArray = new UIBase[uiStack.Count];
        uiStack.CopyTo(uiArray, 0);
        // WebGL/IL2CPP 下被 Destroy 的对象访问任何属性都会 NullReferenceException,
        // 必须在使用前过滤掉(Unity 伪 null:C# 引用非 null 但 == null 为 true)
        uiArray = System.Array.FindAll(uiArray, ui => ui != null);
        
        // 先按照UILayer进行排序,然后再按照栈顺序排序
        Dictionary<UIBase, int> uiOrderDict = new Dictionary<UIBase, int>();
@@ -875,6 +928,7 @@
        Array.Sort(uiArray, (a, b) =>
        {
            if (a == null || b == null) return 0;
            int layerCompare = a.uiLayer.CompareTo(b.uiLayer);
            if (layerCompare != 0)
                return layerCompare;
@@ -885,6 +939,7 @@
        // 遍历排序后的UI数组,设置排序顺序
        foreach (var ui in uiArray)
        {
            if (ui == null) continue;
            // 获取基础排序顺序
            int baseSortingOrder = GetBaseSortingOrderForLayer(ui.uiLayer);
            // 计算当前UI的排序顺序