Menu
CoddyTech

レイヤーとLayerMask

CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 38/71。

すべてのGameObjectは1つのレイヤーに属し、Inspectorの上部にあるLayerメニューで選択します。Unityには32個のレイヤーがあります。いくつかは組み込みのレイヤーです(0 Default、2 Ignore Raycast、4 Water、5 UI)。独自のレイヤーは、User Layer 3から始まるTags and Layersで名前を付けます。LayerMaskはレイヤーの集合で、レイヤーごとに1ビットを使います。maxDistanceの後にレイキャストへ渡すと、レイはその集合に含まれないレイヤー上のすべてのコライダーを無視します。

このプレイヤーは敵の頭の上ではなく、地面からジャンプする必要があります。床をGroundレイヤーに配置し、スクリプトにLayerMaskフィールドを用意します。Inspectorにはメニューとして表示され、そこでGroundにチェックを入れます。

[SerializeField] private LayerMask groundMask;

bool IsGrounded()
{
    return Physics.Raycast(transform.position, Vector3.down, 1.1f, groundMask);
}

Groundだけを含むマスクを使えば、プレイヤー自身を検出することも防げます。レイは開始位置が内部にあるコライダーはスキップしますが、子オブジェクトのコライダーなど、プレイヤーのほかのコライダーはスキップしません。また、後のレッスンで扱うオーバーラップ判定ではプレイヤー自身のコライダーも検出されるため、マスクなしで足元を判定すると、常に接地していると判定されます。プレイヤーとその子オブジェクトをPlayerレイヤーに配置し、判定に使うマスクにはPlayerを含めないようにします。コードでは、LayerMask.GetMask("Ground", "Platform")がレイヤー名からマスクを作成し、マスクの前に付けた~は、そのマスクに含まれていないすべてのレイヤーへ反転します。

challenge icon

チャレンジ

中級

スカウトのレイが自分のランタンの先まで見通せるようにしましょう。

  1. LookAhead()でint mask = ~LayerMask.GetMask("Player");を作成します。これは、スカウトとそのランタンがいるPlayerレイヤー以外のすべてのレイヤーを対象にします。
  2. rangeの後にmaskをレイキャストに渡します。

「プレイ」を押して、矢印キーでスカウトを回転させます。コンソールに岩と木の名前が表示されます。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;

public class Spotter : MonoBehaviour
{
    public float range = 10f;
    private string last = "";

    void Update()
    {
        string seen = LookAhead();
        if (seen != last)
        {
            Debug.Log("Ahead: " + seen);
            last = seen;
        }
    }

    // 前方のrange内で最初に見つかったものの名前。見つからなければ"nothing"。
    public string LookAhead()
    {
        if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hit, range))
        {
            return hit.collider.name;
        }
        return "nothing";
    }
}

物理演算とゲームプレイのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド