Unityで厚みのあるレイを飛ばして当たり判定を行う

今回は厚みのあるレイを飛ばして当たり判定を行ってみたいと思います。

今まではPhysics.LinecastやPhysics.Raycast等の点や方向を使って線を引いて他のゲームオブジェクトと接触しているかどうかを判定している事が多かったですが、

今回はPhysics.BoxCast、Physics.CapsuleCast、Physics.SphereCastを使ってコライダのような空間でレイを飛ばし当たり判定をしてみたいと思います。

それぞれのメソッドの引数の指定方法は数多くあるので、その中の一部だけを使います。

スポンサーリンク

レイのターゲットゲームオブジェクトの作成

レイを飛ばす前にまずはレイが当たるかどうかのターゲットであるゲームオブジェクトを作成します。

ヒエラルキー上で右クリック→3D Object→Cubeを選択し、名前をTargetCubeにします。

TargetCubeのインスペクタでLayerにTargetという名前の新しいレイヤーを作成し、設定します。

BoxCast

BoxCastはCubeのレイを飛ばして当たり判定をすることが出来ます。

BoxCastメソッドは与える引数や個数が違うオーバーロードメソッドがいくつか定義されています。

与える引数はボックスの中心位置とボックスサイズの半分の値、レイを飛ばす方向、当たった相手の情報、レイの長さ、接触判定をするレイヤーのマスク等を与えます。

Physics.BoxCastの戻り値で条件に当てはまるゲームオブジェクト接触したかどうかのbool値が得られますのでif文の条件式にそのまま記述出来ます。

それでは、サンプルを作成していきます。

ヒエラルキー上で右クリック→3D Object→Cubeを選択し、名前をCubeRayとします。

CubeRayのTransformのY軸を回転させ前方(青矢印の方向)をTargetCubeの方向に向けておきます。

このCubeRayからBoxCastでCubeのレイを飛ばしてTargetCubeとの当たり判定をしてみます。

CubeRayにBoxCastRayTestスクリプトを作成し取り付けます。

targetTraにはインスペクタでTargetCubeを設定します。

distanceFromTargetObjはCubeRayとTargetCubeの距離を入れるフィールドで、Boxのレイを視覚化するときに使用します。

UpdateメソッドでPhysics.BoxCastでCubeRayを中心にSizeが1のBoxを作る為にVector3.one(new Vector3(1f, 1f, 1f)と同じ)に0.5をかけてSizeの半分を設定し、CubeRayの向いている方向100m先までレイを飛ばし、Targetレイヤーが設定されたゲームオブジェクトと接触しているかどうかを調べています。

接触していた場合はhitにデータが入るので、その当たった相手のゲームオブジェクトの名前を表示しています。

OnDrawGizmosにはシーンビューに疑似的にBoxのレイを表示する為にワイヤフレームのCubeを表示させる処理を記述しています。

OnDrawGizmosに関しては

UnityのGizmosを使ってシーンビューに視覚的なデバッグの補助をするようにします。具体的にはシーンビューやゲームビューにアイコン等を表示するようにします。

を参照してください。

Unityのプレイボタンを押して実行すると、

BoxCastを使ったサンプル例

上のようにシーンビューでCubeRayを移動させるとBox状のレイから外れるとコンソールにTargetCubeの表示がされなくなります。

SphereCast

SphereCastはSphere(球)のレイを飛ばして接触判定をすることが出来ます。

与える引数はBoxCastと同じような感じで複数のオーバーロードメソッドが用意されているので、自分の都合に合わせて与える引数を変更します。

SphereCastで与える引数の上方としては球の中心位置、球の半径、レイの方向、接触した相手の情報、レイの長さ、レイヤーマスク等です。

それではサンプルを作成していきます。

ヒエラルキー上で右クリック→3D Object→Sphereを選択し、名前をSphereRayとします。

SphereRayのY軸の数値を変更しTargetCubeの方向に向けておきます。

SphereRayにはSphereCastRayTestスクリプトを新しく作成し取り付けます。

BoxCastRayTestスクリプトとほぼ同じなので問題はないと思います。

ただ今回は球の中心位置とレイの方向を引数に与えるのではなくレイの飛ばす位置と飛ばす方向からRay型の変数を作成し、それを引数に与えるメソッドを使用しています。

Unityのプレイボタンを押して実行すると、

SphereCastを使ったサンプル例

上のような感じになります。

ちゃんと球での接触判定がされていることがわかります。

CapsuleCast

最後にCapsuleCastを使います。CapsuleCastはCapsuleのレイを飛ばして接触判定をすることが出来ます。

CapsuleCastも複数のオーバーロードメソッドが定義されています。

与える引数はカプセルを形成する両端の球の中心位置の2点、球の半径、レイの方向、レイの長さ、レイヤーマスク等です。

それではサンプルを作成していきましょう。

ヒエラルキー上で右クリック→3D Object→Capsuleを選択し、名前をCapsuleRayとします。

CapsuleRayのY軸の回転を変更し、TargetCubeの方向を向くようにします。

CapsuleRayにはCapsuleCastRayTestスクリプトを作成し取り付けます。

Physics.CapsuleCastの引数には作成したCapsuleRayのオブジェクトの形状と合わせたレイの形を作成する為、CapsuleRayの中心位置から上と下の位置を計算し、それをカプセルを形成する二つの球の中心位置として渡しています。

OnDrawGizmosメソッドではレイを疑似的に視覚化する為、二つのワイヤフレームの球を表示しています。

Unityのプレイボタンを押して実行すると、

CapsuleCastを使ったサンプル例

上のようになります。

カプセル状のレイが飛んでいるのがわかりますね。(^^)/

似たメソッド

BoxCast、SphereCast、CapsuleCastには似たようなメソッド名のBoxCastAll、BoxCastNonAlloc、SphereCastAll、SphereCastNonAlloc、CapsuleCastAll、CapsuleCastNonAllocがあります。

BoxCastAll等はBoxCast等と違い、レイと接触した情報(RaycastHit)を全て取得する事が出来ます。

接触した相手の全ての情報を使って何らかの処理をしたい時はBoxCastAllメソッドを使用すると便利です。

BoxCast等は接触した相手がいるかどうかのbool値を返しますが、BoxCastAll等は接触した全ての相手の情報であるRaycastHit型の配列を取得出来ます。

用途としてはFPSゲーム等のショットガンで敵を打った時に複数の接触相手に攻撃を与える時等に使えます。

実際に使った例は『終わりに』の項目のリンク先の記事にあります。

BoxCastNonAlloc等はBoxCastAllメソッドとほぼ同じ機能ですが、引数にRaycastHit型の配列を指定しそこにデータを保持し、戻り値は接触した相手の数が返ってきます。

BoxCastNonAlloc等はBoxCastAll等と違ってゴミを発生させないみたいです。

ということは全データを取得する時はNonAlloc系の方がいいんですかね?

終わりに

LinecastやRaycastは使う機会が多いですが、厚みのあるレイも使えるようにしておくと見えない弾丸を飛ばして当たり判定をする時など弾の厚みのレイを飛ばして判定という事が出来ます。

そこら辺は

FPSゲームで銃を撃った時に敵との当たり判定をする機能を作成していきます。銃の向きにレイを飛ばしレイが敵に当たった時に敵を削除するようにします。

の記事で実際に使っているので参照してみてください。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます