UnityUnityメモ

「UnityでRaycastを使いこなそう!壁に当たると「Hit」を表示するスクリプト

Unity

1. はじめに

Unityでゲームを作るとき、オブジェクト同士の衝突を検知したり、特定のイベントをトリガーする方法はいくつかあります。その中でも「Raycast」はとても便利な機能です。Raycastを使うと、目に見えない光線のようなものを飛ばして、その進路上にあるオブジェクトを検知できます。

例えば、プレイヤーが壁に近づいたときに「壁に当たったよ!」と表示したり、敵キャラクターがプレイヤーを見つけたときにアクションを起こす、といった場面で活用できます。


この記事では、以下のことを学べます:

  • Raycastの基本的な使い方
  • スクリプトでオブジェクトが壁に当たるのを検知する方法
  • Unityのコンソールに「Hit」を表示する仕組み

初心者の方でも安心して進められるよう、具体的な手順を丁寧に説明していきます。最後まで進めることで、Raycastの基本がしっかりと理解できるはずです。

Raycastを使って、シンプルだけど実用的なスクリプトを作ってみましょう!

Unityを触ったことがないという方はコチラの記事から見てみてください!



2. シーンの準備

このセクションでは、UnityでRaycastを使う準備として、必要なオブジェクト(Cube、床、壁)をシーンに配置します。以下の手順に従って設定を進めていきましょう!


1. Cube(プレイヤー)を配置する

  1. Hierarchyウィンドウで右クリックします。
  2. メニューから「3D Object」→「Cube」を選択します。
    → シーンにCubeが追加されます。
  3. Cubeの名前を「Player」に変更します。
    • Inspectorウィンドウで名前を変更するか、Hierarchy内のCubeを右クリックして「Rename」を選んで変更します。
  4. 必要であればCubeの位置を調整します。デフォルトの位置(X: 0, Y: 0.5, Z: 0)で問題ありません。

2. 床を配置する

  1. 再びHierarchyウィンドウで右クリックします。
  2. 3D Object」→「Plane」を選択します。
    → シーンに大きな床が追加されます。
  3. Planeの位置を確認して、(X: 0, Y: 0, Z: 0)に設定します。
    → Cubeが床の上に置かれている状態になります。

3. 壁(Wall)を配置する

  1. Hierarchyウィンドウで右クリックし、「3D Object」→「Cube」を選択します。
    → 新たにCubeが追加されます。
  2. Cubeの名前を「Wall」に変更します。
  3. Inspectorウィンドウで「Scale」を以下のように設定し、壁の形状を作ります。
    • X: 1
    • Y: 4
    • Z: 4
  4. 壁を適切な位置に移動します。例えば、以下のような座標に設定します:
    • Position: (X: 3, Y: 2, Z: 0)
      → 壁がPlayerの右側に配置されます。

確認ポイント

  • 「Player」Cubeが床の上に置かれていますか?
  • 「Wall」Cubeがプレイヤーの右側に配置されていますか?
  • 床、Player、Wallの位置がすべて正しく設定されているか、シーンビューで確認してください。

これでシーンの準備は完了です!次のステップでは、Raycastを使ったスクリプトを作成し、壁への当たり判定を行います。




3. Raycastスクリプトの作成

それでは、Raycastを使って壁に当たったことを検知し、コンソールに「Hit」と表示するスクリプトを作成していきます。このセクションでは、スクリプトの作成からコードの詳細な説明までを解説します。

スクリプト「CubeMove」を作成

  1. スクリプトファイルを作成
    • 「Project」ウィンドウで右クリックして、「Create」→「C# Script」を選択します。
    • スクリプトの名前を「CubeMove」と設定してください。
  2. スクリプトをアタッチ
    • 作成した「CubeMove」スクリプトを、「Hierarchy」ウィンドウの「Player」オブジェクト(Cube)にドラッグ&ドロップしてアタッチします。

スクリプトコードの記述

次に、以下のコードを「CubeMove.cs」に入力してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeMove : MonoBehaviour
{
    // Rayの距離と移動速度を設定
    private float rayDistance = 1.0f;
    private float speed = 1.0f;

    void Update()
    {
        // Rayを飛ばす位置をCubeの少し右側に設定
        Vector3 rayPosition = transform.position + new Vector3(0.5f, 0.0f, 0.0f);
        
        // 右方向にRayを作成
        Ray ray = new Ray(rayPosition, Vector3.right);
        
        // デバッグ用にRayを可視化
        Debug.DrawRay(rayPosition, Vector3.right * rayDistance, Color.red);
        
        // Raycastで当たり判定
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, rayDistance))
        {
            // 壁に当たったかどうかを確認
            if (hit.collider.name == "Wall")
            {
                Debug.Log("Hit");
            }
        }

        // キーボード入力でCubeを移動させる
        float moveX = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
        float moveZ = Input.GetAxis("Vertical") * Time.deltaTime * speed;
        transform.position = new Vector3(
            transform.position.x + moveX, 
            transform.position.y, 
            transform.position.z + moveZ);
    }
}

コードの詳細解説

1. Rayの設定

  • Vector3 rayPosition
    Cubeの右側にRayを飛ばすように位置を調整します。new Vector3(0.5f, 0.0f, 0.0f)でCubeの右側に0.5ユニットずらしています。
  • Ray ray = new Ray(rayPosition, Vector3.right);
    Rayを右方向(Vector3.right)に飛ばすように設定しています。
  • Debug.DrawRay(rayPosition, Vector3.right * rayDistance, Color.red);
    Rayを赤い線で可視化することで、シーンビュー上でどの方向にRayが飛んでいるか確認できます。

