【Unity】クリックしたオブジェクトの位置を取得する Raycast入門
クリックした先の3Dオブジェクトを知りたいときは、ScreenToWorldPoint ではなく Raycast を使います。
マウスでクリックしたオブジェクトの位置を取得しようとして、次のようなコードを書いたことはないでしょうか。
var pos = Camera.main.ScreenToWorldPoint(Mouse.current.position.value);
Debug.Log(pos);
エラーにはなりませんが、期待した値は出ません。この記事では、Raycast で「クリックしたオブジェクトの名前」「そのオブジェクトの位置」「クリックした表面の座標」を取得する方法を、実際の Console の出力を見ながら解説します。
動作確認は Unity 6.3 LTS(6000.3.25f1)、Input System を使ったプロジェクトで行いました。
ScreenToWorldPoint では取れない理由
ScreenToWorldPoint は「画面上の点」を「カメラから指定した距離にある位置」に変換する関数で、どのオブジェクトをクリックしたかは分かりません。
引数の Vector3 の z 成分が「カメラからの距離」を表します。Mouse.current.position が返す Vector2 をそのまま渡すと、z は 0 になります。
- Perspective(3D)カメラ: z = 0 は「カメラからの距離 0」なので、カメラ自身の位置が返ります。マウスの位置は結果に反映されません。
- Orthographic(2D)カメラ: x と y は正しく得られますが、z はカメラの z 座標(通常 -10)になります。
つまり、このコードが得意なのは「2D で、z = 0 の平面にオブジェクトを置きたい」場面です。3D のオブジェクトをクリックして選ぶ用途には向きません。
Raycast でクリックしたオブジェクトを取得する
カメラからマウス位置に向けて光線(Ray)を飛ばし、最初に当たった Collider の情報を受け取ります。
using UnityEngine;
using UnityEngine.InputSystem; // 入力を検知するために必要
public class ClickPick : MonoBehaviour
{
Camera cam;
void Start()
{
cam = Camera.main;
}
void Update()
{
if (Mouse.current == null) return;
if (Mouse.current.leftButton.wasPressedThisFrame)
{
Ray ray = cam.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
{
Debug.Log(hit.collider.name); // クリックしたオブジェクト名
Debug.Log(hit.transform.position); // そのオブジェクトの位置
Debug.Log(hit.point); // レイが当たった表面の座標
}
}
}
}
ポイントは3つです。
ScreenToWorldPointではなくScreenPointToRayを使い、画面上の点から Ray を作ります。Physics.Raycast(ray, out hit)がtrueを返したときだけ、何かに当たっています。- 当たった結果は
RaycastHit型のhitに入ります。
このスクリプトは、シーン内の任意の GameObject(空のオブジェクトでも可)に付ければ動きます。Camera.main の仕組みや null になるケースは、UnityのCamera.mainとは? GetComponent<Camera>()との違いを理解しようで解説しています。
実行結果を読む
的(target)をクリックすると、Console に次の3行が出ました。
target
(0.00, -5.00, 14.00)
(0.30, 2.51, 13.60)

| ログ | 値 | 意味 |
|---|---|---|
hit.collider.name | target | クリックしたオブジェクト名 |
hit.transform.position | (0.00, -5.00, 14.00) | target の原点の位置 |
hit.point | (0.30, 2.51, 13.60) | レイが当たった表面上の点 |
使ったオブジェクトの設定は次のとおりです。
| 項目 | 値 |
|---|---|
| Transform の Position | (0, -5, 14) |
| Box Collider の Center | (0, 6.5, 0) |
| Box Collider の Size | (3.8, 3.8, 0.8) |

