レイヤーのフィルタリング技術資料

Unityにおけるレイヤーフィルタリングは、特定のレイヤーに属するオブジェクトのみを対象とした処理を行う際に非常に有用です。本資料では、LayerMask を活用して特定のレイヤーを検出する方法と、その設定をインスペクターから行えるようにする手法について詳述します。


レイヤーマスクの基本

レイヤーマスクとは

LayerMask は、Unityでオブジェクトのレイヤーをビットフラグとして管理するための構造体です。これを利用することで、レイキャストや衝突判定などで特定のレイヤーのみを対象に処理を行うことが可能です。

基本的な使用例

以下のコードは、レイヤー「Enemy」のみを検出するためのレイヤーマスクを作成し、レイキャストを行う例です。

using UnityEngine;

public class RaycastExample : MonoBehaviour
{
    void Update()
    {
        // レイヤーマスクの作成
        int layerMask = LayerMask.GetMask("Enemy");

        // レイの生成(カメラからマウス位置に向かって)
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        // レイキャストの実行
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
        {
            Debug.Log("Hit enemy: " + hit.collider.name);
        }
    }
}

コード解説

  • LayerMask.GetMask(“Enemy"): レイヤー「Enemy」のみを検出するレイヤーマスクを作成します。
  • Mathf.Infinity: レイの飛ばす距離を無限に設定し、全ての距離に対してレイを飛ばします。
  • Physics.Raycast: 指定されたレイヤーマスクに基づいてレイキャストを実行します。

インスペクターからのレイヤー選択

ハードコードではなく、インスペクターから柔軟にレイヤーを選択できるようにすることで、スクリプトの再利用性とメンテナンス性が向上します。

実装手順

ステップ 1: スクリプトの修正

LayerMask 型の変数を公開するか、[SerializeField] 属性を付与してプライベート変数として宣言します。

using UnityEngine;

public class RaycastExample : MonoBehaviour
{
    // インスペクターでレイヤーを選択可能にする
    [SerializeField] private LayerMask layerMask;

    void Update()
    {
        // カメラからマウス位置に向かってレイを飛ばす
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        // レイヤーマスクを使用してレイキャストを実行
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
        {
            Debug.Log("Hit object on selected layer: " + hit.collider.name);
        }
    }
}

ステップ 2: インスペクターでの設定

  1. 上記のスクリプトを対象の GameObject にアタッチします。
  2. インスペクター上でスクリプトコンポーネントを確認すると、Layer Mask というフィールドが表示されます。
  3. ドロップダウンメニューから検出したいレイヤー(例: 「Enemy」)を選択します。複数選択も可能です。

複数レイヤーの選択方法

LayerMask は複数のレイヤーをビットフラグとして保持できるため、インスペクター上で複数のレイヤーを選択して一度に処理することが可能です。

実装例

using UnityEngine;

public class MultiLayerRaycast : MonoBehaviour
{
    [SerializeField] private LayerMask layerMask;

    void Update()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
        {
            Debug.Log("Hit object on selected layers: " + hit.collider.name);
        }
    }
}

使用方法

  1. インスペクター上で Layer Mask フィールドを確認します。
  2. ドロップダウンメニューから複数のレイヤー(例: 「Enemy」と「Obstacle」)のチェックボックスをオンにします。
  3. レイキャストは選択された全てのレイヤーに対して実行されます。

プログラムからの動的レイヤーマスク設定

インスペクターだけでなく、スクリプト内から動的にレイヤーマスクを設定することも可能です。これにより、実行時にレイヤーの設定を変更できます。

実装例

using UnityEngine;

public class DynamicLayerRaycast : MonoBehaviour
{
    [SerializeField] private string[] layerNames;

    void Update()
    {
        // レイヤーマスクを動的に生成
        LayerMask layerMask = LayerMask.GetMask(layerNames);

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
        {
            Debug.Log("Hit object on selected layers: " + hit.collider.name);
        }
    }
}

ステップ

  1. layerNames 配列に検出したいレイヤー名を文字列で追加します(例: "Enemy", "Obstacle")。
  2. スクリプト内で LayerMask.GetMask(layerNames) を使用して、指定したレイヤーのマスクを生成します。
  3. レイキャストは生成されたレイヤーマスクに基づいて実行されます。

ベストプラクティス

  • インスペクターの活用: スクリプト内で直接レイヤー番号をハードコードするのではなく、LayerMask を利用してインスペクターから設定できるようにすることで、柔軟性と再利用性を高めます。
  • レイヤーの命名規則: プロジェクト内で一貫したレイヤー命名規則を設けることで、コードの可読性と管理のしやすさを向上させます。
  • パフォーマンスの考慮: レイキャストの頻度やレイヤーマスクの設定は、必要最低限に抑えることでパフォーマンスへの影響を最小限にします。

参考資料


まとめ

本資料では、Unityにおけるレイヤーフィルタリングの基本から、インスペクターおよびスクリプト内での設定方法、複数レイヤーの選択、動的なレイヤーマスクの設定方法について解説しました。LayerMask を適切に活用することで、効率的かつ柔軟なオブジェクト管理が可能となります。プロジェクトの要件に応じて、最適な方法を選択し実装してください。

Unity,当たり判定

Posted by hidepon