こんにちは、Unityエンジニアのオオバです。
スクリーン座標をワールド座標に変換することって
年に何度か発生します。
そんな未来のあなたのために、
Unityで スクリーン座標をワールド座標に変換方法
を解説します。
カメラを使ってScreenToWorldPointで座標変換

結論を簡単にまとめます。
- Cameraコンポーネントの ScreenToWorldPoint メソッドを使用
- マウスのスクリーン座標は Input.mousePosition
- スクリーン座標のZ値は カメラからの距離 を指定
ソースコードで表すとコチラです。
💻ソースコード : マウス座標をワールド座標に変換するUnityサンプル
// マウスのスクリーン座標
var screenPos = Input.mousePosition;
// 例としてカメラから5m離れた場所を指定
screenPos.z = 5;
// スクリーン座標をワールド座標に変換
var worldPos = _camera.ScreenToWorldPoint(screenPos);
このコードを使うと、
マウスの座標がワールド空間の座標に変換されます。
使用例とともに詳細の解説に移ります。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
マウスを追いかけるワールド空間のオブジェクト制御
このようなマウスに追随して
ワールド座標にメッシュを描画したいとします。

実装するにあたって必要なのは、
マウスの座標をワールド座標に変換 することです。
マウスの座標とは解像度に依存した座標。
つまりスクリーン座標のことです。
スクリーン座標とは解像度に依存した座標
スクリーン座標について解説します。

- 画面の左下 : (0, 0)
- 画面右上 : (Screen.width, Screen.height)
となります。
Screen.width と Screen.height は解像度です。
640px 480pxのモニタだとしたら、
- Screen.width => 640
- Screen.height => 480
という値が入ります。
これがスクリーン座標です。
💻ソースコード : マウスからスクリーン座標の取得するサンプル
// スクリーン座標の取得
var screenPosition = Input.mousePosition;
マウスからスクリーン座標を取得したい場合は、
Input.mousePosition
を使います。
この解像度に依存した座標を、
3D空間上に変換していきます。
カメラを使ってワールド座標に変換する

Cameraコンポーネントの ScreenToWorldPoint を使います。
スクリーン座標をワールド座標に変換するメソッドです。
ScreenToWorldPoint(スクリーン座標);
このようにスクリーン座標を代入すると
ワールド座標に変換されます。
落とし穴 があるんです。
ScreenToWorldPointにマウス座標をそのまま代入してはいけない
試しにマウスの座標をワールド座標に変換してみます。
💻ソースコード : マウス座標をワールド座標に変換したサンプル
using UnityEngine;
public class ScreenToWorld : MonoBehaviour
{
void Update()
{
var worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.localPosition = worldPos;
}
}
コチラのコードを実行してみます。

何も表示されません。
👉 【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない
カメラとオブジェクトが同じ座標に配置される
シーンビューを確認すると理由が分かります。

カメラとオブジェクトが同じ座標になり
カメラに映らないため何も表示されないのです。
原因は Input.mousePositionのZ座標が0 であること。
ScreenToWorldPointのZ座標は
スクリーンからの距離にあたります。
つまりカメラからの距離です。
Input.mousePositionのZ値は0であるため、
常に カメラと同じ位置になってしまう というわけです。
ScreenToWorldPointのZ値はカメラからの距離
ScreenToWorldPointのZ値はカメラからの距離になります。

↑↑つまりこういうことです。
ScreenToWorldPointのZ値を変えましょう。
試しにカメラから5m離れた場所を指定してみます。
var mousePos = Input.mousePosition;
var worldPos = Camera.main.ScreenToWorldPoint(mousePos.x, mousePos.y, 5f);
transform.localPosition = worldPos;

表示されました!!

このようにScreenToWorldPointにマウス座標のX、Yを与えつつ、
Z値にカメラからの距離を指定することで
意図通りの挙動になります。
まとめ : スクリーン座標をワールド座標に変換する方法

記事の内容を簡単にまとめます。
- カメラのScreenToWorldPointを使う
- mousePositionをそのまま使うとダメ
- Z値はカメラからの距離
こんな感じです。
冒頭で触れたとおり、
スクリーン座標をワールド座標に変換することが
ときどき発生します。
だいたい使わない機能は忘れてしまうため、
この記事を読んで思い出してもらえればと思います。

この記事が気に入ったらフォローしよう
- Unity2020.3.19f1