この設定から、値を読み解けます。
hit.transform.positionは Position と一致します。Transform の値そのものです。hit.pointの z = 13.60 は、的の手前の面です。Collider の中心は z = 14 で、奥行き(Size Z)が 0.8 なので、手前の面は 14 − 0.4 = 13.6 になります。カメラ側の表面に Ray が当たったことが分かります。hit.pointの y = 2.51 は、Collider の範囲内です。Collider の中心は y = −5 + 6.5 = 1.5 で、高さ(Size Y)が 3.8 なので、y は −0.4 から 3.4 の範囲になります。hit.pointの x = 0.30 は、中央よりやや右をクリックした位置です。
hit.point と hit.transform.position の違い
「クリックした場所」が知りたいなら hit.point、「オブジェクトの基準位置」が知りたいなら hit.transform.position を使います。RaycastHit に入っている情報(point・normal・distance・collider)の全体像は、UnityのRaycastHitには何が入っている? hit.point・distance・normal・colliderを理解しようで詳しく解説しています。
今回の的は、原点が棒の根元(地面)にあります。そのため hit.transform.position の y は −5 ですが、見た目の的は y = 1.5 付近にあり、大きくずれます。Transform の位置は、見た目の中心とは限りません。hit.transform.position は世界座標です。親子関係があるときの座標の違いは、Unityのtransform.positionとlocalPositionの違い|世界から見た座標と親から見た座標で解説しています。
| 取得したいもの | 使う値 | 使いどころの例 |
|---|---|---|
| クリックした表面の座標 | hit.point | 着弾エフェクトや弾痕を出す位置 |
| オブジェクトの基準位置 | hit.transform.position | 選択したオブジェクトを移動・回転させる |
| クリックしたオブジェクト | hit.collider.gameObject | タグや名前で処理を分ける |
hit.point を使った実例として、クリックした場所にマーカーを置く方法はUnityでクリックした場所にマーカーを置く|hit.pointとhit.normalを実際に使ってみよう、弾痕を残す方法はUnityでクリックした場所に弾痕を残す|RaycastとDestroyを使ってみようで紹介しています。
よくあるつまずき
- 何も出力されない: クリックしたオブジェクトに Collider が付いているか確認します。Collider がないオブジェクトには Ray が当たりません。
- 見た目と判定がずれる: Raycast は見た目の Mesh ではなく、Collider の形で判定します。今回の的のように Collider の Center がずれていると、判定の位置も見た目からずれます。Scene ビューで緑色の枠線を確認してください。
- 遠くの物に当たってしまう:
Physics.Raycast(ray, out hit, 100f)のように第3引数で距離を制限できます。 Mouse.currentがnullになる: マウスが接続されていない環境(スマートフォンなど)ではnullになります。冒頭のif (Mouse.current == null) return;は、その対策です。UnityEngine.InputSystemが使えない: Player Settings の Active Input Handling が、旧 Input Manager のみになっていないか確認します。Input System の基本はUnity 6でキー入力による移動を実装する ― Input Systemの基本で解説しています。- 2D ゲームの場合: Collider2D と
Physics2D.Raycastを使います。単にクリック位置にオブジェクトを置きたいだけなら、ScreenToWorldPointで変換したあと、z を 0 にそろえる方法が使えます。
まとめ
クリックした3Dオブジェクトを調べるには、ScreenPointToRay と Physics.Raycast の組み合わせを使います。
ScreenToWorldPointは座標変換の関数で、クリックしたオブジェクトは分かりません。hit.collider.nameでオブジェクト、hit.pointで当たった表面の座標、hit.transform.positionでオブジェクトの基準位置が得られます。- 判定は Collider の形で行われるので、見た目と合わないときは Collider の設定を確認します。
「座標変換」と「Raycast」は別の仕組みです。やりたいことに合わせて使い分けてください。
関連記事
- 【Unity入門】Raycastで弾痕を作りながら学ぶ|Transformの親子関係までのシリーズまとめ
- UnityのRaycastHitには何が入っている? hit.point・distance・normal・colliderを理解しよう
- Unityでクリックした場所にマーカーを置く|hit.pointとhit.normalを実際に使ってみよう
- UnityのCamera.mainとは? GetComponent<Camera>()との違いを理解しよう
- Unity 6でIgaguriを作る② ― クリックした方向へ飛ばして、パーティクルで演出する(PC版)








ディスカッション
コメント一覧
まだ、コメントがありません