【Unity】UGUI中Camera Depth,Canvas Sorting Layer、Order in Layer与Particle System渲染层级分析

目录

 

前言

一、项目需求

二、Camera

1.Clear Flags

2.Culling Mask

 三、Canvas

1.Sorting Layer

2.Order in Layer

四、Particle System

1.Sorting LayerID 与Order in Layer

总结


前言

        最近在做项目的过程中,发现项目中的部分3d模型会被粒子特效所遮挡,这并不是笔者想要的效果,于是经过一番面向百度编程,了解到了一些解决方案,本篇博客就记录一下所学到的新知识,如果有错误之处,还望各位读者朋友指正。


一、项目需求

        最近在做项目的过程中,发现项目中的部分3d模型会被粒子特效所遮挡,这并不是笔者想要的效果,于是经过一番面向百度编程,了解到了一些解决方案,本篇博客就记录一下所学到的新知识,如果有错误之处,还望各位读者朋友指正。

        这样的需求看起来非常绕,我们直接通过下图进行直观理解:

      

        通过该图我们就可以发现,要实现这样的需求就要求我们需要提前做好渲染层级的规划,避免层级间的相互影响。我们主要会通过设置Camera的Clear Flags、Culling Mask、Depth和Canvas的Sorting Layer、Order in Layer,以及Particle System中Renderer的Sorting Layer ID、Order in Layer进行处理。

        我们可以通过以3d模型为中点将上面的需求分为3个部分进行处理,第一部分是背景、UI、粒子特效、UI,第二部分则是3d模型,第三部分是UI、粒子特效、UI。

二、Camera

1.Clear Flags

        在一般的3d游戏中,我们通常会为场景和UI分别设置不同的摄像机,分别用来显示场景与UI。这里我们将场景摄像机用来显示3D模型,首先我们将其Clear Flags设置为Depth only,之后我们新建一个Camera,命名为UICamera0,同样将其Clear Flags设置为Depth only。

        场景摄像机:

        UICamera0:

        此处Camera的Depth越大,该摄像机渲染的画面会显示在越上层,会将Depth比它小的摄像机的渲染画面覆盖。。

2.Culling Mask

        Culling Mask设置的目的是可以使摄像机只渲染选中的Layer对象层。这里我们添加一个Canvas,命名为Canvas0,并向其中添加Image,命名为Background,做为最底层背景图。将Canvas0的Render Mode设置为Screen Space-Camera,并将UICamera0赋给Render Camera。注意此时UICamera0的Projection应设置为Orthographic(正交模式),避免近大远小的现象。

        之后,我们通过添加不同的Layer来让不同的Camera渲染相应的对象层。此处我们使用默认的UI Layer来处理第一部分的背景、UI、粒子特效、UI,添加Model Layer来处理3d模型,添加UI1 Layer来处理第三部分的UI、粒子特效、UI。如下图添加两个Layer:

        

 扩展:下图是默认Layer层的描述

注意:Unity编辑器的预览窗口机制在内部使用了第31层Layer,为了防止冲突,不用使用这一层!

        之后将Main Camera的Culling Mask设置为Model,让其只渲染3d模型,将UICamera0的Culling Mask设置为UI,让其只渲染第一部分的背景、UI、粒子特效、UI。

        

  

        此时,Game窗口显示如下: 

        我们发现,3d模型被Background Image遮挡,这是因为我们还没有设置两个摄像机的Depth,UICamera0(创建时默认为0)的深度大于MainCamera的深度(创建时默认为-1),因此背景会覆盖在3d模型上方,将UICamera0的Depth设置为0,MainCamera设置为1,这样显示就为3d模型在Background Image上层了,如下图:

扩展:例如在FPS游戏中,如果要绘制玩家的枪支而不使其陷入环境中,可以设置一个Depth为0的摄像机来绘制环境,并设置另一个Depth为1的摄像机来单独绘制武器,将武器的Layer设置为一个单独Weapon层,将武器摄像机的Clear Flags设置为Depth Only,Culling Mask设置为只渲染Weapon对象层。这样将在屏幕上保持环境的图形显示,但丢弃相关对象在3d空间中所处位置的所有信息。绘制枪支时,不透明部分将完全覆盖所绘制的任何对象(不论枪支与墙壁的接近程度如何)。

 三、Canvas

