Unity中UI, 3D和特效等层级SortingOrder管理方案

本文分享Unity中UI, 3D和特效等层级SortingOrder管理方案

我们在Unity的开发中, 经常会遇到一个问题, 就是UI, 3D和特效的层次问题.

因为UI都是最后绘制, 所以UI总是在所有事物的最上层.

但是有些时候我们需要3者相互穿插, 特别是场景中有背景图, 有3D模型, 也有粒子特效动画等, 需要它们和谐共处, 互不影响.

这时就需要我们手动来管理渲染层级.


使用RenderTexture

在某些场景下, 如果只有很少的3D模型(只要带MeshRenderer组件), 我们可以将相关的模型的layer设置为一个专门的layer, 然后使用一个摄像机来对它们进行绘制.

并将绘制的结果输出到一个RenderTexture上, 最后将这个RenderTexure设置到某个RawImage上.

这样, 即所谓3D转2D, 将3D的物体变为2D的图片.

这样的图片和其它的图片一样的用法, 不会有层级和点击的问题了.

注意, 摄像机的ClearFlags要选择"Depth Only", "CullingMask"选择那个专门的layer.

如下所示:

在这里插入图片描述

骨骼动画使用SeletonGraphic

如果是在UI场景中使用的骨骼动画, 比如大厅等界面.

因为默认情况下骨骼动画使用Skeleton Animation, 而该组件使用的是Mesh Render组件来渲染, 会与UI产生层级问题.

我们可以使用SeletonGraphic组件来替换Skeleton Animation, 按照2D的模式来播放动画.

这时, 动画相当于是一个2D动画, 就不会有层级和点击的问题了.

如下所示:

在这里插入图片描述

将Mesh相关的三个组件去掉: Skeleton Mesh, Mesh Renderer, Skeleton Animation, 然后添加Skeleton Graphic, 添加骨骼数据文件和材质.

通过设置Sorting Order

Canvas使用Canvas Renderer来渲染 在所有的renderer绘制完毕之后再进行UI元素的绘制, 所以一般UI元素会显示在所有物体的最上层.

我们可以通过设置Canvas的的渲染模式来改变这一逻辑, 即RenderMode设置为Screen Space-Camera来将Canvas当做普通的Renderer来渲染.

默认是Screen Space-Overlay, 也就是显示在最上面.

这样, 一个Canvas所包含的UI元素就和普通的3D物体一样, 可以通过设置Canvas或者3D元素的Renderer的sortingOrder来进行手动层级控制.

修改Canvas的Sorting Order

将根Canvas的渲染模式设置为Screen Space-Camera, 选择一个SortingLayer, 比如Default, 然后设置一个基础Order, 如1500.

如图:

在这里插入图片描述

然后将每一个单独的预制(代表一个窗口)都挂上单独的Canvas, 勾选Override Sorting, 然后选择与根Canvas相同的SortingLayer, 之后指定一个基础Order.

每个窗口层级都预留一些Order空间给其子节点使用, 如第一个Window使用1600, 第二个Window1700, 之间差的100就是给窗口的子节点使用.

这里要注意, 为了使UI元素获得点击等事件, 需要额外添加Graphic Raycaster组件.

如图:

在这里插入图片描述

在这里插入图片描述

如果某个窗口的子节点需要手动控制层级, 那么在该子节点上加上Canvas, 然后与其窗口保持一样的设置, 只是Order可以稍微高一点, 比如1601, 则这个子节点就会处于这个窗口的所有子节点之上.

修改3D元素或者特效的层级

3D元素和骨骼动画一般使用MeshRenderer组件, 粒子特效一般使用Renderer组件.

在MeshRenderer组件中没有找到SortingLayer和OrderInLayer属性, 因为其继承于Renderer, 属性被隐藏, 但是可以通过代码来设置.

网上有很多组件可以用来设置MeshRenderer的Order, 大家可以自行下载, 也可以使用作者的版本, 传送门在文章最后.

通用解决方案

通过手动(代码管理)调整Renderer的渲染Order来处理UI, 3D, 特效之间的层次关系.

我们可以制作一个组件, 这个组件可以将一个节点的所有子孙节点的SortingOrder设置为与自身保持一致.

如果子节点有Canvas组件, 则设置其Canvas组件的Order, 如果子节点有Renderer组件, 则设置其Renderer组件的Order.

其他子节点默认保持和父节点一样的Order, 不需要主动设置.

这时, 所有的子节点都与父节点有一样的Order, 默认根据其Hierarchy顺序来绘制.

在某些需要特殊处理的节点, 比如3D元素或者特效要显示在某些UI元素之下或者夹在元素之间的需求时, 我们可以单独控制涉及到的子节点.

比如我们需要将一个骨骼动画显示在两个图片之间, 我们可以在两个图片上加上Canvas组件, 将其Order设置为1601和1603, 然后将骨骼动画的Order设置为1602即可.

当然, 以上的操作要结合手动修改预制和代码控制.

作者自己写好了一个组件来完成上述过程, 结合窗口管理过程中加入的Order管理即可满足日常需求.

这里是传送门: RenderSortingOrder.

RenderSortingOrder

这个组件可以一键将所有子节点设置为与自己相同的Order.

可以设置基准Order, 并设置偏移值, 支持Canvas和Renderer.

如图所示:

在这里插入图片描述

在非运行状态下可以勾选OverrideSorting, 覆盖父节点指定的基准Order, 这样父节点在一键设置Order时会跳过该节点, 让该节点自己进行控制.

具体情况大家可以看代码, 这里不再展开细说.

好了, 今天就到这里, 希望对大家有所帮助.

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拂面清风三点水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值