🦾

Godotのcollisionのlayerとmaskがいつもよくわからなくなる

2024/05/21に公開

Godotのcollision(衝突)を扱う場合に、layerとmaskの設定をどうすればよいかよくわからなくなることがあります。毎回調べて思い出す必要があるので、自分用の備忘録としてまとめておきます。

layerとmaskの関係性について

collisionのlayerとmaskは、PhysicsBody系のCharacterBody2DやRigidBody2D、StaticBodyなどが持つプロパティでインスペクタのCollisionから設定できます。

layerとmaskの値は1つのBody(Node)に対して複数設定できます。例えば上の画像で言えば、maskは 135 の3つを同時に指定しています。一方で設定できる数には1~16までと制限があり、計画的に利用する必要があります。

layerとmaskの関係性について説明しますと、layerはBodyがどのレイヤーに所属するかを表し、maskはBodyがどのレイヤーに所属するBodyと衝突判定を行うかになります。
そのため、例えば片方の値だけを設定すると、衝突判定されず通り抜けてしまうことがあります。
一見すると、2種類の値を分けずに1つの値で管理して衝突判定を行えば良いのではないかと思うかもしれません。しかし、layerとmaskを分けることで、柔軟な設定が可能になります。

横スクロールアクションの場合を考えてみましょう。

地面に対してプレイヤーも村人も衝突させたいので、すべてに対してlayerに1を設定します。しかしプレイヤーは村人の前を通り過ぎたいために、プレイヤーと村人は干渉しないようにしたいとします。するとlayerしか指定できない場合にはそれを実現する方法がありません。

layerとmaskで分けるとどうでしょうか?上記の図のようにlayerとmaskを設定すると、プレイヤーと村人はお互いにmaskで衝突をさせないようにする一方で、地面に対しては衝突を有効にすることができます。

ちょっとした疑問

layerとmaskの関係について少し疑問な点があります。それは、maskは一方向の作用を表すため、物理衝突行うBody同士が一方向の設定だけを指定した場合はどうなるかという点です。

例えば上記の図のように、AというBodyにlayer=1とmask=1を指定し、BというBodyにlayer=1を指定し、maskには何も指定しないとします。この場合、AとBのBodyが衝突した際には何が起きるのでしょうか?

結果は次の通りです。
※AとBが衝突するために、地面も設置しています。

上のオブジェクトがBで、下がAです。衝突した瞬間、押し戻されるような違和感のある挙動が起きます。AのBodyの作用だけがBを押し戻す形で辛うじて適用されていますが、物理衝突を行う上で、一方向にだけ作用する設定はあまり好ましくなさそうです。
一方、物理衝突以外のArea2D/Area3Dでの判定では、一方向の作用だけを適用するだけで良いため、少ない設定で処理の効率性が得られる可能性があります。

Discussion