【Unity2D】2点間に障害物がないか検知する


はじめに

こんばんは.ディジコンアドベントカレンダー2021 12月17日担当のmimiです.

adventar.org


Unityで何かを作っているとき,2点間に障害物があるかどうかを知りたいことがあります.
例えば,「壁の向こうからではアイテムを取れないようにしたい」,「障害物の後ろにいれば敵に発見されないようにしたい」という場合です.

今回は2点間に障害物がないか検知してみます.以下が方針です.
①Raycastを用い,1点からもう片方の1点に光線を放つ.
②もし光線が何かにぶつかれば障害物があり,何にもぶつからなければ障害物がないと分かる.

Raycastについては前回紹介しました.レーザーポインターのようなもので,機能としてその光線が当たった位置や当たり判定を持つオブジェクトの情報を取得することができます.
分かり易いので「光線」と表現しています.

mimi2021.hatenablog.com

やってみる

まず,障害物となりえるオブジェクトにコライダー(当たり判定)を付けておきます.(Box Collider 2Dなど)
これがないとRaycastに反応されません.

次にスクリプトを書いていきます.
※今回は2Dを想定しています.

Vector2 point1 = new Vector2(2, 10);
Vector2 point2 = new Vector2(10, 30);

RaycastHit2D result = Physics2D.Raycast(point1, (point2 - point1), (point2 - point1).magnitude);

if(result.collider == null)
{
 Debug.Log("障害物はありません");
}

else
{
 Debug.Log("障害物があります");
}

これで完成です.

RaycastHit2D result = Physics2D.Raycast(point1, (point2 - point1), (point2 - point1).magnitude);
でpoint1からpoint2にかけて光線を飛ばし,当たったオブジェクトを変数resultに代入しています.もし道中何もなかったらここには何も入りません(nullになります)
if(result.collider == null)
で何にも当たらなかったことを確認し,そうであれば"障害物はありません"と表示します.

終わりに

今回のやり方では,開始地点となるオブジェクト自体にコライダー(当たり判定)が付いていると自分自身に当たるという問題があります.これを回避するためには,レイヤーマスクを指定して光線が障害物にしか当たらなくするなどといった工夫が必要です.


本日はここまでです.ありがとうございました.

【Unity2D】Raycastの紹介

はじめに

こんにちは.ディジコンアドベントカレンダー2021 12月2日担当のmimiです.
adventar.org


今回は,Unity2DのRaycastを紹介したいと思います.

Raycastとは(簡単に)

レーザーポインターのようなものです.その光線が当たった位置や当たり判定を持つオブジェクトの情報を取得することができます.

使い方

※今回記載しているのは2Dでの使用法です.3Dの場合は書き方が異なるので参考にしないでください.

以下の関数で光線を放ちます. RaycastHit2D型の戻り値があります.

Physics2D.Raycast (発射地点(Vector2型), 向き(Vector2型), 飛距離(float型));

※今回は理解しやすくするために,3つの引数のみを指定しています.他の引数では当たるオブジェクトのレイヤー指定などができます.
全ての引数はこちらに書かれています.

向き(Vector2型)に注意してください.これは光線の終着点ではありません.発射地点が(0,0)のとき,向き(Vector2型)が(1,1)でも(3,3)でも飛距離(float型)が同じなら同様の結果になります.


RaycastHit2D型の戻り値があるので,実際は以下のように使用します.

RaycastHit2D result = Physics2D.Raycast (発射地点(Vector2型), 向き(Vector2型), 飛距離(float型));

これにより,変数resultに光線が当たった位置やオブジェクトの情報が格納されます.
例えば,当たった位置はresult.pointで得られます.当たったオブジェクトの名前は,result.collider.gameObject.nameで得られます.

なお,光線を当てるためには当たる対象にコライダー(当たり判定)が付与されている必要があります. (例えば,BoxCollider2Dです)


光線は描画されないため,その軌跡を見るにはデバッグ機能を使用します.
以下が活用する関数です.

Debug.DrawRay (発射地点(Vector3型), 飛ぶベクトル(Vector3型) , 色(Color型), 描画時間(float型));

※こちらも他に引数があります.全ての引数はこちらに書かれています.

2つ目の引数に注意してください.Physics2D.Raycast() では方向とその長さをそれぞれ記入したのに対し,これは一つにまとめられています.発射地点から描かれる矢印(ベクトル)を描画する感じです.
Physics2D.Raycast()で放った光線をそのまま描画したい場合,例えば以下のように記述する必要があります.

Vector2 startPos = new Vector2(2, 10);
Vector2 endPos = new Vector2(10, 30);
float length = 10f;

//実際の光線
Physics2D.Raycast(startPos, (endPos - startPos), length);

//描画される光線
Debug.DrawRay(startPos, (endPos - startPos).normalized * length);

次回はこのRaycastを用いて,ステルスゲームにあるような敵の視線検知をしてみようと思います.お楽しみに!
本日はここまでです.ありがとうございました.