スポンサーリンク
Unity C#・スクリプト実装

【Unity】クリック操作の作り方完全ガイド|移動・攻撃・弾発射・Raycastまで解説

Unity C#・スクリプト実装

Unityでゲームを作っていると、こんな操作を実装したくなることがあります。

  • クリックした敵を攻撃したい
  • クリックした場所へキャラクターを移動させたい
  • クリックで弾を発射したい
  • クリックしたオブジェクトを選択したい

ところが実際に調べ始めると、「Input」「Raycast」「ScreenToWorldPoint」など聞き慣れない用語が次々と登場し、どこから理解すればよいのか迷ってしまう方も少なくありません。

特にUnityのクリック操作は、単純にマウスのボタンを押したことを取得するだけでは完成しません。

例えば「クリックした敵を攻撃する」と言っても、Unityは最初からどの敵をクリックしたのかを知っているわけではないため、クリック位置とゲーム内のオブジェクトを結び付ける処理が必要になります。

私も最初にRaycastを学んだときは、「なぜクリックしただけなのに光線を飛ばすの?」と混乱した記憶があります。

しかし仕組みを一度理解してしまうと、クリック移動・オブジェクト選択・攻撃・弾発射など、多くのゲームシステムが同じ考え方で作れるようになります。

クリック操作はRPG、RTS、シミュレーション、脱出ゲーム、シューティングゲームなど、さまざまなジャンルで使われる基本技術です。

まずはクリック操作の全体像を整理しながら、一つずつ実装方法を確認していきましょう。


  1. 結論
  2. Unityのクリック操作はInputとRaycastで作る
    1. Inputは「クリックした」を取得する仕組み
    2. Raycastは「何をクリックしたか」を取得する仕組み
    3. ScreenToWorldPointとRaycastの違い
  3. Unityのクリック判定を実装する方法
    1. 左クリックを取得するサンプルコード
    2. 右クリックとホイールクリックを取得する方法
    3. クリック位置を取得する方法
  4. Unity Raycastの基本実装と仕組み
    1. Ray・RaycastHit・Physics.Raycastの役割
    2. Camera.ScreenPointToRayの使い方
    3. Raycastでクリックしたオブジェクトを取得する
    4. Raycastの流れを図解で理解する
  5. Unityでクリックしたオブジェクトを選択・攻撃する方法
    1. タグを使って敵だけ判定する
    2. クリックした敵を破壊するサンプル
    3. オブジェクト選択システムへ応用する方法
  6. Unityでクリック移動を実装する方法
    1. Raycastで移動先座標を取得する
    2. Transform移動とNavMeshAgent移動の違い
    3. 初心者はどちらを選ぶべきか
  7. Unityでクリックした方向に弾を発射する方法
    1. 弾Prefabを準備する
    2. Instantiateで弾を生成する
    3. AddForceで弾を飛ばす
    4. 発射音と自動削除を追加する
    5. 弾発射を作る時によくある失敗
  8. Unityのクリック操作でよくあるエラーと対処法
    1. Raycastが当たらない
    2. クリックしても反応しない
    3. hit.colliderがNullになる
    4. LayerMaskを使うべき場面
    5. Debug.DrawRayで原因を調べる方法
  9. Unityクリック操作で初心者が勘違いしやすいポイント
    1. Colliderがなければクリックできない
    2. TagとLayerは別物
    3. ScreenToWorldPointとRaycastは用途が違う
    4. Raycastは毎フレーム撃つ必要はない
  10. まとめ
    1. 参考文献
  11. よくある質問(FAQ)
    1. 関連記事:

結論

Unityのクリック操作は、次の2つを組み合わせることでほとんど実現できます。

  1. Inputでクリックを検知する
  2. Raycastでクリック先を調べる

クリック移動、敵の選択、クリック攻撃、弾発射などは一見すると別々の機能に見えます。しかし実際には、どれも「クリックした場所やオブジェクトを取得し、その結果に応じて処理を実行する」という共通の流れで作られています。

