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

Unityでマウス追従を実装する方法まとめ|移動・回転・ドラッグ操作まで初心者向け解説

Unity C#・スクリプト実装

Unityでマウスカーソルにオブジェクトを追従させたいと思ったものの、思った場所へ移動しなかったり、オブジェクトが画面の外へ飛んでいったりして困った経験はありませんか?

実は、Unityのマウス追従でつまずく原因の多くは、マウス位置の取得方法ではなく「座標の扱い方」にあります。

マウスカーソルの位置は取得できていても、その座標をそのままオブジェクトへ適用すると期待通りに動かないことが少なくありません。

また、マウス追従ができるようになると、クリックで移動するゲームやドラッグ&ドロップ、トップダウンシューティングの照準操作など、さまざまなゲームシステムへ応用できるようになります。

私自身もUnityを始めたばかりの頃は、「なぜ同じコードなのに思った位置へ動かないんだろう?」と何度も悩みました。あとから振り返ると、スクリーン座標とワールド座標の違いを理解できていなかったことが原因でした。

マウス位置の取得から座標変換、オブジェクトの追従、回転、ドラッグ操作まで順番に理解していくと、入力処理の仕組みがぐっと見えやすくなります。


Unityでマウス追従する仕組み

Unityでマウス追従を実装する場合、最も重要なのは「マウス座標をそのまま使わない」という点です。

マウスカーソルの位置とゲーム内オブジェクトの位置は、実は別の座標系で管理されています。そのため、まずは座標の種類を理解することが大切です。

マウス追従は「座標変換」がすべて

Unityで取得できるマウス位置は、基本的にスクリーン座標(Screen座標)です。

スクリーン座標とは、ゲーム画面上の位置を表す座標のことで、左下が(0,0)、右上が(Screen.width, Screen.height)になります。

一方で、オブジェクトのTransform.positionはワールド座標(World座標)で管理されています。

つまり、マウス位置を取得できたとしても、そのままTransform.positionへ代入してはいけません。

例えば次のようなコードです。

transform.position = Input.mousePosition;

一見すると正しそうに見えますが、実際にはスクリーン座標とワールド座標を混ぜているため、意図しない位置へ移動してしまうことがあります。

そのため、通常は次の流れで処理します。

  • マウス位置を取得する
  • スクリーン座標をワールド座標へ変換する
  • 変換後の座標をTransform.positionへ代入する

この「座標変換」がマウス追従の核心部分です。

初心者が最初につまずくポイント

マウス追従がうまく動かない場合、多くは次のどれかに当てはまります。

  • Input.mousePositionをそのまま代入している
  • ScreenToWorldPointを使っていない
  • Z値を設定していない
  • Camera.mainが取得できていない

特に多いのが、ScreenToWorldPointを使っているのにZ値を設定していないケースです。

スクリーン座標は画面上の2D情報しか持っていません。そのため、Unityは「カメラからどれくらい離れた位置へ変換するのか」という奥行き情報も必要になります。

この奥行き情報が不足すると、オブジェクトが思わぬ場所へ移動したり、まったく見えない場所へ飛んでいったりすることがあります。

私も最初の頃は「コードは合っているはずなのに動かない……」と悩みましたが、原因はほぼZ値でした。

マウス追従がうまくいかない場合は、まず座標変換とZ値設定を確認すると解決できることが多いですよ。




Unityでマウス位置を取得する方法

マウス追従を作る最初のステップは、現在のマウスカーソルの位置を取得することです。

Unityには主に2つの入力システムがあり、どちらを使っているかによって取得方法が異なります。

まずは現在のプロジェクトでどちらを使用しているか確認しておきましょう。

Legacy Input Managerで取得する方法

もっともシンプルな方法は、Input.mousePositionを使用する方法です。

多くの初心者向けチュートリアルでも使われており、すぐに試せるのが特徴です。

using UnityEngine;

public class MousePositionSample : MonoBehaviour
{
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        Debug.Log(mousePos);
    }
}

