Amazon11/12まで!スマイルSale開催中!セール会場へ

UnityのRaycastの使い方|3Dの当たり判定と当たらない原因

UnityのRaycastの使い方

UnityのRaycastは、ある位置から特定の方向へ見えない線を飛ばし、Colliderに当たるかを調べる機能です。

前方の壁を調べる、照準の先にある物を判定する、といった処理に使えます。

3DではPhysics.Raycast、2DではPhysics2D.Raycastを使います。

見た目が平面的なゲームでも、使用しているColliderが3D用ならPhysics側です。

最初に、この組み合わせを確認してください。

Unity 6.0の公式APIを2026年10月26日に照合しています。

以下は確認用のコードと手順で、今回Unityでのコンパイル、実行、画面確認は行っていません。

目次

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は確認用の線であり、製品内のレーザー表現を描画する機能ではありません。

この例は表示確認のためUpdateで判定しますが、移動と物理計算のタイミングは別途考慮が必要です。

線の表示条件はDebug.DrawRay、レイヤー名からの変換はLayerMask.GetMaskの公式仕様に基づきます。

Cubeを置いて動作を確認する

  1. 空のGameObjectを原点に置き、回転を0にします。
  2. Cubeを位置(0, 0, 5)付近に置き、Box Colliderを有効にします。
  3. 空のGameObjectへスクリプトを追加し、Distanceを10にします。
  4. 再生して、Hit Object NameにCubeの名前が出るか確認します。
  5. 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を検出できないケースにも注意します。

自分自身の中心から線を出して外殻を調べようとするより、開始位置を外へ置くか、目的に合う別の判定方法を検討します。

TransformでColliderを移動した直後だけ判定がずれる場合は、物理エンジンへの反映時点も確認します。

autoSyncTransformsが無効な場合、変更の自動同期はFixed Updateの物理シミュレーション前に行われます。

同じ処理の中でTransformを変更し、直後に新しい位置へRaycastする必要がある場合は、判定前のPhysics.SyncTransforms()を検討します。

これはTransformの変更を物理エンジンへ反映する操作で、レイヤーやTriggerの条件を直すものではありません。

自動同期を常時有効にして変更と判定を繰り返すと、処理負荷が増える場合があります。

設定を一律に変える前に、移動後の同期時点と判定の順序を確認してください。

仕様はautoSyncTransformsとSyncTransformsを参照しています。

スポンサーリンク

線ではなく太さが必要な判定は別に考える

細い線1本の判定では、キャラクターの幅や足元全体を表現できません。

前進できる隙間を調べたいなら、SphereCastやCapsuleCastなど、形状を持つ判定が適する場合があります。

まずRaycastで位置・方向・距離を理解し、その後で用途に合う形へ広げると整理しやすくなります。

今回のサンプルも、物理的に移動を止める処理は含まず、前方に何があるかを確認するためのものです。

ほかの症状はUnityのエラー一覧で、症状別に先に確かめることをまとめています。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Unityのおすすめ書籍

開発PCの選び方

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

須澤 元貴のアバター 須澤 元貴 代表社員

MOTOKI合同会社 代表社員。
アニメ・映像業界とゲーム業界で、2D・UI・3D・アニメーション制作、映像編集、ツール制作に携わってきました。
現在はWordPressを中心にWebサイトの制作とカスタマイズを手がけています。
著書に『Unity デザイナーズ・バイブル』『Unityゲーム プログラミング・バイブル 2nd Generation』(ボーンデジタル)。
岡山県出身、埼玉県在住。

目次