まず覚えておきたいのは、InputとRaycastの役割の違いです。

機能役割
Inputクリックされたことを検知する
Raycast何をクリックしたかを調べる

例えば、左クリックで敵を攻撃する場合を考えてみましょう。

Inputだけでは「左クリックされた」という事実しか取得できません。そのため、どの敵をクリックしたのかまでは分からない状態です。

そこでRaycastを使い、カメラからクリック位置へ向かって光線を飛ばします。その光線が敵に当たった場合だけ攻撃処理を実行します。

逆に、クリックした場所へキャラクターを移動したい場合も考え方は同じです。

  • クリックされたことを取得する
  • Raycastで地面との接触位置を取得する
  • 取得した座標へ移動する

つまり、クリック操作を作るときは「まずInput、その次にRaycast」と考えると整理しやすくなります。

この流れを理解しておくと、後からクリック移動やクリック攻撃を学ぶときにも迷いにくくなります。




Unityのクリック操作はInputとRaycastで作る

Inputは「クリックした」を取得する仕組み

Unityでマウスクリックを検知するときは、主にInputクラスを使用します。

クリック操作でよく使われるのは次の3つです。

メソッド動作主な用途
Input.GetMouseButtonDown()押した瞬間だけtrue攻撃・決定ボタン
Input.GetMouseButton()押している間trueチャージ攻撃・連射
Input.GetMouseButtonUp()離した瞬間だけtrue溜め攻撃の発動

例えば、クリックした瞬間に弾を発射したい場合はGetMouseButtonDownを使います。

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Debug.Log("左クリック");
    }
}

初心者の方がよくやってしまうのが、GetMouseButtonを使ってしまうケースです。

GetMouseButtonは押している間ずっとtrueになるため、1回クリックしたつもりでも大量の弾が発射されることがあります。

「1回だけ実行したいのか」「押している間実行したいのか」を先に考えると、どのメソッドを選ぶべきか判断しやすくなります。

Raycastは「何をクリックしたか」を取得する仕組み

Inputだけでは、クリックされたことしか分かりません。

例えば画面上に敵が3体並んでいたとしても、Inputは「左クリックされた」という情報しか持っていません。

そこで登場するのがRaycastです。

Raycastは、カメラからマウスカーソルの方向へ見えない光線を飛ばし、その先にあるオブジェクトを調べる仕組みです。

イメージとしては次のような流れになります。

マウスクリック
       ↓
カメラからRayを発射
       ↓
オブジェクトに命中
       ↓
命中したオブジェクトを取得

この仕組みがあるからこそ、

  • 敵をクリックして攻撃する
  • アイテムをクリックして拾う
  • ドアをクリックして開く
  • 地面をクリックして移動する

といったゲームらしい操作が実現できます。

私も最初は「クリックしただけなのに、なぜ光線を飛ばすのだろう」と不思議でした。しかし3Dゲームでは画面の座標だけでは対象を特定できないため、Raycastが重要な役割を担っています。

ScreenToWorldPointとRaycastの違い

クリック処理を調べると、ScreenToWorldPointという機能もよく出てきます。

ここで混乱しやすいのですが、ScreenToWorldPointとRaycastは役割が異なります。

やりたいこと使う機能
クリック位置の座標を取得したいScreenToWorldPoint
クリックしたオブジェクトを取得したいRaycast
敵をクリックして攻撃したいRaycast
地面をクリックして移動したいRaycast

2Dゲームで単純にマウス位置へオブジェクトを移動させるだけならScreenToWorldPointでも十分な場合があります。

一方で、「何をクリックしたのか」を判定したい場合はRaycastが必要になります。

迷ったときは、「座標が欲しいのか」「オブジェクトが欲しいのか」で考えると選びやすくなります。




Unityのクリック判定を実装する方法

左クリックを取得するサンプルコード

まずは最も基本となる、左クリックを取得する処理から見ていきましょう。