Input.mousePositionの戻り値はVector3です。

ただし、取得できるのはスクリーン座標であり、オブジェクトのTransform.positionとは別物です。

また、Zの値は実質的に奥行きを表しているわけではないため、そのままワールド座標として利用することはできません。

まずは「マウスの現在位置を取得するための値」と考えておくと理解しやすいでしょう。

New Input Systemで取得する方法

Unityの新しい入力システム(Input System)を利用している場合は、Mouseクラスから位置を取得します。

using UnityEngine;
using UnityEngine.InputSystem;

public class MousePositionSample : MonoBehaviour
{
    void Update()
    {
        Vector2 mousePos = Mouse.current.position.ReadValue();

        Debug.Log(mousePos);
    }
}

こちらの戻り値はVector2です。

マウス位置の取得だけならLegacy Input Managerと大きな違いはありませんが、ゲームパッドやタッチ操作との連携がしやすいというメリットがあります。

最近のUnityプロジェクトではInput Systemを採用するケースも増えています。

どちらを使うべきか

どちらを選ぶべきか迷った場合は、次のように考えると判断しやすくなります。

項目Legacy Input ManagerInput System
導入の手軽さ
学習コスト低いやや高い
将来性
ゲームパッド対応
初心者向け

「まずはマウス追従を理解したい」という段階であれば、Legacy Input Managerでも十分です。

一方で、PC・スマホ・ゲームパッドなど複数の入力デバイスへ対応する予定がある場合は、Input Systemを選んでおくと後から拡張しやすくなります。

どちらを使ったとしても、この後に行う座標変換の考え方は同じです。まずはマウス位置を取得できることを確認し、次のステップでワールド座標へ変換していきましょう。




Unityでオブジェクトをマウス追従させる方法

マウス位置を取得できるようになったら、次はオブジェクトを実際に追従させてみましょう。

ここで重要になるのが、スクリーン座標をワールド座標へ変換する処理です。

マウス追従がうまく動かない原因の多くは、この座標変換にあります。

ScreenToWorldPointで座標変換する

Unityでは、Camera.ScreenToWorldPoint()を使用するとスクリーン座標をワールド座標へ変換できます。

基本的な流れは次の通りです。

Vector3 mousePos = Input.mousePosition;

Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos);

ただし、このコードだけでは正しく動かない場合があります。

なぜなら、マウス位置には「どの奥行きへ変換するか」という情報が含まれていないからです。

そのため、多くの場合はZ値を設定してから変換を行います。

Z値はなぜ必要なのか

初心者がもっとも混乱しやすいポイントがここです。

マウスカーソルは画面上の2D情報です。

しかし、Unityのワールド空間は3Dです。

つまりUnityは、「画面上のこの位置」という情報だけでは、実際にどの場所へ変換すればよいのか判断できません。

そこで必要になるのがカメラからの距離(奥行き)です。

例えば次のような設定を考えてみましょう。

  • カメラ位置:Z = -10
  • オブジェクト位置:Z = 0

この場合、カメラからオブジェクトまでは10離れています。

そのためScreenToWorldPointへ渡す前に、Zへ10を設定します。

Vector3 mousePos = Input.mousePosition;

mousePos.z = 10f;

Vector3 worldPos =
    Camera.main.ScreenToWorldPoint(mousePos);

もしZ値を設定しないと、変換結果が意図しない座標になる場合があります。

「オブジェクトが画面外へ飛んだ」「全然違う場所へ移動した」というときは、まずこの部分を確認してみてください。

オブジェクトを追従させるサンプルコード

実際にオブジェクトをマウスカーソルへ追従させるコードは次のようになります。

using UnityEngine;

public class MouseFollow : MonoBehaviour
{
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        mousePos.z = 10f;

        Vector3 worldPos =
            Camera.main.ScreenToWorldPoint(mousePos);

        transform.position = worldPos;
    }
}

