Unity UGUI 与特效层级方案
文章目录
需求
- 显示:UI 需要与特效共同显示,且能方便地调整前后关系。
- 操作:对 UI 的操作需要与显示的层级对应,不会出现错误的穿透问题。
网上大多数人只研究了第一点,但在实际项目中必须要解决第二点,否则会出现莫明其妙的操作 Bug。
前提
UGUI 与特效能同时显示的前提是都使用相同的方式渲染与排序。
因此 Canvas 的 Render Mode
可以设置为 Screen Space - Camera
或 World Space
,即使用 Camera 来渲染 UI。
原理
不论是显示还是操作,都是受不同的属性影响。 有 SortingLayer、SortingOrder、Z 等方便修改的属性,还有 RenderQueue 之类不方便修改的属性。
UGUI和特效模型混排的解决方案 这篇文章讲解地比较详细。
因为属性需要人工在 Unity 界面中修改,所以只考虑方便修改的属性。
- 显示:SortingLayer > SortingOrder > Z
- 操作:SortingLayer > SortingOrder > Graphic.depth > Z
注:操作相关的属性比较来自于 UGUI 源码 中的 EventSystem.cs
与 GraphicRaycaster.cs
。
Graphic.depth 是什么?官方文档解释如下:
The depth is relative to the first root canvas. Here is an example hierarchy and the corresponding graphics depth: Canvas Graphic <- 1 Graphic <- 2 Nested Canvas Graphic <- 3 Graphic <- 4 Graphic <- 5
实际上检查源码发现,Graphic.depth 是 Canvas 下继承自 Graphic 的 UI 组件的深度遍历顺序。
但是由于 EventSystem 在比较 Graphic.depth 时未考虑是否是同一个 GraphicRaycaster(Canvas) 下的 Graphic, 因此导致无法在不同 Canvas 下使用此属性。
方案
由于上述 EventSystem 的限制,导致只能使用 SortingLayer 或 SortingOrder。 由于 SortingLayer 需要预先定义,那么剩下的选项只有 SortingOrder。
- 显示:SortingOrder > Z
- 操作:SortingOrder
那么在实际使用中,需要管理不同 Canvas 的 SortingOrder。即按照显示顺序设置 Canvas 的 SortingOrder,同时为 Canvas 下的粒子增加 SortingGroup 组件并设置相同的 SortingOrder,此时再修改 Z 值来决定粒子与 UI 之间的显示顺序。
工具
如果涉及到原有 UI 改造,那么建议编写几个工具批量处理:
- 统一 UI 结构工具,保证结构与属性都一致,如坐标取整、缩放统一以保证粒子显示正常等等。
- UI 自动查找特效并增加 SortingGroup 工具,方便美术调整。