Unityでは、左クリックはボタン番号「0」で表します。

using UnityEngine;

public class ClickTest : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("左クリックされました");
        }
    }
}

このスクリプトを適当なGameObjectにアタッチして実行すると、左クリックした瞬間にConsoleへメッセージが表示されます。

クリック処理の多くは、このGetMouseButtonDownから始まります。

例えば次のような処理です。

  • 弾を発射する
  • 敵を攻撃する
  • アイテムを拾う
  • 移動先を決定する

まずは「クリックされた瞬間を検知する」という基本を覚えておくと、後の応用が理解しやすくなります。

右クリックとホイールクリックを取得する方法

Input.GetMouseButton系では、引数の数字によって取得するボタンを切り替えられます。

ボタン番号対象
0左クリック
1右クリック
2ホイールクリック

右クリックを取得する場合は次のようになります。

if (Input.GetMouseButtonDown(1))
{
    Debug.Log("右クリック");
}

RTSゲームでは、左クリックで選択、右クリックで移動指示という操作がよく使われます。

また、ホイールクリックはカメラリセットや特殊アクションに割り当てられることがあります。

ゲームジャンルによって使い方は異なりますが、番号の対応関係は覚えておくと便利です。

クリック位置を取得する方法

クリックした場所の座標を取得したい場合は、Input.mousePositionを使用します。

Vector3 mousePos = Input.mousePosition;

Debug.Log(mousePos);

ただし、ここで取得できるのはワールド座標ではありません。

Input.mousePositionが返すのは、ゲーム画面上の位置を表すスクリーン座標です。

例えば次のような値が取得されます。

X : 960
Y : 540
Z : 0

これは「画面のどこをクリックしたか」を表しているだけで、ゲーム空間の位置ではありません。

そのため、クリックした敵を取得したり、クリック地点へ移動したりする場合は、この座標だけでは不十分です。

ここでRaycastが必要になります。

初心者の方がつまずきやすいポイントですが、Input.mousePositionとRaycastは競合するものではなく、むしろセットで使われることがほとんどです。

次は実際にRaycastを使い、クリックしたオブジェクトを取得する方法を見ていきましょう。




Unity Raycastの基本実装と仕組み

Ray・RaycastHit・Physics.Raycastの役割

Raycastを使うときに、最初の壁になりやすいのが次の3つです。

  • Ray
  • RaycastHit
  • Physics.Raycast

名前が似ているため混乱しやすいのですが、それぞれ役割が違います。

要素役割
Ray飛ばす光線の情報
RaycastHit命中結果を保存する箱
Physics.Raycast実際に判定を行う処理

例えるなら、Rayは矢、RaycastHitは命中結果のレポート、Physics.Raycastは矢を発射する動作です。

この3つが揃って初めて「何をクリックしたのか」を調べられます。

初心者の方はまず、「RaycastHitは結果を保存するための変数」という理解だけでも十分です。

Camera.ScreenPointToRayの使い方

クリックした場所へ向かってRayを飛ばすには、まずRayを作る必要があります。

そのときによく使うのがCamera.ScreenPointToRayです。

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

この1行で、メインカメラからマウスカーソルの位置へ向かうRayが生成されます。

流れとしては次のようになります。

マウス位置
      ↓
Input.mousePosition
      ↓
ScreenPointToRay
      ↓
Ray生成

ここで生成されたRayは、まだ何にも当たっていません。

あくまで「この方向へ光線を飛ばしますよ」という情報を持っているだけです。

そのため次にPhysics.Raycastを使って判定を行います。

Raycastでクリックしたオブジェクトを取得する

実際にクリックしたオブジェクトを取得する基本コードは次のようになります。

using UnityEngine;

public class RaycastTest : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                Debug.Log(hit.collider.gameObject.name);
            }
        }
    }
}

このコードでは、クリックした瞬間にRayを飛ばし、命中したオブジェクトの名前をConsoleへ表示します。

例えばCubeをクリックした場合は、次のような結果になります。

