您当前的位置: 首页 >  ui

Peter_Gao_

暂无认证

  • 1浏览

    0关注

    621博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

UGUI的UGUI渲染层级层深(layer)问题

Peter_Gao_ 发布时间:2020-06-18 18:27:42 ,浏览量:1

遵循原则:刷油漆

Unity中的渲染顺序自上而下大致分为三层。 分别是Camera - > Sorting Layer - > Sorting order 最高层为Camera层,可以在Camera的depth那里设置,设置之后,图形的渲染顺序就是先绘制depth低的相机下的物体, 再绘制depth高的相机下的物体,也就是说,depth高的相机会覆盖depth低的相机(具体的覆盖关系有don't clear, solid color等等几种)

UGUI渲染模式:Canvas -- Render Mode:ScreenSpace-Overlay

此模式下不依赖摄像机Camera的渲染

Hierachy下存在各层级遮挡,

 

  • 不同Camera的Depth。(大在前,小在后)
  • 同Camera的SortingLayer。(下在前,上在后)
  • 同SortingLayer下的Order in Layer。(大在前,小在后)
  • 同Order in Layer下的Z轴。(小在前,大在后)

改变控件之间的层级关系 同一canvas下:      改变控件transform的SiblingIndex,      transform.GetSiblingIndex();      transform.SetSiblingIndex(int index); //index值越大,越后渲染,层级越大,越显示在前面

不同Canvas下:     设置Canvas下的Sort Order //Sort Order值越大,越后渲染,层级越大,越显示在前面 渲染顺序与hierarchy面板里物体的摆放顺序也有关 面板里越靠上的物体越先被渲染,越后被渲染的显示在越前面。

注意:

如果是多个Canvas的渲染先后顺序 http://blog.csdn.net/huutu/article/details/43636241 调Canvas下面有一个Sort Order值,默认为0,越大越在后面。   创建任意UGUI元素时自动生成一个Canvas物体,Canvas下的所有物体从上往下渲染,即排在下面的会遮盖排上面的。同理,子元素会覆盖父元素。

在游戏运行中如何修改UGUI的显示层级? 在代码中调整该元素的层级位:使用RectTransform类的函数。

  •    SetAsFirstSibling:移动到所有兄弟节点的第一个位置(Hierarchy同级最上面,先渲染,显示在最下面)
  •    SetAsLastSibling:移动到所有兄弟节点的最后一个位置(Hierarchy同级最下面,后渲染,显示在最上面)
  •    GetSiblingIndex:获得该元素在当前兄弟节点层级的位置
  •    SetSiblingIndex:设置该元素在当前兄弟节点层级的位置

Canvas的渲染模式【Render Mode】:ScreenSpace Overlay,ScreenSpace Camera,World Space ScreenSpace-Overlay:

  • OverLay模式,永远覆盖在其他物体之上。出现在最上面。不受摄像机的Depth值影响
  • 有多个摄像机时,由摄像机的Depth值决定
  • 只有一个摄像机时,由距离和方向决定World模式和Camera模式、它们的渲染结果 可前、可后、可穿插。ScreenSpace-Camera:

1.遵循刷油漆规则 2.依次由Render Camera的Depth值、Sorting  Layer先后顺序、Order in Layer值决定  Render Camera不同时,由Render Camera的Depth决定 Render Camera相同时,由Sorting Layer先后顺序决定 Render Camera相同时,Sorting Layer相同,由Order in 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 _DicUIFormSortLayerCount;

       //初始化核心数据,加载"UI窗体路径"到集合中         private void Awake()         {             //字段初始化             _DicUIFormSortLayerCount = new Dictionary             {                { "SelectTipsUI",40 },                 {"DiceUI",20 },                 { "GetItemBoxUI",20},                 { "MissionTipsUI",20},                 { "RandomEventUI",20},                 { "RandomShopUI",20},                 { "ShopGoodsInfoUI",25}             };             _DicAllUIForms = new Dictionary();             _DicCurrentShowUIForms = new Dictionary();             _DicFormsPaths = new Dictionary();             _StaCurrentUIForms = new Stack();             _StaChildUIForm = new Stack();

            //初始化加载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().sortingOrder = UIManager._DicUIFormSortLayerCount[name];             }         }

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

   public class UIMaskManager : MonoBehaviour     {

 /// 设置遮罩状态         ///         /// 需要显示的UI窗体         ///         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();             _objMaskPanel.GetOrAddComponent();             //顶层窗体下移             _objTopPanel.transform.SetAsLastSibling();

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

 

 

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

关注
打赏
1664521772
查看更多评论
立即登录/注册

微信扫码登录

0.0542s