Unity

【Unity】Raycastの使い方【当たり判定・距離判定・可視化】

この記事について

この記事では、UnityでRaycastを使った当たり判定と可視化方法を解説します。Colliderとの違いや、実際にコードでどう使うかをまとめました。

この記事で分かること

  • Raycastの基本的な使い方(Physics.Raycast / RaycastHit)
  • Raycastで距離を測定する方法
  • Ray構造体(Ray)を使った判定方法
  • Rayをシーンビューで可視化する方法(Debug.DrawRay)
  • Rayを前方に3本飛ばす方法
  • Rayを360度飛ばす方法

ColliderとRaycastの違い

  • Collider: 物体同士の衝突判定(物理的にぶつかったとき)
  • Raycast: 始点から方向に「線」を飛ばして当たり判定を取得

Colliderとは?

Colliderについては以下の記事を参考にしてください。

Raycastとは?

Raycast は、始点から特定の方向に「見えない線」を飛ばし、その線上でオブジェクトに当たるかどうかを調べる仕組み です。

  • 足元判定 → 下方向にRayを飛ばし、地面に接地しているか判定
  • 銃の照準 → 前方にRayを飛ばして当たった敵を判定
  • 敵AIの視界 → Rayを扇状や360度に飛ばすことで「見える範囲」を表現

RaycastHitを使って情報を取得する

Raycastの基本の書き方はこのようになっています。

Physics.Raycast(始点, 方向, out hit, distance);
out hit とは?
  • out hit は「Rayがヒットしたときの情報を入れる箱」
  • もし何かに当たれば、その情報が hit 変数に保存されます。
  • 当たらなければ if の中は実行されません。
取得できる代表的な情報
  • hit.collider.name // 当たったオブジェクトの名前
  • hit.point  // Rayが当たったワールド座標
  • hit.normal // 当たった面の法線ベクトル(傾き)
  • hit.distance // 始点からヒット地点までの距離

Raycastの使い方

Raycastの準備

まずはヒエラルキーで右クリックをしてCubeを2つ用意します。
・「右クリック」→「3Dオブジェクト」→「Cube」
・2つのCubeに「BoxCollider」、右側のCubeに「Rigidbody」
・左側のCubeのY軸を90度回転する

次にスクリプトを作成して左のCubeにアタッチしてください。

Raycastで当たり判定と距離測定

以下のコードでは、オブジェクトの前方にRayを飛ばし、何かに当たったら情報をログに出力します。

using UnityEngine;

public class Raycast_Script : MonoBehaviour
{
    // Rayを飛ばす距離
    [SerializeField] private float rayDistance = 2f;

    private void Update()
    {
        // RaycastHit には当たったオブジェクトの情報が入る
        RaycastHit hit;

        // transform.position から transform.forward に向かってRayを飛ばす
        if (Physics.Raycast(transform.position, transform.forward, out hit, rayDistance))
        {
            Debug.Log("当たった相手: " + hit.collider.name);
            Debug.Log("ヒットまでの距離: " + hit.distance);
        }
    }
}

実行してみると、Rayが当たっているのがわかりますね。

Raycastをシーンビューで可視化(Ray構造体を利用)

Ray構造体」を使うと、始点と方向をまとめて扱えます。また、シーンビューでRayを確認する場合は「Debug.DrawRay()」を使用します。

using UnityEngine;

public class Raycast_Script : MonoBehaviour
{
    // Rayを飛ばす距離
    [SerializeField] private float rayDistance = 2f;

    private void Update()
    {
        // Ray構造体を作成
        Ray ray = new Ray(transform.position, transform.forward);
        // RaycastHit には当たったオブジェクトの情報が入る
        RaycastHit hit;

        // transform.position から transform.forward に向かってRayを飛ばす
        if (Physics.Raycast(ray, out hit, rayDistance))
        {
            Debug.Log("当たった相手: " + hit.collider.name);
            Debug.Log("ヒットまでの距離: " + hit.distance);
        }

        // 赤い線をシーンビューで描画
        Debug.DrawRay(ray.origin, ray.direction * rayDistance, Color.red);
    }
}

実行してみると、Gameビューには表示されませんがSceneビューで赤いRayの線を確認できましたね。確認のためにも実装はしておいた方が良さそうです。

Rayを3本飛ばす(Labelで線の判定)

視野を広く持たせたい場合は、複数方向にRayを飛ばすことができます。飛ばし方としてはdirectionを3つ作成してforeachでループさせる手法です。

using UnityEngine;

public class Raycast_Script : MonoBehaviour
{
    [SerializeField] private float rayDistance = 2f;

    private void Update()
    {
        // 方向ベクトルとラベルをセット
        (string label, Vector3 dir)[] rays =
        {
            ("Forward", transform.forward),
            ("Forward+Right", (transform.forward + transform.right).normalized),
            ("Forward-Right", (transform.forward - transform.right).normalized),
        };

        foreach (var ray in rays)
        {
            if (Physics.Raycast(transform.position, ray.dir, out RaycastHit hit, rayDistance))
            {
                Debug.Log($"Ray [{ray.label}] でヒット: {hit.collider.name}");
            }

            Debug.DrawRay(transform.position, ray.dir * rayDistance, Color.red);
        }
    }
}

実行してみると、3本のRayがそれぞれ当たった時のみ判定していますね。また、Labelのおかげでどれが当たったのかわかりやすいですね。

Rayを360度に飛ばす(レーダー風)

敵キャラや探索用のレーダーに便利な方法です。

using UnityEngine;

public class Raycast_Script : MonoBehaviour
{
    [SerializeField] private float rayDistance = 10f;
    [SerializeField] private int rayCount = 36; // 10度刻みでRayを飛ばす

    private void Update()
    {
        for (int i = 0; i < rayCount; i++)
        {
            // Y軸周りに回転
            float angle = i * 360f / rayCount;
            Vector3 dir = Quaternion.Euler(0, angle, 0) * transform.forward;

            if (Physics.Raycast(transform.position, dir, out RaycastHit hit, rayDistance))
            {
                Debug.Log($"Ray[{i}] (角度: {angle:F1}°) ヒット: {hit.collider.name}");
            }

            // 可視化
            Debug.DrawRay(transform.position, dir * rayDistance, Color.cyan);
        }
    }
}

実行してみると、360度分のRayが飛んでいますね。360度にしないにしても角度を制限すれば他にも応用ができそうです。

まとめ

  • Colliderは物体同士の衝突判定
  • Raycastは線での当たり判定ができる
  • Debug.DrawRay でシーンビュー可視化
  • Ray構造体を使った書き方も便利
  • 複数Ray(3本、360度)で視界・レーダーを表現できる