渋谷ほととぎす通信

新しいこと、枯れたこと問わず大庭が興味を持ったものを調査、生活の効率を求める完全趣味の技術ブログ。基礎を大事にしています。

Unityスクリーン座標をワールド座標に変換する


個人的に時々必要になる且つよく忘れるコードなのでメモです。

この記事でも活用してて、

f:id:esakun:20181205152326g:plain
このようなスクリーン座標のマウスに追随してワールド座標にメッシュを描画するときに使用しています。

スクリーン座標

f:id:esakun:20190521012411p:plain:w450
スクリーン座標は左下が原点で、右上にひくほど値が大きくなります。

ゲームビューのサイズ設定との関係性

FreeAspectの場合

f:id:esakun:20190521012828p:plain:w450
Unityのゲームビューで、FreeAspectを選んだ際は、等倍で表示されたことになります。

絶対値でサイズ指定の場合

f:id:esakun:20190521013017p:plain:w450
値指定をしている場合は、その値が座標の最大値になります。

比率でサイズ指定の場合

比率指定の場合の画面サイズは等倍です。

ソースコード

var screenPos = Input.mousePosition;
// zの値をスクリーンの位置(カメラからz離れた位置)
screenPos.z = Mathf.Abs(_camera.transform.position.z);

// スクリーン座標をワールド座標に変換
var worldPos = _camera.ScreenToWorldPoint(screenPos);

ポイントはInput.mousePositionしたタイミングではZ座標が0なので、そのまま使用するとカメラと同じ座標になり、思ったのと違う結果になってしまうため、現在のカメラのz'スクリーンからの距離)を指定することで、思った通りの挙動になると思います。

以前にも同じようなことをまとめていました。