こんにちは、ともくんのゲーム作り部屋にようこそ!
このページでは、
「2DゲームでRaycastメソッドが使いたい!」
「マウスでオブジェクトをクリックする処理を行いたい!」
というお悩みの方に向けた内容となっています。
Unityでは、Raycastメソッドを使うことで、特定の地点からまっすぐに進む光線となるRayを飛ばして、コライダーの付いたオブジェクトとの当たり判定を作ることができます。
このRaycastメソッドは、2D用と3D用で少し使い方が異なっており、2D用のRaycastメソッドでは、Rayで当たったオブジェクト情報をRaycastHit2D型で受け取り、様々な処理を作ることができます。
例えば、マウスでクリックした場所にある2Dオブジェクトに対して、Raycastメソッドを使うことで、当たり判定の処理を作ることができます。
そこで、このページでは、Unityの2DゲームにおいてRaycastメソッドを使った当たり判定処理の作り方についてまとめていきます。
Raycastメソッドとは?
まずは、Raycastメソッドがどういうものなのか紹介していきます。
Rayを飛ばして当たり判定の処理を作れるメソッド
Raycastメソッドとは、冒頭でも解説した通り、Rayと呼ばれる光線を飛ばして、その先にあるオブジェクトとの当たり判定の処理を作ることができるメソッドです。
そもそもRayというのは、一定方向に真っ直ぐに進む光線を表している構造体のことです。
このRay構造体の中には、Vector3型のメンバ変数として、光線を飛ばす位置を決める「origin」と、飛ばす方向を決める「direction」の2つの値で光線が決められています。

Raycastメソッドは、このRayを飛ばした先に、コライダーの付いているオブジェクトがある場合、そのオブジェクト情報を取得することができるメソッドになっています。
ちなみに、光線上に2つのコライダーの付いているオブジェクトがある場合、手前にあるオブジェクトしか当たり判定を行うことが出来ないため、注意しておきましょう。
2DのRaycastと3DのRaycastは使い方が異なる
2DのRaycastメソッドの使い方は後ほどまとめていますが、3D用と2D用で少し使い方が異なっているため、注意しておきましょう。
具体的に説明すると、まず3Dゲーム用では、Physicsクラスの中のRaycastメソッドを使い、当たり判定のあるオブジェクト情報をRaycastHit型というもので取得します。
この3DのRaycastメソッドは、コライダーの付いているオブジェクトと当たったかどうかをbool型の値で返してくるので、if文を使って条件指定してその中で当たり判定の処理を作ることになります。

一方で、2Dゲーム用ではPhysics2DクラスのRaycastメソッドを使い、当たり判定のあるオブジェクト情報をRaycastHit2D型で取得します。
2DのRaycastメソッドは、当たり判定に関係なくRaycastHit2D型で値を返してきて、当たり判定があればオブジェクトの情報が中に入り、当たり判定が無ければnullになります。