Cube

ここで重要なのは、クリック対象にColliderが必要という点です。

見た目が表示されていても、Colliderが付いていなければRaycastは命中しません。

Raycastが動かない場合は、まずColliderの有無を確認するクセを付けておくとトラブル解決が早くなります。

Raycastの流れを図解で理解する

Raycastの仕組みを文章だけで理解するのは少し大変です。

そこで、処理の流れをシンプルに整理してみましょう。

プレイヤーがクリック
        ↓
Inputがクリックを検知
        ↓
ScreenPointToRayでRay生成
        ↓
Physics.Raycast実行
        ↓
Colliderに命中
        ↓
RaycastHitへ結果保存
        ↓
攻撃・移動・選択処理

クリック移動もクリック攻撃も、実は途中まではまったく同じ流れです。

違うのは、命中した後に何をするかだけです。

  • 敵なら攻撃する
  • 地面なら移動する
  • アイテムなら取得する
  • NPCなら会話する

この考え方を理解すると、クリック操作の応用が一気に広がります。

Raycastについてさらに詳しく知りたい場合は、LayerMaskによる絞り込みや当たらない原因も含めて解説している以下の記事も参考になります。




Unityでクリックしたオブジェクトを選択・攻撃する方法

タグを使って敵だけ判定する

Raycastでオブジェクトを取得できるようになると、次に必要になるのが「どの種類のオブジェクトなのか」を判定する処理です。

例えばゲーム内には次のようなオブジェクトが存在します。

  • 味方
  • 地面
  • アイテム
  • 障害物

クリックしたものが敵だった場合だけ攻撃したいのであれば、Tagを使って判定するのが一般的です。

まず、攻撃対象のオブジェクトに「Enemy」というTagを設定しておきます。

その後、Raycastの結果に対してCompareTagを使用します。

if (Physics.Raycast(ray, out hit))
{
    if (hit.collider.CompareTag("Enemy"))
    {
        Debug.Log("敵をクリックしました");
    }
}

初心者の方は次のような書き方を見かけることがあります。

if(hit.collider.tag == "Enemy")

もちろん動作はしますが、UnityではCompareTagの利用が推奨されています。

可読性が高く、タイプミスによる問題も見つけやすいためです。

また、Tagは「敵かどうか」の判定用であり、Raycastの当たり判定を制御するためのものではありません。

ここはLayerと混同しやすいポイントなので覚えておきましょう。

クリックした敵を破壊するサンプル

それでは実際に、クリックした敵を破壊する処理を作ってみましょう。

流れは非常にシンプルです。

  1. クリックを検知する
  2. Raycastを飛ばす
  3. 敵タグを確認する
  4. Destroyで削除する
using UnityEngine;

public class EnemyAttack : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                if (hit.collider.CompareTag("Enemy"))
                {
                    Destroy(hit.collider.gameObject);
                }
            }
        }
    }
}

このスクリプトを実行すると、Enemyタグが付いたオブジェクトだけが削除されます。

地面や壁をクリックしても反応しないため、意図しないオブジェクトを破壊してしまう心配もありません。

実際のゲームではDestroyの代わりに、HPを減らしたりダメージ演出を再生したりすることが多いです。

まずは「クリックした敵を特定する」という部分を理解することが大切です。

オブジェクト選択システムへ応用する方法

Raycastは攻撃だけでなく、さまざまなシステムへ応用できます。

例えばRTSゲームやシミュレーションゲームでは、クリックしたユニットを選択する処理がよく使われます。

selectedObject = hit.collider.gameObject;

このように選択中のオブジェクトを保存しておけば、後から移動命令や攻撃命令を出せるようになります。

また、選択状態を視覚的に分かりやすくするために、次のような演出を組み合わせることもあります。

  • アウトラインを表示する
  • 色を変更する
  • 頭上にマーカーを表示する
  • 選択音を鳴らす

私がゲーム制作をしているときも、Raycastは「攻撃機能」というより「プレイヤーが何を選んだかを調べる仕組み」として使うことが非常に多いです。

