Version: 5.6
シェーダーのロード時間を最適化
レイヤーベースの衝突検出

レイヤー

レイヤー は、 カメラ によりシーンの一部のみレンダリングするために、また ライト はシーンの一部のみ照らすため、というように頻繁に使用されます。一方で部分的に、Collider を無視するあるいは レイヤーベースの衝突検出を発生させるためにも使用することができます。

レイヤーの作成

まず新規レイヤーを作成し、次にそのレイヤーを ゲームオブジェクト に割り当てます。新規レイヤーを作成するには Edit メニューを開いて Project Settings->Tags and Layers を選択します。

空の User Layer の中から新規レイヤーを作成します。ここではレイヤー 8 を選択することにします。

レイヤーの割り当て

新規レイヤーは作成できたので、次にゲームオブジェクトの一つにアサインします。

Tag Manager で Player レイヤーをレイヤー 8 に割り当てました。

シーンの一部のみをカメラのカリングマスクで描画

カメラのカリングマスクを使用して、特定の 1 つのレイヤーのオブジェクトのみをレンダリングできます。 そのためには、オブジェクトを選択的に描画するカメラを選択します。

Culling Mask プロパティーでレイヤーのチェックをつけたり外したりすることでカリングマスクの設定を変更することができます。

選択的に Raycast する

レイヤーを使用して、特定のレイヤーでレイキャストを行ったり、コライダーを無視することができます。 例えば 、Player レイヤーのみにレイキャストを行い、他のコライダーを無視することができます。

Physics.Raycast 関数はビットマスクを使用して、ビットごとにレイヤーを無視するかどうか判定することができます。 layerMask (レイヤーマスク)のすべてのビットが有効である場合は、すべてのコライダーと衝突します。 もし layerMask = 0 の場合、レイがコライダーに衝突することはありません。

// JavaScript example.

// ビットマスクを取得するために、レイヤーのインデックスをビットシフトします
var layerMask = 1 << 8;
// レイはプレイヤーレイヤーのオブジェクトと交差するか?
if (Physics.Raycast (transform.position, Vector3.forward, Mathf.Infinity, layerMask))
    print ("The ray hit the player");


// C# example.

int layerMask = 1 << 8;
        
// レイはプレイヤーレイヤーのオブジェクトと交差するか?
if (Physics.Raycast(transform.position, Vector3.forward, Mathf.Infinity, layerMask))
    Debug.Log("The ray hit the player");


現実世界では、この逆を行いたい場合があります。Player レイヤー以外のすべてのコライダーに対して Raycast します。

// JavaScript example.
function Update () {
  // ビットマスクを取得するために、レイヤー (8) のインデックスをビットシフトします
  var layerMask = 1 << 8;
  // これは、レイヤー 8 のコライダーに対してのみレイを照射するところでしたが
  // 代わりに、レイヤー 8 以外のすべてに対して衝突させます。 ~ 演算子は、ビットマスクを逆にします。
  layerMask = ~layerMask;

  var hit : RaycastHit;
  // レイはプレイヤーレイヤー以外のオブジェクトと交差するか?
  if (Physics.Raycast (transform.position, transform.TransformDirection (Vector3.forward), hit, Mathf.Infinity, layerMask)) {
    Debug.DrawRay (transform.position, transform.TransformDirection (Vector3.forward) * hit.distance, Color.yellow);
    print ("Did Hit");
  } else {
    Debug.DrawRay (transform.position, transform.TransformDirection (Vector3.forward) *1000, Color.white);
    print ("Did not Hit");
  }
}


// C# example.
void Update () {
    //ビットマスクを取得するために、レイヤー (8) のインデックスをビットシフトします
    int layerMask = 1 << 8;
        
   // これは、レイヤー 8 のコライダーに対してのみレイを照射するところでしたが
  // 代わりに、レイヤー 8 以外のすべてに対して衝突させます。 ~ 演算子は、ビットマスクを逆にします。
    layerMask = ~layerMask;
    
    RaycastHit hit;
    // レイはプレイヤーレイヤー以外のオブジェクトと交差するか?
    if (Physics.Raycast(transform.position, transform.TransformDirection (Vector3.forward), out hit, Mathf.Infinity, layerMask)) {
        Debug.DrawRay(transform.position, transform.TransformDirection (Vector3.forward) * hit.distance, Color.yellow);
        Debug.Log("Did Hit");
    } else {
        Debug.DrawRay(transform.position, transform.TransformDirection (Vector3.forward) *1000, Color.white);
        Debug.Log("Did not Hit");
    }
}

Raycast 関数に layerMask を渡さない場合、IgnoreRaycast レイヤーのコライダーのみ無視します。 Raycast するときにいくつかのコライダーを無視するにはこれがもっとも簡単です。

シェーダーのロード時間を最適化
レイヤーベースの衝突検出