このスクリプトをCubeなどのオブジェクトへアタッチすると、マウスカーソルに合わせて移動するようになります。

もし動かない場合は次の点を確認してみましょう。

  • Main Cameraタグが設定されているか
  • カメラからオブジェクトまでの距離が正しいか
  • オブジェクトが画面内に存在しているか

X軸だけ・Y軸だけ追従させる方法

ゲームによっては、すべての方向へ追従させる必要がない場合もあります。

例えば横スクロールゲームなら、X方向だけ動かしたいケースがあります。

その場合は追従させたい軸だけ更新します。

X軸だけ追従させる例です。

Vector3 pos = transform.position;

pos.x = worldPos.x;

transform.position = pos;

逆にY軸だけ追従させたい場合は、Yのみ更新します。

Vector3 pos = transform.position;

pos.y = worldPos.y;

transform.position = pos;

この方法は次のような場面でよく使われます。

  • 横スクロールシューティングの自機移動
  • スライダーのツマミ移動
  • 特定レーンのみ移動するゲーム
  • ドラッグ制限付きのUI操作

単純なマウス追従でも、軸を制限するだけで実用的なゲームシステムへ応用しやすくなります。




Unityでマウス追従を滑らかにする方法

ここまでの方法でもマウス追従は実装できますが、カーソルの動きに完全に一致するため、場合によっては少し機械的な印象になります。

特にキャラクターやペット、ドローンのようなオブジェクトでは、少し遅れて追従した方が自然に見えることがあります。

そんなときに活躍するのがLerpやMoveTowardsです。

transform.position直接代入との違い

まずは代表的な移動方法の違いを見てみましょう。

方法特徴向いている用途
transform.position即座に移動するカーソル、UI、正確な追従
Vector3.Lerpなめらかに近づくキャラクター、演出
Vector3.MoveTowards一定速度で移動する敵AI、追跡処理

「マウスに完全一致で追従したい」のか、「自然な動きにしたい」のかで選ぶ方法が変わります。

Vector3.Lerpで自然な動きにする

もっとも手軽なのはVector3.Lerpを使う方法です。

目標地点へ向かって徐々に近づいていくため、追従に少し遅れが生まれ、柔らかい動きになります。

using UnityEngine;

public class SmoothMouseFollow : MonoBehaviour
{
    [SerializeField] private float followSpeed = 10f;

    void Update()
    {
        Vector3 mousePos = Input.mousePosition;
        mousePos.z = 10f;

        Vector3 targetPos =
            Camera.main.ScreenToWorldPoint(mousePos);

        transform.position = Vector3.Lerp(
            transform.position,
            targetPos,
            followSpeed * Time.deltaTime
        );
    }
}

followSpeedの値を大きくすると素早く追従し、小さくするとゆっくり追従します。

私の場合、キャラクターなら5〜10程度、浮遊するオブジェクトなら2〜5程度から調整することが多いです。

ただし、Lerpは目標地点へ近づくほど移動量が小さくなるため、常に一定速度で動くわけではありません。

どの方法を選ぶべきか

迷ったときは次の基準で選ぶと失敗しにくくなります。

  • マウスカーソルと完全に一致させたい → transform.position
  • 自然な追従を作りたい → Vector3.Lerp
  • 速度を一定にしたい → Vector3.MoveTowards

例えば、ドラッグ中のオブジェクトであれば直接代入の方が操作感が良くなります。

一方で、ペットや追従キャラクターのような演出ならLerpの方が見栄えが良くなることが多いです。

「正しい方法」を探すよりも、「そのゲームで気持ちよく見える方法」を選ぶことが大切です。

さらに移動アニメーションや演出を強化したい場合は、DOTween ProのようなTweenライブラリを利用すると実装しやすくなります。

DOTween Pro
✅アセットストアでチェックする




Unityでマウス方向にオブジェクトを回転させる方法

マウス追従ができるようになると、「オブジェクトをマウスの方向へ向かせたい」と思うことがあります。