一度クリック対象を取得できるようになると、会話システムやアイテム取得システムなどにも応用しやすくなります。

まずは敵をクリックして反応させるところから始めて、徐々に選択システムへ発展させていくのがおすすめです。




Unityでクリック移動を実装する方法

Raycastで移動先座標を取得する

クリック移動の基本はとてもシンプルです。

プレイヤーがクリックした地面の座標を取得し、その座標へキャラクターを移動させます。

ここで重要になるのがRaycastHitのhit.pointです。

hit.pointには、Raycastが命中した場所のワールド座標が保存されています。

例えば地面をクリックした場合、その地点の座標を取得できます。

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

RaycastHit hit;

if (Physics.Raycast(ray, out hit))
{
    Debug.Log(hit.point);
}

例えば次のような値が取得されます。

X : 5.3
Y : 0
Z : -2.1

この座標が「プレイヤーが移動したい場所」です。

クリック移動では、このhit.pointを目的地として利用します。

なお、地面にColliderが付いていない場合はRaycastが命中しません。

クリック移動が動かないときは、キャラクター側よりも先に地面側のCollider設定を確認すると原因を見つけやすくなります。

Transform移動とNavMeshAgent移動の違い

クリックした座標が取得できたら、次はキャラクターを移動させます。

代表的な方法は2つあります。

方法向いている用途
Transform移動学習用・シンプルなゲーム
NavMeshAgent移動RPG・RTS・本格的な3Dゲーム

Transform移動は自分で移動処理を書く方法です。

transform.position =
    Vector3.MoveTowards(
        transform.position,
        targetPosition,
        moveSpeed * Time.deltaTime
    );

仕組みが分かりやすく、移動の勉強には最適です。

ただし障害物を避けたり、経路探索を行ったりする機能はありません。

一方でNavMeshAgentは、Unityが移動経路を自動計算してくれます。

agent.SetDestination(hit.point);

これだけで目的地まで自動移動できるため、RPGやRTSでは非常によく使われます。

ただし事前にNavMeshのベイクが必要になるため、最初は少し設定が増えます。

初心者はどちらを選ぶべきか

どちらを使うべきか迷った場合は、作りたいゲームで判断するのがおすすめです。

  • まずクリック移動の仕組みを学びたい → Transform移動
  • トップダウンRPGを作りたい → NavMeshAgent
  • RTSゲームを作りたい → NavMeshAgent
  • 障害物を避けながら移動したい → NavMeshAgent
  • 単純なサンプルを試したい → Transform移動

私の場合も、最初はTransform移動で座標の考え方を理解してからNavMeshAgentへ進みました。

いきなり高機能な仕組みを使うよりも、「クリックした場所の座標を取得できる」「その座標へ移動できる」という流れを先に体験した方が理解しやすいことが多いです。

クリック移動についてさらに詳しく知りたい場合は、こちらの記事も参考になります。

TopDown Engine
✅アセットストアでチェックする




Unityでクリックした方向に弾を発射する方法

弾Prefabを準備する

クリックで弾を発射する仕組みは、シューティングゲームやアクションゲームでよく使われます。

まずは弾となるPrefabを準備しましょう。

サンプルとしてSphereを使う場合は、次のコンポーネントを追加します。

  • Sphere Collider
  • Rigidbody

特にRigidbodyは重要です。

後ほどAddForceで弾を飛ばすため、Rigidbodyが付いていないと発射処理が機能しません。

設定が終わったらPrefab化しておきましょう。

HierarchyからProjectウィンドウへドラッグするだけでPrefabを作成できます。

Instantiateで弾を生成する

弾を発射する最初のステップは、クリック時にPrefabを生成することです。

Instantiateを使うと、実行中にオブジェクトを生成できます。

public GameObject bulletPrefab;
public Transform shootPoint;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Instantiate(
            bulletPrefab,
            shootPoint.position,
            shootPoint.rotation
        );
    }
}