1.Sorting Layer

        Sorting Layer的作用主要用于改变Canvas的渲染顺序,在Hierarchy中创建的Canvas,Unity默认自上而下渲染,位置越靠后的Canvas将渲染在靠前位置的Canvas之上,但有时我们需要让位置后靠后的Canvas先进行渲染或者让位置靠前的Canvas后渲染,此时就要用到Sorting Layer。

        我们在Canvas0中添加一个UI0_0和UI0_1的Image,如下图:

        

        此时,我们可以看到UI0_0覆盖住了UI0_1的大部分画面:        

        我们可以通过设置Sorting Layer来解决。添加如下Sorting Layers:

        Sorting Layers中Layer 1设置为UI0_0,主要用于Hierarchy中的UI0_0,Effect用于第一部分夹在两个UI中的粒子特效,UI0_1主要用于Hierarchy中的UI0_1,让其最后进行渲染。我们将向UI0_1添加Canvas组件,并勾选Override Sorting属性,此时会发现多出来Sorting Layer与Order in Layer属性。        

        此时,我们发现UI0_1渲染到了最上层,如下图:        

          这是因为在UI0_1在勾选了Overrides Sorting属性后,Sorting Layer 默认为Defalut,Order in Layer默认为0,而此时Canvas0的Sorting Layer也为Default,Order in Layer为0(UI0_0没有单独添加Canvas,因此其归属于Canvas0,属性也就和Canvas0相同)。它们两个的属性就完全相同了,可是因为UI0_1的Canvas在Hierarchy中的层级比Canvas0的靠后,因此UI0_1便渲染到了最上层。

        回到正文,我们将UI0_1的Sorting Layer设置为UI0_1,就得到需求所要的正确结果了,如下图:

2.Order in Layer

        Order in Layer用于相同Sorting Layer层级的内部渲染顺序,越靠后的越晚渲染,这样配合Sorting Layer可以形成两级排序。当然,配合上多个UICamera就形成了三层排序,但在实际使用中还是应该尽量避免使用过多的Camera。

拓展:UGUI会自动合并批次,原理是它会把一个Canvas下的所有元素合并在一个Mesh里,如果Canvas下的元素很多,任意一个元素发生位置、大小的改变,就需要重新合并所有元素的Mesh。如果元素非常多的话,就可能会造成卡顿。
一个比较好的做法是每个UI界面都设置成一个Canvas。如果这个界面下的元素比较多,可以考虑嵌套多几个Canvas。尤其是会频繁改变位置大小的元素,这样可以降低它们合并Mesh的开销。但是Canvas嵌套太多也不好,Mesh合并是降低了,但是DrawCall又上去了,因为每个Canvas都会单独占用一个DrawCall。

        在此处,我们额外创建一个UICamera1和Canvas1,用作第三部分UI、粒子特效、UI效果的实现,这里我们会采用Order in Layer的方式来实现。将Canvas1与UICamera进行绑定,添加一个UI1的Layer,添加一个UI1的Sorting Layer,进行如下图设置:

 

        在Canvas1中添加Fir0与Fir1两张Image,如下图:    

                                               

                      

        此时Fir0的图像在Fir1图像的后面,我们可以通过向两个Image添加Canvas,并勾选Overrite Sorting属性,之后将它们的Sorting Layer设置于同一层,并用Order in Layer进行内部排序,即可让Fir0显示在Fir1上方,如下图:

 

四、Particle System

1.Sorting LayerID 与Order in Layer

        Particle System的Sorting LayerID与上述作用相同,同样是可在不同Canvas中改变其渲染顺序。而Order in Layer则是相同Sorrting Layer中的内部排序,在此不再赘述,直接看案例。

        在Hierarchy中添加FX_Fire粒子特效,将其拖到UI0_1与UI0_0的结合部,Layer设置为UI,只在UICamera0中进行渲染,打开Particle System中的Renderer,将其Sorting LayerID设置为Effect,这样火焰特效即会在UI0_1与UI0_0中间进行渲染,如下图:

 

        为了与第一部分的背景、UI、粒子特效、UI效果进行对照,我们再往Hierarchy中添加一个命名为Display的Canvas,其创建与设置与Canvas1相似,但是Slider Image使用额外创建的Sorting Layer,如下: 

 

 

 

 

        最后我们需要在Display的Bar与Slider图像中间加入一个粒子特效,形成第三部分的UI、粒子特效、UI效果。向场景中添加FX_Smoke粒子特效,并将位置设置与UI结合处,将其Sorting Layer ID设为Effect1,如下图:

        通过上述操作,最终就得到我们想要的效果啦!


总结

1.渲染排序级别:Camera Depth>Canvas Sorting Layer>Canvas Order in Layer。

2.同时要注意区分Layer与Sorting Layer,在UI中,Layer主要用于Camera的Culling Mask,用于渲染选中的对象层,而Sorting Layer则是可以改变Canvas节点的渲染顺序。而Sorting Layer与Order in Layer的关系是当在同一Sorting Layer中时,Order in Layer负责其内部排序。Sorting Layer与Order in Layer可以组成二级排序,如果再配合上Camera的Depth则可构成三级排序。

3.Particle System的Renderer中也有Sorting LayerID,Order in Layer,其用法与Canvas中一致。

        好啦,以上就是笔者要分享的内容啦!真是万万没想到呀,简简单单的一篇博客竟然花了两天的空余时间来完成,看来UGUI中需要深入了解学习的知识还是有很多的,后续如果有遇到新的、有趣的问题,我也会用博客进行记录的。最后希望这篇博客能够对大家有所帮助!

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值