例えば次のようなゲームでは定番の処理です。

  • トップダウンシューティングの照準
  • ツインスティックシューター
  • 砲台やタレットの向き制御
  • 敵キャラクターの視線演出

まずはもっとも簡単な方法から見ていきましょう。

LookAtを使う方法

3Dオブジェクトの場合は、Transform.LookAt()を使うだけで指定した座標の方向を向かせることができます。

using UnityEngine;

public class MouseLook : MonoBehaviour
{
    void Update()
    {
        Vector3 mousePos = Input.mousePosition;

        mousePos.z = 10f;

        Vector3 targetPos =
            Camera.main.ScreenToWorldPoint(mousePos);

        transform.LookAt(targetPos);
    }
}

コード自体はとてもシンプルです。

LookAtは「指定した座標へ向く」という処理を自動で行ってくれるため、回転計算を自分で行う必要がありません。

まず試すならこの方法がおすすめです。

LookAtで思った方向を向かない原因

ただし、LookAtを使っても期待通りに見えないことがあります。

これはコードの問題ではなく、モデルの向きが原因であるケースが非常に多いです。

Unityでは通常、オブジェクトのZ軸(Forward)が前方向として扱われます。

しかし、3Dモデルによっては次のような状態になっています。

  • X軸方向が前になっている
  • Y軸方向が前になっている
  • モデリングソフトとUnityで向きが異なる

その結果、LookAtは正しく動作しているのに、モデルだけ横を向いて見えることがあります。

こうした場合は、モデルの親オブジェクトを作成して向きを補正したり、モデル自体の回転を調整したりする方法がよく使われます。

「回転がおかしい=LookAtが壊れている」ではないので、まずはSceneビューでForward方向を確認してみましょう。

2Dゲームの場合の回転方法

2DゲームではLookAtをそのまま使うことはあまりありません。

なぜなら、2DではZ軸回転だけを制御したいケースが多いからです。

その場合はAtan2を利用して角度を求め、Quaternion.Eulerで回転させる方法が一般的です。

Vector3 direction =
    targetPos - transform.position;

float angle =
    Mathf.Atan2(direction.y, direction.x)
    * Mathf.Rad2Deg;

transform.rotation =
    Quaternion.Euler(0, 0, angle);

少し難しく見えますが、やっていることは「現在位置からマウス位置への角度を計算している」だけです。

トップダウンシューティングや2Dアクションでは頻繁に使われる考え方なので、将来的に照準システムを作る予定がある場合は覚えておくと役立ちます。

まずは3DならLookAt、2DならAtan2を使うと覚えておけば十分です。




Unityでドラッグ移動を実装する方法

マウス追従が理解できると、次に作りたくなるのがドラッグ操作です。

カードゲームのカード移動や、アイテムを掴んで移動する仕組みなど、多くのゲームで利用されています。

まずはUnity標準機能だけで実装できる方法から見ていきましょう。

OnMouseDragで実装する方法

UnityにはOnMouseDragという便利なイベントがあります。

オブジェクトをクリックしている間、毎フレーム呼び出されるため、ドラッグ処理を簡単に実装できます。

using UnityEngine;

public class DragObject : MonoBehaviour
{
    private float distanceToCamera;

    void Start()
    {
        distanceToCamera =
            Vector3.Distance(
                transform.position,
                Camera.main.transform.position
            );
    }

    void OnMouseDrag()
    {
        Vector3 mousePos = Input.mousePosition;

        mousePos.z = distanceToCamera;

        Vector3 worldPos =
            Camera.main.ScreenToWorldPoint(mousePos);

        transform.position = worldPos;
    }
}

このスクリプトをアタッチすると、オブジェクトをクリックしたまま移動できるようになります。

特に試作品や学習用のプロジェクトでは、とても手軽な方法です。

OnMouseDragが動かない原因

コードに問題がないのに動かない場合は、設定を確認してみましょう。