特に注意すべき点として、2DのRaycastメソッドでは、「null」が返ってくる可能性があるので、nullでないかどうかのチェックが必要になってきます。
ちなみに、僕自身が3DのRaycastメソッドを知ってから、2Dで同じようにRaycastで当たり判定を作ろうとしたら、処理の作り方が異なり困ってしまったので、2Dと3Dで使い方が違う点に注意しておきましょう。
なお、3DでのRaycastメソッドの使い方は、以下のページでまとめていますので、良かったら参考にしてみてください。
2DでのRaycastメソッドの使い方
ここからは、2DでのRaycastメソッドの使い方について紹介していきます。
Physics2D.Raycastで光線を飛ばす
2DゲームでRaycastメソッドを使う場合、前述した通り、Physics2DクラスのRaycastメソッドを使い、以下のように記述することで、RaycastHit2D型で値を取得することができます。
Physics2D.Raycast(origin, direction, distance, layerMask, minDepth, maxDepth);origin:光線を飛ばし始める位置(Vector2型)
direction:光線を飛ばす方向(Vector2型)
distance:光線を飛ばす距離(float型)
layerMask:当たり判定を行うレイヤー(int型もしくはLayerMask型)
minDepth:Z座標の最小値(float型)
maxDepth:Z座標の最大値(float型)
なお、第3引数から第6引数は省略することができます。
まず、第1引数で光線を飛ばす開始位置、第2引数で光線を飛ばしたい方向をそれぞれVector2型で指定します。
この際に注意すべき点として、Ray構造体で定義されている光線を飛ばす場合、開始位置と方向はVector3型で管理されているため、2DのRaycastで使用する際はVector2型に変換して指定する必要があります。
次に、第3引数で光線を飛ばす距離をfloat型で指定して、省略した場合は「Mathf.Infinity」となり無限大になります。
第4引数は、レイヤーマスクと呼ばれる指定したレイヤーに含まれているオブジェクトだけを当たり判定にすることができるフィルター機能で、省略した場合は「DefaultRaycastLayers」となります。
第5引数と第6引数は、当たり判定の対象となるオブジェクトのZ座標(深度)を指定するもので、省略した場合はそれぞれ「-Mathf.Infinity」と「Mathf.Infinity」が入ります。
そして、以下のようにRaycastHit2D型の変数に直接Physics2D.Raycastの値を代入してあげることで、オブジェクト情報を受け取ることができます。
RaycastHit2D hit = Physics2D.Raycast(●●,●●);マウスでオブジェクトをクリックする処理
実際に、2DゲームでRaycastメソッドを使った処理として、以下のようにオブジェクトを複数配置しておき、マウスを使ってそれぞれのオブジェクトをクリックした場合に、そのオブジェクトが消去するという処理を作ってみます。

まず、それぞれの配置した丸いオブジェクトに対して、CircleCollider2Dを紐づけておきます。

次に、空のオブジェクトを作成して、以下のスクリプトをアタッチしていきます。
using UnityEngine;
public class Test : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルの位置からのカメラ奥に進む光線
RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction); // 光線に当たったオブジェクトを格納する処理
if (hit.collider != null)
{
Destroy(hit.collider.gameObject); // オブジェクトを消去する処理
}
}
}
}マウスをクリックした場合の中の9行目で、マウスのカーソルの位置から画面の奥に向かうRayを取得しています。
Input.mousePositionでカーソル位置のスクリーン座標を取得することができるので、これをScreenPointToRayメソッドでその位置からカメラの奥に進む光線になるRay構造体を取得しています。
そして、10行目でRaycastHit2D型の変数に、Physics2D.Raycastの値を代入しています。
先ほど取得したRay構造体は、メンバ変数の値がVector3型となっているため、Raycastの引数に指定する際は、頭に「(Vector2)」を付けて型を変換しています。
あとは、このRaycastHit2D型がnullで無い場合に、13行目でDestroyメソッドを使って、コライダーに紐づくオブジェクトを破壊するようにしています。
ちなみに、RaycastHit2D型ではcollider変数で、当たり判定のあるオブジェクトのコライダーを取得できるので、そこからgameObejctを使ってオブジェクトを指定しています。
これでゲームを実行してみると、

上記のように、マウスでクリックしたオブジェクトを消去することができています。
なお、同様の処理はPhysics2D.Raycast以外にも、EventSystemという機能でも作ることができるので、以下の記事も参考にしてみてください。
まとめ
このページでは、Unityの2DゲームにおけるRaycastメソッドの使い方についてまとめていきましたが、いかがでしたでしょうか?
Raycastメソッドとは、特定の地点からまっすぐに進む場所にあるオブジェクトとの当たり判定処理を作ることができるメソッドです。
2DゲームでRaycastを使う際は、3Dの場合とは異なり、直接RaycastHit2D型の変数にRaycastの値を代入して使うことになります。
そのため、nullチェックをしておかないと、エラーが発生する可能性があるため、注意しておきましょう。
最後までお読みいただきまして、ありがとうございました!











コメント