SoringLayer 和 Layer 的區別
SoringLayer :排序層級。影響物體渲染的順序,具體的規則見後文。
Layer:層級。用於物體的邏輯分層。
- 在物理相關的射線檢測等時,可以指定忽略/只關注某些層級的物體。
- 相機可以設置只渲染特定層級的物體。
相機
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。
- 創建一個空場景 TestSortingLayer。
- 創建一個節點,重命名爲 Red,掛載 SpriteRenderer 組件,在 Sprite 屬性點擊右側小圈後選擇 Unity 的自帶資源 Background,修改顏色爲紅色。
- 複製 Red 結點,重命名新節點爲 Green,修改顏色爲綠色,將 Green 的結點往右下角移動,使得兩個結點不完全重疊。大致關係如下即可。
-
可以看到 Red、Green 結點的 SoringLayer(
Default
)、OrderInLayer(0
)、z 座標(0
) 都是相等的。 -
通過每次只改變其中一項來觀察圖片的覆蓋情況,可以得出三個規則各自的渲染順序如上文所述。
(每種情況測試後,都需要把修改還原,再進行下一個情況的測試。)- case1
只修改 Red 結點的 SortingLayer 爲 Top,可以發現 Red 結點在上。
- case2
只修改 Red 結點的 OrderInLayer 爲 1,可以發現 Red 結點在上。
- case3
只修改 Red 結點的 z 座標爲 -1,可以發現 Red 結點在上。(相機 z 座標在 -10,物體的 z 座標越小,離相機越近。但是不能小於 -10,否則就不能被相機捕獲並渲染。)
-
同時,可以發現三個規則的生效是有上文所述的優先級的。
- case4
修改 Red 結點的 SoringLayer 爲 Top 後,只要 Green 結點的 SoringLayer 仍爲 Default,無論如何修改 Green 結點的 OrderInLayer 和 z 座標 ,都可以發現 Red 結點在上。
- case5
Red 和 Gredd 結點的 SoringLayer 都爲 Top,修改 Red 的 OrderInLayer 爲 1,Green 的 OrderInLayer 爲 0,無論如何修改 Green 結點的 z 座標,都可以發現 Red 結點在上。
距離的更多細節
物體距離相機的距離這條規則,還有細節可以繼續深入。
查看官網文檔 https://docs.unity3d.com/Manual/Sprites.html 中 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 官方文檔 https://docs.unity3d.com/Manual/2DSorting.html。
射線檢測
驗證
-
編寫
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 是通過射線檢測來觸發的。也就是物體上必須有碰撞體才能檢測到。
當同一位置有多個碰撞體時,距離相機最近的物體,會被首先檢測到,並觸發相應的方法。