UGUI的層級層深(layer)問題

使用UGUI時,經常需要設置UI上的層級。

1.先來說說我們的問題:由於unity渲染物體時是從上到下直接渲染的,這就導致了渲染出來的效果和我們預期的不一致,因此必須設置層級,指定渲染的先後順序(層級低的先渲染)纔行。


這裏寫圖片描述
這裏寫圖片描述

那麼問題來了,UGUII並沒有NGUI這麼方便的提供設置層級的入口。
2.我們必須給UI添加一個組件(Canvas)來設置UI層級

但是坑爹的是:設置完後,層級的問題解決了,但是UI的所有事件被攔截(包括按鈕的點擊、UI拖拽等等)

3.終極解決方案:給UI再設置一個組件Graphic Raycster,完美解決,既可以顯示特效,還不會遮擋UI。


至此有個問題,如果界面很多都需要設置上述的canvas,那就需要自己實現一個管理類,給每個ui設置它的order,不過canvas會影響合併批次,所以不能有太多,自己權衡。

 

     public class UIManager : MonoBehaviour
    {

        /// 窗口的排序層集合
        public static Dictionary<string, int> _DicUIFormSortLayerCount;

       //初始化核心數據,加載"UI窗體路徑"到集合中
        private void Awake()
        {
            //字段初始化
            _DicUIFormSortLayerCount = new Dictionary<string, int>
            {
                { "SelectTipsUI",40 },
                {"DiceUI",20 },
                { "GetItemBoxUI",20},
                { "MissionTipsUI",20},
                { "RandomEventUI",20},
                { "RandomShopUI",20},
                { "ShopGoodsInfoUI",25}

            };
            _DicAllUIForms = new Dictionary<string, BaseUIForm>();
            _DicCurrentShowUIForms = new Dictionary<string, BaseUIForm>();
            _DicFormsPaths = new Dictionary<string, string>();
            _StaCurrentUIForms = new Stack<BaseUIForm>();
            _StaChildUIForm = new Stack<BaseUIForm>();

            //初始化加載Canvas根預設
            InitRootCanvasLoading();

            //得到UI根節點、全屏節點、固定節點、彈出節點
            _TraCanvasTransform = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS).transform;
            _TraNormal = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_NORMAL_NODE);
            _TraFixed = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_FIXED_NODE);
            _TraPopUp = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_POPUP_NODE);
            _TraGuide = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_GUIDE_NODE);
            _TraUIScripts = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_SCRIPTMANAGER_NODE);
            _TraSavePrefab =       UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject,SysDefine.SYS_SAVEPREFAB_NODE);
 

}

========================================================================= 

    /// 基礎UI窗體
    public class BaseUIForm : MonoBehaviour
    {

        /// 重置層序
        public void ResetCanvasSortLayer()
        {
            if (UIManager._DicUIFormSortLayerCount.ContainsKey(name))
            {
                this.GetComponent<Canvas>().sortingOrder = UIManager._DicUIFormSortLayerCount[name];
            }
        }

========================================================================== 

   public class UIMaskManager : MonoBehaviour
    {

 /// 設置遮罩狀態
        /// </summary>
        /// <param name="objDisplay">需要顯示的UI窗體</param>
        /// <param name="LucenyType"></param>
        public void SetMaskWindow(GameObject objDisplay,UIFormLucenyType LucenyType = UIFormLucenyType.Lucency)
        {
            if (LucenyType == UIFormLucenyType.DnotMask)
            {
                //顯示窗體下移
                objDisplay.transform.SetAsLastSibling();
                //增加當前UI攝像機的層深(保證當前相機爲最前顯示)
                if (_UICamera != null)
                {
                    _UICamera.depth = _UICamera.depth + 100;
                }
                return;
            }
            Canvas _MaskCanvas = _objMaskPanel.GetOrAddComponent<Canvas>();
            _objMaskPanel.GetOrAddComponent<GraphicRaycaster>();
            //頂層窗體下移
            _objTopPanel.transform.SetAsLastSibling();

            if (UIManager._DicUIFormSortLayerCount.ContainsKey(objDisplay.name))
            {
                objDisplay.GetComponent<Canvas>().sortingOrder = UIManager._DicUIFormSortLayerCount[objDisplay.name]+2;
                _MaskCanvas = _objMaskPanel.GetComponent<Canvas>();
                _MaskCanvas.overrideSorting = true;
                _MaskCanvas.enabled = true;
                _MaskCanvas.sortingOrder = objDisplay.GetComponent<Canvas>().sortingOrder - 1;
            }
            else
            {
                if (_MaskCanvas != null)
                {
                    Destroy(_objMaskPanel.GetComponent<GraphicRaycaster>());
                    Destroy(_MaskCanvas);
                }
            }
}

 

 

引用:https://blog.csdn.net/qq_34937637/article/details/81066890

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章