このコードでは、左クリックした瞬間にshootPointの位置へ弾を生成します。

生成だけでは弾はその場に出現するだけなので、次は発射処理を追加します。

AddForceで弾を飛ばす

弾を飛ばすには、生成したオブジェクトのRigidbodyへ力を加えます。

public GameObject bulletPrefab;
public Transform shootPoint;
public float bulletPower = 1000f;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        GameObject bullet =
            Instantiate(
                bulletPrefab,
                shootPoint.position,
                shootPoint.rotation
            );

        Rigidbody rb =
            bullet.GetComponent<Rigidbody>();

        rb.AddForce(
            shootPoint.forward * bulletPower
        );
    }
}

shootPoint.forwardは発射口の前方向を表します。

つまり、shootPointが向いている方向へ弾が飛んでいきます。

FPSやTPSでは、この考え方が非常によく使われています。

弾が横や後ろへ飛ぶ場合は、モデルの向きとforward方向が一致していない可能性があります。

その場合はPrefabの回転設定を確認してみましょう。

発射音と自動削除を追加する

弾が発射されるだけでも動作はしますが、音があるとゲームらしさが一気に増します。

AudioSourceを利用すると発射音を再生できます。

audioSource.Play();

また、弾を削除しないまま放置すると、シーン内に大量のオブジェクトが残ってしまいます。

そのため一定時間後に削除する処理を入れておくのがおすすめです。

Destroy(bullet, 5f);

この例では5秒後に弾が自動的に削除されます。

簡単な処理ですが、不要なオブジェクトを減らせるためパフォーマンス面でも効果があります。

弾発射を作る時によくある失敗

クリック発射で初心者の方がつまずきやすいポイントをまとめました。

症状原因
弾が飛ばないRigidbodyが付いていない
弾が真下へ落ちる発射力が小さい
違う方向へ飛ぶPrefabの向きが違う
何も生成されないPrefabが未設定
大量に弾が出るGetMouseButtonを使用している

私も最初は「弾が飛ばないからコードが間違っている」と思い込んでいましたが、実際にはRigidbodyの付け忘れだったことが何度もありました。

クリック発射が動かない場合は、まず次の3つを確認してみてください。

  • Prefabが設定されているか
  • Rigidbodyが付いているか
  • shootPointの向きが正しいか

この3つを確認するだけで、多くのトラブルは解決できます。

Easy Character Movement 2
✅アセットストアでチェックする




Unityのクリック操作でよくあるエラーと対処法

Raycastが当たらない

クリック処理で最も多いトラブルが「Raycastが当たらない」という問題です。

コードに問題があると思いがちですが、実際には設定ミスが原因になっているケースが少なくありません。

まず確認したいのはColliderです。

RaycastはColliderに対して判定を行うため、Mesh Rendererで見た目が表示されていてもColliderが付いていなければ命中しません。

確認項目は次の通りです。

  • Box Colliderが付いているか
  • Sphere Colliderが付いているか
  • Mesh Colliderが付いているか
  • Colliderが無効化されていないか

Raycastが当たらない場合は、まずColliderの有無を確認するクセを付けておくと原因を見つけやすくなります。

クリックしても反応しない

クリックしても何も起きない場合は、入力処理そのものが実行されていない可能性があります。

次のポイントを確認してみましょう。

  • スクリプトが有効になっているか
  • GameObjectが非アクティブになっていないか
  • Update関数内で処理しているか
  • Consoleにエラーが出ていないか

特に初心者の方は、別のスクリプトエラーによってUpdate自体が実行されていないケースによく遭遇します。

まずはDebug.Logを追加し、クリック時に処理が実行されているか確認すると切り分けがしやすくなります。

if (Input.GetMouseButtonDown(0))
{
    Debug.Log("クリック検知");
}

このログが表示されない場合は、Raycast以前の問題である可能性が高いです。

hit.colliderがNullになる

次のようなコードでエラーが発生することがあります。

