Unity - Raycaster:Ray を飛ばしてクリックやドラッグをしたオブジェクトを検出し、イベントを発生させる -
初めに
Raycaster とは、Ray(光線)をcast(投射)したとき、Ray になにかがぶつかったことを検出する仕組みです。例えば、クリックした場所から Ray を飛ばすことで、クリックした場所にあるオブジェクトを取得することができます。この記事では、Raycaster についてまとめます。
Index
Raycaster
Ray とは
Raycaster を扱うとき Ray が必要になります。Ray について知りたい方は以前、記事にまとめたのでそちらからご覧ください。
Raycaster とは
Raycaster とは、EventSystem で用いられる Ray(光線)をcast(投射)したとき、Ray になにかがぶつかったことを検出することができる仕組みです。
使用するには EventSystem が必要になります。
fineworks-fine.hatenablog.com
Raycaster の種類
Raycaster には次の種類があります。
Raycaster | 説明 |
---|---|
Graphic Raycaster | UI 要素で使用し、キャンバス上で有効で、キャンバス内を検索します |
Physics Raycaster | 3D 物理要素で使用します |
Physics 2D Raycaster | 2D 物理要素で使用します |
Graphic Raycaster
Graphic Raycaster とは
Graphic Raycaster は UI 要素に対して使用します。Canvas オブジェクトにGraphic Raycaster コンポーネントをつけて使用します。(Canvas を生成するとはじめからついています。)
Canvas オブジェクトへの Raycast(レイキャスト)に用いられます。Graphic Raycaster は Canvas 上にあるボタン等のUIを監視し、どれにタッチされたかを判定しています。
機能 | 説明 |
---|---|
Ignore Reversed Graphics | false だとRaycaster のほうを向いていないオブジェクトの判定が取れる |
Blocked Objects | レイキャストをブロックするオブジェクトを選択する (None : なし、Two D : 2D、Three D : 3D、All : すべて) |
Blocking Mask | レイキャストをブロックするオブジェクトがあるレイヤーを選択する |
Raycast Target
各 UI 要素のコンポーネントにある Raycast Target が true であれば、Ray がぶつかったことを検出できます。
Physics Raycaster
Phisics Raycaster とは
3Dオブジェクトに対して使用します。Camera オブジェクトに追加して使用します。
機能 | 説明 |
---|---|
Event Mask | Raycast target にする Layer を選択できる |
Max Ray Intersections | Ray の交わりが検出できる最大数 |
Physics.Raycast
Physics.Raycast を使うことで Ray を投射し、ぶつかったオブジェクトの情報を取得することができます。
public static bool Raycast (Vector3 origin, Vector3 direction, float maxDistance= Mathf.Infinity, int layerMask= DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction= QueryTriggerInteraction.UseGlobal);
引数 | 説明 |
---|---|
origin | ワールド座標でのレイの開始地点 |
direction | レイの方向を表すベクトル |
maxDistance | レイが衝突を検知する最大距離 |
layerMask | レイヤーマスクはレイキャストするときに選択的に衝突を無視するために使用します |
queryTriggerInteraction | トリガーに設定されているものも検索対象にするか |
(注意点)
- origin と directionで指定した Ray の始点と方向は、Ray そのものを引数にすることも可能です。
- Physics.Raycast は bool 関数のため、返り値は true/false です。Ray がぶつかったオブジェクトの情報は RaycastHit で取得します。(詳細は下記の使用例で説明)
(使用例の1つ)
クリックしたオブジェクトの名前をログに表示させる
private void Update () { //メインカメラ上のマウスカーソルのある位置からRayを飛ばす Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)){ //Rayが当たるオブジェクトがあった場合はそのオブジェクト名をログに表示 Debug.Log(hit.collider.gameObject.name); } }
Ray がオブジェクトにぶつかったら Physics.Raycast が true になり、if文の中に入ります。その際、Ray を発射するときに参照を渡した RaycastHit の hit に衝突したオブジェクトの情報が入っています。RaycastHit で読み取れる情報は下のドキュメントをご覧ください。
docs.unity3d.com
Physics.Raycast のドキュメントに他の使用例がいくつか紹介されています。
docs.unity3d.com
Eventの設定の仕方
次の手順で3Dオブジェクトに Event を追加できます。
- カメラオブジェクトにAdd Component>Event>Physics Raycaster を追加
- 3DオブジェクトにAdd Component>Event>Event Triggerを追加
- 3DオブジェクトにCollider がついていなければ追加
- Event TriggerのAdd New Event Typeで Event Type を追加し、Event を追加する
- Hierarchy にEventSystem を追加
Physics Raycaster で Ray を管理し、Event System でユーザーからの入力を管理しています。それらが Ray が3Dオブジェクトの Collider にぶつかったことを検出し、Event Trigger で設定した関数を呼び出すという仕組みです。
Event Type では、イベント発生のタイミングが指定できます。Event Type は次の種類があります。
EventType | 説明 |
---|---|
Pointer-- | ポインターが条件を満たしたとき Enter:オブジェクトに乗ったとき Exit:オブジェクトから離れたとき Down:オブジェクトを押下したとき Up:押下状態からはなしたとき Check:オブジェクト上で押下し、同一のオブジェクト上で離したとき |
Drag | オブジェクトがドラッグされている間 |
Drop | ドラッグされてきた他のオブジェクトが、範囲内でドラッグ解除されたとき |
Scroll | オブジェクトの範囲内でマウスホイールをスクロールしたとき |
UpdateSelected | 選択中のオブジェクトで毎フレーム発生 |
Select | オブジェクトが選択されたとき |
Deselect | オブジェクトの選択状態が解除されたとき |
Move | 選択状態で方向キーの入力があったとき |
InitializePotentialDrag | ドラッグ対象をクリックしたとき |
BeingDrag | ドラッグを開始したとき |
EndDrag | ドラッグが終了したとき |
Submit | サブミットボタンが押されたとき submit は提出を意味する。デフォルトはリターンキー(Enter) |
Cancel | キャンセルボタンが押されたとき デフォルトはエスケープキー |
Event Type 選択後は、Button と同じように、呼び出される関数を指定してイベントを設定できます。
Physics 2D Raycaster
Physics Paycaster(3Dの場合)との違い
基本的な使い方は同じですが、違う部分もあります。細かい違いは下記のようなものがあります。
- Collider ではなく Collider2Dを使用する必要がある
- Physics.Raycast ではなく Physics2D.Raycast を使う
Physics2D.Raycast
public static RaycastHit2D Raycast (Vector2 origin, Vector2 direction, float distance= Mathf.Infinity, int layerMask= DefaultRaycastLayers, float minDepth= -Mathf.Infinity, float maxDepth= Mathf.Infinity);
基本的には、Physics.Raycast と同じです。
Physics.Raycast と違う部分を紹介します。
- minDepth と maxDepth が追加
- origin, direction を Ray で指定できない
- (最重要)返り値が違う
minDepth と maxDepth が追加されていますが、これは Ray が衝突する z 座標の範囲を指定できます。(多分、使うことはないと思います。)
3Dの場合、origin, direction を Ray でも指定できましたが、2Dの場合はできないようです。
最も大きな違いは返り値が違います。
返り値 | ||
---|---|---|
Physics.Raycast | bool | |
Physics2D.Raycast | RaycastHit2D |
3Dの場合と違い、下のような記述が可能になります。
RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction, maxDistance, layerMask);
最後に
Raycaster についてまとめました。Raycast を扱うには必要なコンポーネントやオブジェクトが多く分かりづらい部分もあります。しかし、丁寧にやらないとオブジェクトが重なったとき、クリックしたいオブジェクトが反応しないようなことが起きますので、注意しましょう(自戒)。