Unity 中的相机会影响渲染顺序和射线检测。
默认情况下相机的 rotation 为(0, 0, 0),朝向 z 轴正方向。
在 2D 游戏中,如果相机的 rotation 设置为(180, 0, 0),则画面上下颠倒;
如果设置为 (0, 180, 0),则画面上下颠倒。
本文以默认情况,即相机 rotation(0, 0, 0)、position(0, 0, -10)、scale(1, 1, 1)为例。
按照如下规则
依次
来确定渲染排序
(先渲染的会被后渲染的覆盖。仅当前一个条件相同时,才会比较下一个条件。)
物体的 SortingLayer。根据
Project Setting
-
Tags & Layers
中的顺序,越靠上的 SortingLayer 越先渲染。
物体的 OrderInLayer。数字越小越先渲染。
物体距离摄像机的距离。越远的越先渲染。在 2D 游戏中(默认设置下摄像机朝向 z 轴正方向时),这通常等价于 z 坐标,越大的越先渲染。
物体距离摄像机的距离,这条规则还有更多的细节,后文会再补充。
创建 2D 项目
添加 SortingLayer: Top。
修改 Red 结点的 SoringLayer 为 Top 后,只要 Green 结点的 SoringLayer 仍为 Default,无论如何修改 Green 结点的 OrderInLayer 和 z 坐标 ,都可以发现 Red 结点在上。
case5
Red 和 Gredd 结点的 SoringLayer 都为 Top,修改 Red 的 OrderInLayer 为 1,Green 的 OrderInLayer 为 0,无论如何修改 Green 结点的 z 坐标,都可以发现 Red 结点在上。
距离的更多细节
物体距离相机的距离这条规则,还有细节可以继续深入。
查看官网文档
docs.unity3d.com/Manual/Spri…
中 Sorting Sprites 这个章节,可以发现距离的定义与项目和相机的设置有关。
Unity Editor
-
Edit
-
Project Settings
-
Graphics
-
Camera Settings
-
Transparency Sort Mode
里面的设置
默认:根据 camera 的投射模式是透视还是正交。
Default - Sorts based on whether the Camera’s Projection mode is set to
Perspective or Orthographic
透视、远景:根据 sprite 的中心和 camera 的直线距离
Perspective - Sorts based on perspective view. Perspective view sorts Sprites based on the distance from the Camera’s position to the Sprite’s center.
正交:根据 camera 方向上, sprite 和 camera 的距离。
Orthographic - Sorts based on orthographic view. Orthographic view sorts Sprites based on the distance along the view direction.
自定义轴:根据设置的轴来排序。
Custom Axis - Sorts based on the given axis set in Transparency Sort Axis
将 Red、Greed 结点的 scale 改成 (200, 200, 1),移动结点位置,使得 Red 结点的中心位置在左上角,Greed 结点的中心在中央。
Green 结点的 z 坐标修改 为 5,Red 结点的 z 坐标为 0 保持不变。此时 Red 结点在上。因为此时决定物体渲染顺序的距离是:在相机方向上(也就是 z 轴正方向上)物体和相机的距离,也就是 z 坐标的差值。Red 结点所在平面 距离 相机所在平面 更近。
修改相机的 Projection 为 Perspective
或者
修改
Project Settings
-
Graphics
-
Camera Settings
-
Transparency Sort Mode
为 Perspective,可以看到 Green 结点在上。因为此时决定物体渲染顺序的距离是:物体中心和相机中心的距离,也就是两个坐标间的距离。Red、Greed 结点上 z 的差值远小于 x、y 的差值,所以 Green 结点距离相机更近。
更多的细节
除了以上因素,Render Queue、Sorting Group、Material/Shader 也会影响渲染顺序。
更多的细节可以参照 Unity 官方文档
docs.unity3d.com/Manual/2DSo…
编写
ClickPanel
脚本
public class ClickPanel : MonoBehaviour
public readonly UnityEvent onClick = new UnityEvent();
public readonly UnityEvent onMouseDown = new UnityEvent();
public readonly UnityEvent onMouseUp = new UnityEvent();
private void OnMouseDown()
onMouseDown.Invoke();
private void OnMouseDrag()
// 可以增加判断,如果拖动超过一定距离或者一定时间,
private void OnMouseUp()
onMouseUp.Invoke();
onClick.Invoke();
Debug.LogFormat("onMouseUp:{0}", name);
给 Red、Green 结点都挂载 ClickPanel 脚本 和 BoxCollider2D 组件。
运行游戏。
设置 Red 结点 SoringGroup:Default,OrderInLayer:1,z 坐标:0。
设置 Green 结点 SoringGroup:Default,OrderInLayer:0,z 坐标:0。
可以看到此时无论如何修正 Green 结点的 z 坐标,Red 结点都在上。
点击两个结点重叠的部分,可以看到 onMouseUp:NAME
的输出。
当 Green 结点的 z 坐标大于 Red 结点 z 坐标时,NAME 为 Red。
当 Green 结点的 z 坐标小于 Red 结点 z 坐标且大于 相机 z 坐标时,NAME 为 Green。
当 Green 结点的 z 坐标大于相机 z 坐标时,NAME 为 Red。此时 Green 结点不可见。
Unity 2D 中,点击屏幕时,OnMouseDown、OnMouseDrag、OnUp 是通过射线检测来触发的。也就是物体上必须有碰撞体才能检测到。
当同一位置有多个碰撞体时,距离相机最近的物体,会被首先检测到,并触发相应的方法。
yzbyzz
56.3k
粉丝