粒子在UI上的层级问题问题 问题:在UI上用过粒子特效的人(只要用到了粒子系统的Renderer模块),大都遇到粒子效果要么显示在所有UI面板的前面,要么无法显示粒子。 原因 造成该问题的原因:Unity的粒子系统的Renderer模块使用Sorting Layer进行摄像机渲染的层级排序,而对于UI来说并非都是如此。 其他因素:所有UI和粒子都没有额外设置过Renderer Queue。没有进行过渲染层级相关的操作。 UI的显示和Canvas组件相关,笔者见过的一种做法为,建立一个根UI节点,在该节点上挂载Canvas组件,而下面的子节点不会再次挂载Canvas组件。 可以从可图看到,如果子节点没有挂载 Canvas组件或者挂在了没有勾选OverrideSorting,并设置相应层级。那所有UI都会在一个渲染层级下。 其一个目的为:一个Canvas下所有元素都会合并在一个Mesh中,而设置多个Canvas或嵌套Canvas并生成多个Mesh。而如果在游戏运行中改变了UI的位置、大小等,则该Canvas下就需要重新合并所有的元素生成新的Mesh。 因此对于频繁改动位置、大小等的UI可以单独建立一个Canvas,降低Mesh合并的开销。 另一方面,每一个Canvas都会单独占用一个DrawCall。频繁嵌套Canvas会增加过多的DrawCall。 根节点添加Canvas 根节点下的子节点添加Canvas 想要具体了解UI的层级关系,以及Canvas对于渲染合批的作用,可以查看这篇博客:传送门 简而言之,Unity中一般会设置两个相机,一个为Main Camera主要负责渲染游戏内的内容,例如战斗场景。第二个相机为UI Camera,专门负责渲染UI层级的内容。而粒子系统Renderer默认会设置一个Sorting Layer,如果UI都在同一个Canvas下,且没有嵌套更多的Canvas。那就无法区分粒子和UI的前后层关系(所有的UI都处于同一层!)。因此粒子要么在所有的UI前,要么在所有的UI后。 解决方案 方案一:问了一下同学,他们项目组使用的是网络上的插件,在Github和相关网站上都有粒子效果管理的插件,使用哪个自行甄别,这里不作推荐。 方案二:自行建立UI的层级管理。个人目前采用的为比较简单的做法:为每一个打开的UI面板都设置一个Canvas并设置一个对应的层级管理的Manager代码来管理所有的UI层级。新打开的UI Order in Layer要在旧的前面,对于需要顶层显示的信息(例如提示类消息)设置一个默认的最高层级。 对于UI面板的定义划分为: 1、不同功能模块的内容建立新的UI面板 2、在同一个面板中,如果有弹出提示操作面板(例如商城页面点击购买后弹出购买面板)等内容最好设置为新的面板,不要放入同一个UI内。 3、UI面板的管理、优化可大可小。需要根据人力、时间、便捷性等多方面考虑选择。 UI上的粒子遮罩问题UI上的粒子系统是不支持Mask遮罩的。主要原因为大部分的Shader或者是自己写的Shader没有支持模板测试。因此就需要修改对应粒子上的Shader。 当然,仍有部分Shader是自身支持模板测试的。对于Shader如何支持模板测试可以直接在搜索引擎搜索即可。后续有时间我也会详细阐述补充该方面的步骤。 << Java使用经验汇总 《经济学原理》笔记01 导言 >>