Debug.Log(hit.collider.name);

原因の多くは、Raycastが失敗しているにもかかわらずhit情報へアクセスしていることです。

Raycastの結果を使う場合は、必ず判定成功後に処理を行いましょう。

if (Physics.Raycast(ray, out hit))
{
    Debug.Log(hit.collider.name);
}

この形にしておけば、何も命中していない場合でもエラーを防げます。

LayerMaskを使うべき場面

ゲーム開発が進むと、すべてのオブジェクトにRaycastが当たると困る場面が出てきます。

例えば次のようなケースです。

  • 地面だけクリック移動したい
  • 敵だけ攻撃対象にしたい
  • 背景オブジェクトは無視したい

そんなときはLayerMaskを使います。

Physics.Raycast(
    ray,
    out hit,
    100f,
    groundLayer
);

LayerMaskを利用すると、指定したLayerだけを対象にRaycastを実行できます。

プロジェクトが大きくなるほど重要になる機能なので、早い段階で存在だけでも知っておくと役立ちます。

Debug.DrawRayで原因を調べる方法

Raycastは目に見えないため、「本当に正しい方向へ飛んでいるのか」が分かりにくいことがあります。

そんなときに便利なのがDebug.DrawRayです。

Debug.DrawRay(
    ray.origin,
    ray.direction * 100f,
    Color.red
);

これを実行すると、Sceneビュー上に赤い線が表示されます。

次のような問題を発見しやすくなります。

  • カメラの向きがおかしい
  • Rayの方向がズレている
  • 想定外のオブジェクトに当たっている

私もRaycast関連の不具合を調査するときは、まずDebug.DrawRayを使います。

見えないものを見えるようにするだけで、原因の特定がかなり楽になります。




Unityクリック操作で初心者が勘違いしやすいポイント

Colliderがなければクリックできない

「オブジェクトは見えているのにクリックできない」という相談は非常によくあります。

その原因の多くはColliderが付いていないことです。

Unityでは見た目を表示するRendererと、当たり判定を担当するColliderは別のコンポーネントです。

例えばCubeは作成時からBox Colliderが付いていますが、自作モデルやAsset StoreのモデルではColliderが設定されていないことがあります。

RaycastはColliderに対して判定を行うため、見た目だけではクリックできません。

クリック判定が動かないときは、まずInspectorでColliderの有無を確認してみましょう。

TagとLayerは別物

Unity初心者の方が混同しやすいのがTagとLayerです。

どちらもオブジェクトを分類するために使いますが、目的が異なります。

機能主な用途
Tagオブジェクトの種類を判定する
Layer衝突判定やRaycast対象を制御する

例えば敵をクリックして攻撃したい場合は、Enemyタグを使って判定します。

if(hit.collider.CompareTag("Enemy"))

一方で、地面だけをクリック移動の対象にしたい場合はLayerMaskを使います。

「敵かどうか」はTag、「判定対象にするか」はLayerと覚えておくと整理しやすくなります。

ScreenToWorldPointとRaycastは用途が違う

クリック処理を調べていると、ScreenToWorldPointとRaycastの両方が出てくるため混乱しやすくなります。

しかし、この2つは競合する機能ではありません。

  • ScreenToWorldPoint → 座標を取得する
  • Raycast → オブジェクトを取得する

例えばマウスカーソルの位置にエフェクトを出したいだけなら、ScreenToWorldPointで十分な場合があります。

一方で敵をクリックして攻撃したい場合は、どの敵をクリックしたのか判定する必要があるためRaycastが必要です。

「座標が欲しいのか」「対象オブジェクトが欲しいのか」を考えると選びやすくなります。

Raycastは毎フレーム撃つ必要はない

初心者の方のコードを見ると、Update内で常にRaycastを実行していることがあります。

void Update()
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    Physics.Raycast(ray, out hit);
}

このコードでも動作はしますが、クリックした時しか使わないのであれば毎フレーム実行する必要はありません。

