UnityのRaycastは、ある位置から特定の方向へ見えない線を飛ばし、Colliderに当たるかを調べる機能です。前方の壁を調べる、照準の先にある物を判定する、といった処理に使えます。
3DではPhysics.Raycast、2DではPhysics2D.Raycastを使います。見た目が平面的なゲームでも、使用しているColliderが3D用ならPhysics側です。最初に、この組み合わせを確認してください。
Raycastに必要な4つの情報
| 情報 | 意味 | 例 |
|---|---|---|
| origin | 線を飛ばす開始位置 | カメラやセンサーの位置 |
| direction | 線を飛ばす方向 | オブジェクトの前方 |
| maxDistance | 判定する距離 | 前方10単位 |
| layerMask | 判定対象のレイヤー | 壁や操作できる物だけ |
directionには、目的地のワールド座標をそのまま入れるのではなく、開始位置から見た方向を渡します。ある地点を狙うならtargetPosition – originから方向を求めます。距離を有限にしておくと、想定外の遠い物まで判定するのを避けやすくなります。
前方のColliderを調べるコード
ForwardRayExample.csという名前で保存し、空のGameObjectに追加します。Input Systemには依存しない例で、再生中に前方の判定結果をInspectorへ表示します。
using UnityEngine;
public class ForwardRayExample : MonoBehaviour
{
[SerializeField] private float distance = 10f;
[SerializeField] private LayerMask targetLayers = Physics.DefaultRaycastLayers;
[SerializeField] private string hitObjectName;
private void Update()
{
Vector3 origin = transform.position;
Vector3 direction = transform.forward;
float length = Mathf.Max(0f, distance);
bool found = Physics.Raycast(
origin, direction, out RaycastHit hit, length,
targetLayers, QueryTriggerInteraction.Ignore);
hitObjectName = found ? hit.collider.name : "なし";
float drawLength = found ? hit.distance : length;
Debug.DrawRay(origin, direction * drawLength,
found ? Color.green : Color.red);
}
}
Updateで調べるたびにConsoleへログを出すと、判定結果が大量に並びます。この例では、Hit Object Nameの表示だけを更新します。Debug.DrawRayは確認用の線であり、製品内のレーザー表現を描画する機能ではありません。
Cubeを置いて動作を確認する
- 空のGameObjectを原点に置き、回転を0にします。
- Cubeを位置(0, 0, 5)付近に置き、Box Colliderを有効にします。
- 空のGameObjectへスクリプトを追加し、Distanceを10にします。
- 再生して、Hit Object NameにCubeの名前が出るか確認します。
- SceneビューのGizmosを有効にし、線の方向を見ます。
次にCubeを横へ移動し、判定が「なし」へ変わるかを確かめます。さらにDistanceを2にすると、前方5付近のCubeには届かなくなります。方向、距離、Colliderの関係を1つずつ変えると、コードの意味を追いやすくなります。
LayerMaskはレイヤー番号そのものではない
判定対象を絞るときは、InspectorのTarget Layersでレイヤーを選びます。コードで指定するならLayerMask.GetMask(“名前”)などを使います。レイヤー番号の8と、8番レイヤーを表すビットマスクは同じ値ではありません。
この例はTriggerを無視する設定です。Triggerへも当てたいなら、QueryTriggerInteraction.Collideなど、用途に合う指定へ変更します。基本の引数、返り値、Triggerの扱いはUnity 6のPhysics.Raycastリファレンスで確認できます。
当たらないときに確認する順番
- Mesh Rendererだけでなく、Colliderが付いているか。
- ColliderとGameObjectが有効か。
- 2D用と3D用の物理APIを混ぜていないか。
- 開始位置と前方向が意図した位置・向きか。
- 判定距離とLayerMaskが対象を含んでいるか。
- Triggerを無視する設定になっていないか。
開始点がColliderの内部にある場合、そのColliderを検出できないケースにも注意します。自分自身の中心から線を出して外殻を調べようとするより、開始位置を外へ置くか、目的に合う別の判定方法を検討します。
線ではなく太さが必要な判定は別に考える
細い線1本の判定では、キャラクターの幅や足元全体を表現できません。前進できる隙間を調べたいなら、SphereCastやCapsuleCastなど、形状を持つ判定が適する場合があります。
まずRaycastで位置・方向・距離を理解し、その後で用途に合う形へ広げると整理しやすくなります。今回のサンプルも、物理的に移動を止める処理は含まず、前方に何があるかを確認するためのものです。