私が初心者の方から相談を受けるときも、ほとんどが次のどれかです。

  • Colliderが付いていない
  • カメラからオブジェクトが見えていない
  • Ignore Raycastレイヤーになっている
  • オブジェクトが無効化されている

特にColliderの付け忘れは非常によくあります。

OnMouseDragはColliderを利用してクリック判定を行うため、Colliderが存在しないとイベント自体が発生しません。

まずはBox ColliderやSphere Colliderが付いているか確認してみてください。

OnMouseDragはいつ使うべきか

OnMouseDragは便利ですが、すべてのプロジェクトで最適というわけではありません。

用途おすすめ度
学習用
試作品
簡単なツール
本格ゲーム

小規模なゲームなら十分実用的ですが、複雑なクリック判定やマルチプラットフォーム対応を考えると限界もあります。

例えば、特定レイヤーだけ反応させたい場合や、複数オブジェクトの選択処理を行いたい場合は別の方法が向いています。

本格的なゲームならRaycastがおすすめ

より柔軟なクリック判定を行いたい場合は、Raycastを利用する方法が一般的です。

Raycastを使うと次のような制御が可能になります。

  • 特定レイヤーだけ選択する
  • クリック可能なオブジェクトを制限する
  • ドラッグ開始と終了を細かく管理する
  • 複数オブジェクトの判定を行う

商用ゲームや中規模以上のプロジェクトでは、こちらが採用されることが多いです。

「とりあえずドラッグを体験したい」ならOnMouseDrag、「将来的に本格的な操作システムを作りたい」ならRaycastを覚える、と考えると判断しやすいでしょう。




Unityマウス追従でよくある失敗と対処法

マウス追従はコード自体はそれほど難しくありませんが、設定や座標の理解不足によって予想外の動作になることがあります。

私自身も何度も同じようなミスを経験しましたし、初心者の方から質問を受ける内容もほぼ共通しています。

ここでは特によくあるトラブルと対処法をまとめておきます。

オブジェクトが動かない

まず確認したいのは、Update内で処理が実行されているかどうかです。

次のようなケースがよくあります。

  • スクリプトがアタッチされていない
  • GameObjectが非アクティブになっている
  • コンソールにエラーが出ている
  • Camera.mainが取得できていない

特にコンソールエラーが発生している場合は、その時点で処理が停止していることがあります。

まずはConsoleウィンドウを確認する習慣を付けると原因を見つけやすくなります。

オブジェクトが変な場所へ飛ぶ

これはマウス追従で最も多いトラブルです。

原因の多くはScreenToWorldPointへ渡すZ値が適切ではないことです。

例えば次のようなコードです。

mousePos.z = 0f;

この状態だと、カメラ設定やシーン構成によって意図しない座標へ変換されることがあります。

まずはカメラから対象オブジェクトまでの距離を確認してみましょう。

「コードは合っているのに位置がおかしい」という場合は、かなりの確率でZ値が原因です。

Camera.mainが取得できない

Camera.mainは「Main Camera」タグが付いたカメラを取得します。

そのため、カメラ名がMain Cameraであってもタグが設定されていなければ取得できません。

Hierarchyでカメラを選択し、InspectorのTagが次の設定になっているか確認してください。

  • Main Camera

複数カメラを使用しているプロジェクトでは、Camera.mainに依存しない設計にすることもあります。

ただし、学習段階ではMain Cameraタグを利用する方法で問題ありません。

ドラッグできない

OnMouseDragが動かない場合はColliderを確認しましょう。

OnMouseDragはColliderを利用してマウス判定を行います。

そのため、見た目は表示されていてもColliderが付いていなければイベントは発生しません。

確認するポイントは次の通りです。

  • Box Colliderが付いているか
  • Sphere Colliderが付いているか
  • Colliderが無効化されていないか
  • Ignore Raycastレイヤーになっていないか

ドラッグできない場合は、まずColliderを疑うと解決が早いことが多いです。

