2Dゲームオブジェクトをマウスで掴んで動かす(Unity 6対応)
2Dゲームオブジェクトをマウスで掴んで動かすサンプルになります。
準備
まずは、ドラッグ対象となる2Dオブジェクトを用意します。
■ 必要なコンポーネント
対象のゲームオブジェクトに以下を追加します。
- SpriteRenderer
- Box Collider 2D
- Rigidbody 2D(任意)
Rigidbody2Dを使用する場合は、以下の設定にします。
- Body Type:Kinematic
今回は transform.position で移動させるためです。
コード(Unity 6 / Input System対応)
using UnityEngine;
using UnityEngine.InputSystem;
public class MouseDrag : MonoBehaviour
{
private Vector3 offset;
void OnMouseDown()
{
offset = transform.position - GetMouseWorldPos();
}
void OnMouseDrag()
{
transform.position = GetMouseWorldPos() + offset;
}
private Vector3 GetMouseWorldPos()
{
Vector2 mousePos = Mouse.current.position.ReadValue();
Vector3 screenPos = new Vector3(
mousePos.x,
mousePos.y,
-Camera.main.transform.position.z
);
return Camera.main.ScreenToWorldPoint(screenPos);
}
}
コードの説明
■ offset
マウスで掴んだ位置と、オブジェクトの中心との差分を保持します。
これにより、クリックした位置を維持したまま自然にドラッグできます。
■ OnMouseDown()
オブジェクトをクリックした瞬間に呼ばれます。
このときに「掴んだ位置」を記録します。
■ OnMouseDrag()
マウスを押しながら動かしている間、毎フレーム呼ばれます。
■ GetMouseWorldPos()
スクリーン座標 → ワールド座標へ変換しています。
ここで重要なのは z の値です。
2Dでは「カメラから対象までの距離」を指定しています。
スクリプトのアタッチ
- スクリプトを保存
- 対象のゲームオブジェクトにドラッグ&ドロップ
再生して、マウスでドラッグできることを確認してください。
注意点(Unity 6 / Input System)
Unity 6 では Input System が標準になっています。
そのため、従来のコードで使われていた
Input.mousePosition
を使用すると、次のようなエラーが発生します。
InvalidOperationException:
You are trying to read Input using the UnityEngine.Input class...
■ 原因
- UnityEngine.Input は旧入力システム
- Unity 6 は Input System が標準
→ 混在するとエラーになる
■ 対処方法
マウス座標の取得を次に変更します。
using UnityEngine.InputSystem;
Vector2 mousePos = Mouse.current.position.ReadValue();
注意点(Unity6におけるバージョンによる違い)
Unity 6.4 より前のバージョンでは、OnMouseDown() は
Input System(新入力)のみの設定では動作しない場合があります。
■ 原因
OnMouseDown() はもともと
旧Inputシステム(Input Manager)に依存した仕組みのためです。
■ 対処方法
以下の設定を変更します。
Edit > Project Settings > Player > Other Settings
Active Input Handling を次のいずれかに変更します。
- Both(推奨)
- Input Manager (Old)
■ 推奨設定
Both
理由:
- OnMouseDown が動く
- 新Input Systemも使える
- 将来の拡張に対応できる
■ Unity 6.4以降について
Unity 6.4 以降では、
Input Systemのみの設定でも
OnMouseDown / OnMouseDrag / OnMouseUp が動作するように改善されています。
ただし、
- 内部仕様は変更される可能性がある
- 環境差が出る可能性がある
ため、授業や検証用途では注意が必要です。
3Dの場合の注意点
2Dと3Dでは、座標の扱いが異なります。
■ 2Dの場合
- 移動する面が固定(Z=0など)
- zは固定値でOK
■ 3Dの場合
- 奥行き(Z)がオブジェクトごとに異なる
- カメラからの距離を使う必要がある
ScreenToWorldPoint() の z は
ワールドのZ座標ではなく、カメラからの距離
です。
3D対応コード
using UnityEngine;
using UnityEngine.InputSystem;
public class MouseDrag3D : MonoBehaviour
{
private float distanceToCamera;
private Vector3 offset;
void OnMouseDown()
{
distanceToCamera = Vector3.Distance(
Camera.main.transform.position,
transform.position);
offset = transform.position - GetMouseWorldPos();
}
void OnMouseDrag()
{
transform.position = GetMouseWorldPos() + offset;
}
private Vector3 GetMouseWorldPos()
{
Vector2 mousePos = Mouse.current.position.ReadValue();
Vector3 screenPos = new Vector3(
mousePos.x,
mousePos.y,
distanceToCamera
);
return Camera.main.ScreenToWorldPoint(screenPos);
}
}
補足(OnMouseDownについて)
OnMouseDown はシンプルで使いやすい便利な機能です。
Unity 6.4 以降では、Input System 使用時でも動作するよう改善されています。
ただし、
- 内部処理がブラックボックス
- UIや複雑な入力と組み合わせにくい
という特徴があります。
まとめ
- 2Dはシンプルに実装できる
- Unity 6では Input System に注意
- Input.mousePosition は使わない
- 3Dでは「カメラからの距離」が重要
一言
OnMouseDownは非常に分かりやすい入り口です。
ただし現在のUnityでは
入力はInput System、座標変換は自分で制御する
という考え方が主流になっています。




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