Unity 中SoringLayer 和 Layer 的區別、相機、渲染順序和射線檢測

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 是通過射線檢測來觸發的。也就是物體上必須有碰撞體才能檢測到。

當同一位置有多個碰撞體時,距離相機最近的物體,會被首先檢測到,並觸發相應的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章