2. Raycastの判定

  • Physics.Raycast(ray, out hit, rayDistance)
    Rayが指定した距離内でオブジェクトに当たったかどうかを判定します。out hitで衝突情報を取得できます。
  • hit.collider.name == "Wall"
    衝突したオブジェクトが「Wall」という名前であるかを確認します。この名前が一致した場合に「Hit」をコンソールに表示します。

3. Cubeの移動

  • Input.GetAxis("Horizontal")Input.GetAxis("Vertical")
    キーボードの矢印キーやWASDキーでCubeを移動させるためのコードです。Time.deltaTimeを掛けることで、フレームレートに依存しない滑らかな移動を実現しています。

次のステップでは、このスクリプトを使ってテストプレイを行い、実際に「Hit」が表示されるか確認します。



4. スクリプトを動かしてみよう

ここまでで、シーンの準備とスクリプトの作成が完了しました。次はいよいよ、作成したスクリプトを実行して「Hit」の表示を確認してみましょう!


テストプレイの準備

  1. シーンを保存する
    念のため、作業中のシーンを保存しておきましょう。「File」メニューから「Save」をクリックし、シーンに名前を付けて保存します(例:RaycastDemo)。
  2. プレイモードを開始する
    Unityエディターの上部にある再生ボタン(▶)をクリックしてプレイモードに入ります。

実際に動かしてみる

  1. Cubeを移動させる
    キーボードの矢印キーまたは「W」「A」「S」「D」キーを使って、Cube(Player)を動かしてみましょう。
  2. 壁に近づける
    Cubeを壁(Wall)の方に移動させ、壁に接近するまで進んでみてください。
    壁にぶつかると、コンソールに「Hit」と表示されるはずです。

確認するポイント

  • コンソールの表示
    Unityエディター下部にある「Console」タブを開き、スクリプトが正常に動作しているか確認しましょう。壁に当たると「Hit」というログが表示されます。
  • Rayの可視化
    スクリプト内でDebug.DrawRayを使用しているので、プレイモード中に赤い線が描画されます。この線がRaycastの向きを示しています。もしRayが壁を検知していない場合、方向や距離の設定を見直しましょう。

動作がおかしい場合のチェックリスト

  1. 壁の名前を確認
    壁オブジェクトの名前が「Wall」になっていることを確認してください。スクリプトは名前で判定しています。
  2. 壁にColliderがついているか確認
    壁(Wall)にColliderコンポーネントがアタッチされているか確認してください(通常はCubeを配置した時点で自動的に設定されます)。
  3. Rayの向きと距離を確認
    スクリプトでRayが適切な方向に飛んでいるか、距離が足りているかを確認してください。
    必要であれば、以下のコードを調整してみてください:
    private float rayDistance = 1.5f; // 距離を調整

これでスクリプトを動かす作業は完了です!正しく動作していれば、壁にぶつかった時に「Hit」が表示され、Rayの仕組みを理解できたはずです。次のステップでは、さらに応用例や他の使い方を学んでいきましょう!



よくある質問

Q
Raycastが反応しない場合はどうすればいいですか?
A

Raycastが正しく反応しない場合、以下の点を確認してください:

  • オブジェクトの名前: スクリプト内で if (hit.collider.name == "Wall") として名前を直接指定しています。壁のオブジェクト名が「Wall」になっているか確認してください。
  • Rayの方向と位置: Debug.DrawRay を使ってRayの位置や方向が正しいかを可視化できます。表示がずれている場合は rayPositionVector3.right を調整しましょう。
  • Colliderの設定: 壁のオブジェクトにCollider(例: Box Collider)がアタッチされているか確認してください。また、Colliderが「Is Trigger」にチェックされているとRaycastに反応しない場合があります。
Q
他のオブジェクトにも対応させたい場合はどうすればいいですか?
A

スクリプトを修正して、名前ではなくタグで判定する方法を使用するのがおすすめです。たとえば、壁のオブジェクトに「Wall」というタグを付けて以下のように書き換えます:

if (hit.collider.CompareTag("Wall"))
{
Debug.Log("Hit");
}

この方法なら、同じタグが付いた複数のオブジェクトに対応できます。タグはInspectorウィンドウで簡単に設定できます。

Q
壁以外の方向にもRaycastを使いたい場合は?
A

Rayの方向を変更するだけで、別の方向にも使用できます。例えば、上方向にRayを飛ばしたい場合は以下のように修正します:

Ray ray = new Ray(rayPosition, Vector3.up);
Debug.DrawRay(rayPosition, Vector3.up * rayDistance, Color.green);

このコードでは、上方向(Y軸)にRayを飛ばし、デバッグ用の線は緑色で表示されます。方向を自由に変更して、ゲームの仕様に合わせた動きを作りましょう。

おすすめのアセット

「Hot Reload – Edit Code Without Compiling」は、Unityでコードを編集する際に、ビルドや再コンパイルを行わずに即時に変更を反映できる便利なツールです。これにより、作業中の中断を最小限に抑え、開発速度を大幅に向上させることができます。

特に大規模なプロジェクトや頻繁にコードを変更する場合、毎回のコンパイル時間が省けるのは大きなメリットです。また、エディターやランタイムでの動作を確認しながら開発が可能なため、リアルタイムでのフィードバックが得られます