ぐーるらいふ

底辺。

【Unity】ScreenToWorldPointが上手く取れない?

ScreenToWorldPointを使う

Unityを使用していて、クリックした位置にオブジェクトを移動させたりすることはよくある。
クリックした位置を取得するのは容易だ。流石Unity。

https://docs.unity3d.com/jp/540/ScriptReference/Input-mousePosition.html

これだけでいい。
しかし、これはあくまでScreen上のpointであって、Scene上のpositionに変換してあげなければ 思っていたような動きをしてくれない。

調べると

https://docs.unity3d.com/ja/540/ScriptReference/Camera.ScreenToWorldPoint.html

を使えばOK。
という記事が大量に見つかる。

「OK!やったるで!」

と素直な君はそのまま書くだろう。

が、
「上手く取れない…なんでだ、Unityやっぱクソだな。」
と絶望を感じるだろう。

逆に
「上手く取れた!やっぱUnity神だな。そして俺天才だな。」
と大いに自惚れるだろう。

UnityのCamera

Cameraの投影設定には2つのモードがある。
Perspective
Orthographic
誤解を恐れずに簡潔に言えば、立体投影と平面投影の違いだ。

f:id:ghoul_life:20170516001446p:plain

なんでや

この
Perspective
に設定されている時はz値の設定が無いと
正しく ScreenToWorldPoint で値を変換することが出来ない。 Input.mousePositon はそのままだとxyだけで事足りるのでz値が無いのだ。
このz値を設定してあげれば正しく変換することが出来る。

ScreenToWorldPoint check source file

このソースを実行して画面の真ん中辺りをクリックすると

f:id:ghoul_life:20170515192743p:plain

こんな値が取れる。
ちなみにtmpPos側は画面のどこをクリックしても同じこの値が返ってくる。

また、z値によって変換されて返ってくる値が変わってくるのに注意だ。
「そりゃそうだろ」って話なんだが、
Perspectiveで描画するがゲーム自体は2Dのように動かす、 なんて時には直面するかもしれない。

では
Orthographic
の時はどうだろう?

これはz値が必要ないので、直でもOKだ。
ちゃんと値が変換されて返ってくる。

また、逆にz値に何を入れてもxy値は変わらずに返ってくる。
これも「そりゃそうだろ」って話なんだが、
ハッキリわかっておくと安心出来る。