[Unity] Physics.OverlapCapsuleの使い方

Capsule and Cube Collider

このようにCapsule Colliderに重なってる2つのColliderを取得したいときは、Physics.OverlapCapsuleを使うとよい。このメソッドにCapsule Colliderの位置と大きさを与えると、重なっているColliderがすべて返る。RigidbodyをKinematic TriggerにしてOnTriggerEnterをハンドルして取得することもできるが、こちらのほうが手軽である。

Physics.OverlapCapsuleの必須の引数のみのシグネチャを以下に示す。

point0point1にCapsuleの上下の半球の中心をradiusに半径を指定する。

CapsuleColliderの位置と大きさは、中心の座標(Center)と高さ(Height)と半径(Radius)で与えられる。Physics.OverlapCapsuleの引数の仕様とは異なっているので変換の必要がある。

CapsuleColliderの位置と大きさはローカル座標で与えられるので、変換する前にグローバル座標に変換する必要がある。この記事のプログラムは大きさを変換していないため、GameObjectの大きさが1でないと正しく動かない。

グローバル座標に変換する手順を以下に示す。

まず、GameObjectのTransformのTransformVectorを使って大きさをグローバル座標に変換する。半径をxに高さをyに与えて変換すると、グローバル座標における半径と高さが求められる。次にTransformPointを使って、中心の座標をグローバル座標に変換する。

こうして求めた大きさと位置から、以下のようにPhysics.OverlapCapsuleの引数を計算して実行する。

当然のことながら、返ってくるColliderにはCapsuleColliderも含まれることに注意してほしい。避けたければ、あらかじめCapsuleColliderを無効化しておくとよい。

Physics.OverlapCapsuleを用いると、対象のCapsuleCollderよりもサイズを小さくして、触れているだけのColliderを除外するとか、サイズを大きくして接触しそうなColliderを取得するといったことが自在に行える。

ところで、Physics.OverlapCapsuleは呼ぶたびに配列をアロケートして結果を返すので、毎フレーム呼ぶ場合には大量にゴミが出てしまう。その場合には、Physics.OverlapCapsuleNonAllocで事前にアロケートした配列で結果を受け取る。使用例を以下に示す。

重なりを5つまで検出する場合は、5要素のColliderの配列をUpdateの外で作っておく。それをPhysics.OverlapCapsuleNonAllocに渡して実行すると、_resultに検出したColliderが格納されて、その数が返値として返る。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です