回転方向がおかしい

LookAtを使ったのに横を向いたり、上下逆になったりすることがあります。

この場合はスクリプトよりもモデルの向きが原因であるケースがほとんどです。

UnityではForward(青い矢印)が前方向として扱われます。

しかし、3DモデルによってはForwardと実際の正面が一致していないことがあります。

そんなときは次の方法が有効です。

  • 親オブジェクトを作って回転補正する
  • モデル側のRotationを調整する
  • モデリングソフト側で向きを修正する

LookAtが壊れているのではなく、「モデルがどちらを前として作られているか」を確認することが大切です。

マウス追従がうまくいかない場合は、コードを書き換える前に「座標」「カメラ」「Collider」「モデルの向き」の4つを順番に確認してみてください。意外とあっさり解決することも多いですよ。




まとめ

Unityでマウス追従を実装する場合は、まずマウス位置を取得し、その後スクリーン座標をワールド座標へ変換する必要があります。

今回の内容を振り返ると、重要なポイントは次の通りです。

  • マウス位置はInput.mousePositionまたはInput Systemで取得する
  • ScreenToWorldPointでワールド座標へ変換する
  • Z値にはカメラから対象までの距離を設定する
  • transform.positionへ代入すると追従できる
  • LookAtを使うとマウス方向へ回転できる
  • OnMouseDragを使うと簡単にドラッグ操作を実装できる

特に初心者の方が覚えておきたいのは、「マウス位置を取得すること」と「オブジェクトを移動させること」は別の処理だという点です。

私も最初はInput.mousePositionをそのままTransform.positionへ代入して、「なぜ変な場所へ飛ぶんだろう?」と悩みました。

しかし、スクリーン座標とワールド座標の違いを理解してからは、クリック移動やドラッグ操作、Raycastによる選択処理などもスムーズに実装できるようになりました。

マウス追従は単独のテクニックというより、Unityの入力処理全体につながる基礎知識です。

今回の内容を理解できれば、トップダウンシューティングやRTS、カードゲーム、ドラッグ&ドロップUIなど、さまざまなゲームシステムへ応用しやすくなるでしょう。

まずはシンプルな追従処理を作り、そこから回転やドラッグ、クリック判定へ発展させてみてください。


よくある質問(FAQ)

Q
Input.mousePositionとInput Systemはどちらを使うべきですか?
A

学習目的や小規模なプロジェクトであれば、Input.mousePositionでも十分です。

コードがシンプルなので理解しやすく、サンプルも豊富に見つかります。

一方で、ゲームパッドやタッチ操作への対応を予定している場合は、Input Systemを選んでおくと後から拡張しやすくなります。

どちらを使ってもマウス追従の考え方は同じなので、まずは使いやすい方で座標変換の仕組みを理解することをおすすめします。

Q
ScreenToWorldPointのZ値は何を入れればいいですか?
A

基本的には「カメラからオブジェクトが存在する平面までの距離」を指定します。

例えばカメラがZ=-10、オブジェクトがZ=0に存在する場合は、距離が10になるため次のように設定します。

mousePos.z = 10f;

この値はシーン構成によって変わるため、必ずしも10で固定ではありません。

オブジェクトが意図しない場所へ移動する場合は、まずカメラと対象オブジェクトの距離を確認してみましょう。

Q
OnMouseDragとRaycastはどちらがおすすめですか?
A

簡単なドラッグ操作を素早く実装したいならOnMouseDragがおすすめです。

Colliderを付けるだけで利用できるため、学習用や試作品では非常に便利です。

一方で、本格的なゲーム開発ではRaycastを使うケースが多くなります。

Raycastならレイヤーごとの判定制御や複雑なクリック処理を実装しやすく、拡張性も高くなります。

迷った場合は、まずOnMouseDragで仕組みを理解し、その後Raycastへステップアップすると学習しやすいでしょう。

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

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

スポンサーリンク