クリック時だけ実行する方が処理回数を減らせます。

if(Input.GetMouseButtonDown(0))
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    Physics.Raycast(ray, out hit);
}

特に小規模なゲームでは大きな差にならないこともありますが、「必要な時だけ実行する」という考え方は今後のゲーム開発でも役立ちます。

クリック操作を実装するときは、まずInputでクリックを取得し、そのタイミングでRaycastを実行する流れを意識してみてください。




まとめ

Unityのクリック操作は、一見すると難しそうに見えますが、本質はとてもシンプルです。

まずInputでクリックされたことを取得し、その後Raycastでクリック先を調べます。

この流れを理解できると、さまざまなゲームシステムへ応用できるようになります。

  • クリックした敵を攻撃する
  • クリックした地点へ移動する
  • クリックで弾を発射する
  • クリックしたオブジェクトを選択する
  • NPCとの会話を開始する
  • アイテムを取得する

これらはすべて、「クリックした対象を取得する」という共通の考え方の上に成り立っています。

私自身もUnityを学び始めた頃は、Raycastの仕組みがなかなか理解できませんでした。

しかし、Inputは「クリックした」、Raycastは「何をクリックした」という役割の違いを意識するようになってから、一気に理解が進みました。

もしこれからクリック操作を学ぶなら、次の順番で試してみるのがおすすめです。

  1. クリックを取得する
  2. Raycastでオブジェクト名を表示する
  3. クリックした敵を選択する
  4. クリック移動を実装する
  5. クリック攻撃や弾発射へ発展させる

いきなり複雑なシステムを作ろうとせず、一つずつ動作を確認しながら進めると理解しやすくなります。

クリック操作はUnity開発で何度も使う基本技術です。

この機会にInputとRaycastの仕組みをしっかり身につけて、RPGやシューティング、RTSなどさまざまなゲーム制作に活用してみてください。

参考文献

Unityの教科書 Unity 6完全対応版
✅ Amazonでチェックする✅ 楽天でチェックする

よくある質問(FAQ)

Q
UnityでUIボタンとRaycastは同時に使えますか?
A

同時に使用できます。

ただし、そのまま実装するとUIボタンをクリックした時に、背後にあるゲームオブジェクトにもRaycastが反応してしまうことがあります。

例えば「インベントリボタンを押したら、後ろにいる敵も攻撃してしまった」という状態です。

そのため実際のゲームでは、UIをクリックしている時はゲーム側のRaycastを無効化する処理を入れることが一般的です。

UIとゲーム画面のクリック処理は別物として管理すると、後から不具合が発生しにくくなります。

Q
2DゲームでもRaycastは使えますか?
A

使えます。

ただし3Dゲームで使用するPhysics.Raycastではなく、2DゲームではPhysics2D.Raycastを使用することが一般的です。

また、Colliderも3D用ではなく次のような2D用コンポーネントを使用します。

  • Box Collider 2D
  • Circle Collider 2D
  • Polygon Collider 2D

3D用Colliderと2D用Colliderは互換性がないため、Physics.RaycastとBox Collider 2Dを組み合わせても正常に判定できません。

2Dゲームを作る場合は、「Physics2D系で統一する」と覚えておくと分かりやすいです。

Q
新Input Systemでも同じ考え方ですか?
A

基本的な考え方は同じです。

変わるのは「クリック入力を取得する方法」であり、「クリックした場所やオブジェクトをRaycastで取得する」という流れは変わりません。

例えば旧Input Systemでは次のように入力を取得します。

Input.GetMouseButtonDown(0)

一方、新Input SystemではInput Actionを利用してクリックイベントを取得します。

しかし、その後に行う処理はほぼ同じです。

  • クリック入力を取得する
  • ScreenPointToRayでRayを作る
  • Physics.Raycastを実行する
  • 結果に応じて移動や攻撃を行う

まずはクリック操作の考え方を理解し、その後に新Input Systemへ移行するとスムーズに学習できます。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク