UnityでRaycastを使ってオブジェクトを検知する方法

Unity

はじめに

Unityでは、プレイヤーの前方にあるオブジェクトを検知したい場合があります。

今回は、Unity のPhysics.Raycastを使って、プレイヤーの前方にあるオブジェクトを検知する方法を紹介します。

Raycastを使うことで、指定した方向へRay(光線)を飛ばし、オブジェクトに当たったかどうかを確認できます。


Raycastとは

Raycastは、指定した位置から指定した方向へRayを飛ばし、その先にあるコライダーを検知する機能です。

例えば、プレイヤーの前方にあるオブジェクトを調べたり、床までの距離を調べたりするときなどに使用できます。

前回紹介したIs Triggerが「指定した範囲に入ったこと」を検知するのに対して、Raycastは「指定した方向にあるオブジェクト」を検知できます。


Raycastを使う準備

今回は、プレイヤーの前方にCubeを配置し、RaycastがCubeに当たったときにConsoleへログを表示します。

まず、Raycastを使用するオブジェクトを用意します。

今回は、これまで使用しているPlayerにスクリプトを追加します。

Projectウィンドウで右クリックし、

Create → C# Script

からスクリプトを作成します。

今回はRaycastTestという名前にします。


Raycastを記述する

RaycastTestを開き、次のように記述します。

using UnityEngine;
using UnityEngine.InputSystem;

public class RaycastTest : MonoBehaviour
{
    [SerializeField] private Camera rayCamera;

    void Update()
    {
        if (Mouse.current.leftButton.wasPressedThisFrame)
        {
            if (Physics.Raycast(rayCamera.transform.position, rayCamera.transform.forward, out RaycastHit hit, 10f))
            {
                Debug.Log("オブジェクトを検知しました:" + hit.collider.name);
            }
        }
    }
}

[SerializeField]を付けることで、Inspectorから使用するカメラを指定できます。

スクリプトをPlayerに追加すると、InspectorにRay Cameraが表示されます。

ここにMain Cameraをドラッグ&ドロップします。

この処理では、マウスの左クリックをしたときに、指定したカメラの位置から前方へRayを飛ばします。

Mouse.current.leftButton.wasPressedThisFrameで、左クリックされた瞬間を検知しています。

クリックするとPhysics.Raycastが実行され、指定したカメラの前方10m以内にあるコライダーを検知します。

Physics.Raycastの主な部分は次の通りです。

  • rayCamera.transform.position:Rayを飛ばす開始位置
  • rayCamera.transform.forward:Rayを飛ばす方向
  • hit:Rayが当たったオブジェクトの情報
  • 10f:Rayを飛ばす距離

今回は、左クリックしたときにMain Cameraから前方10mまでを検知する設定にしています。


Rayを見えるようにする

Raycastはそのままだと、Sceneビュー上でRayが見えません。

確認しやすくするため、Debug.DrawRayを追加します。

using UnityEngine;
using UnityEngine.InputSystem;

public class RaycastTest : MonoBehaviour
{
    [SerializeField] private Camera rayCamera;

    void Update()
    {
        if (Mouse.current.leftButton.wasPressedThisFrame)
        {
            Debug.DrawRay(
                rayCamera.transform.position,
                rayCamera.transform.forward * 10f,
                Color.red,
                3f
            );

            if (Physics.Raycast(rayCamera.transform.position, rayCamera.transform.forward, out RaycastHit hit, 10f))
            {
                Debug.Log("オブジェクトを検知しました:" + hit.collider.name);
            }
        }
    }
}

Debug.DrawRayによって、クリックしたときに指定したカメラの位置から前方へ10mのRayが表示されます。

最後の3fは、Rayを表示する時間です。

今回は3秒間表示する設定にしています。

Sceneビューで確認すると、クリックしたタイミングでカメラから前方へ伸びるRayを確認できます。


Raycastでオブジェクトを検知して処理を実行する

次に、Raycastで検知したCubeをクリックすると回転するようにしてみます。

Playerの前方にCubeを配置し、Playボタンを押します。

Cubeに向かって左クリックすると、RaycastがCubeを検知します。

検知したオブジェクトはhit.collider.gameObjectで取得できます。

取得したオブジェクトに対してtransform.Rotateを使用すると、Cubeを回転させることができます。

RaycastTestを次のように変更します。

using UnityEngine;
using UnityEngine.InputSystem;

public class RaycastTest : MonoBehaviour
{
    [SerializeField] private Camera rayCamera;

    void Update()
    {
        if (Mouse.current.leftButton.wasPressedThisFrame)
        {
            Debug.DrawRay(
                rayCamera.transform.position,
                rayCamera.transform.forward * 10f,
                Color.red,
                3f
            );

            if (Physics.Raycast(rayCamera.transform.position, rayCamera.transform.forward, out RaycastHit hit, 10f))
            {
                hit.collider.gameObject.transform.Rotate(0f, 45f, 0f);
            }
        }
    }
}

左クリックしたときにRaycastがCubeを検知すると、CubeがY軸方向に45度回転します。

何度もクリックすると、そのたびに45度ずつ回転します。

このようにRaycastを使うことで、プレイヤーが見ているオブジェクトを検知して、そのオブジェクトに処理を実行することができます。


Raycastが当たらない場合

Raycastは、設定した方向と距離の範囲にあるコライダーを検知します。

そのため、CubeをRayの範囲から外すと検知されなくなります。

例えば、CubeをPlayerの横に移動すると、前方へ飛ばしているRayがCubeに当たらなくなるため、Consoleへのログも表示されません。

Rayがどの方向に、どこまで飛んでいるのか分からない場合は、Debug.DrawRayで確認できます。

SceneビューでRayを表示し、CubeがRayの範囲内にあるか確認してみましょう。

このように、Raycastで検知できない場合は、まずRayの方向・距離・対象の位置を確認すると原因を見つけやすくなります。


まとめ

今回は、UnityのPhysics.Raycastを使って、Main Cameraの前方にあるオブジェクトを検知する方法を紹介しました。

Raycastでは、Rayを飛ばす位置や方向、距離を指定することで、指定した範囲にあるコライダーを検知できます。

今回は左クリックしたときにRayを飛ばし、Cubeを検知した場合に処理を実行しました。

Raycastは、オブジェクトの検知をはじめ、視線方向にあるものの確認や、ゲーム内のさまざまな処理を実行するきっかけとして利用できます。