画面タッチ スクリーン座標 ワールド座標 ビューポート座標 Canvas座標
Input.mousePosition
マウスクリック時に取得されるInput.mousePositionですが、こちらはスクリーン座標となっており、320×480の場合は⇦が0で右が320になります。
Unityの世界の中ではオブジェクトを作った時の初期状態ではxが0yが0zが0でカメラの中心に存在すると思います。
それなのにスクリーン座標をもとにオブジェクトをクリックした位置に動かそうとするとかなり大変だという事がわかると思います。
そこで座標をわかりやすく変換できる関数をいくつか…
Camera.main.ScreenToWorldPoint
Camera.main.ScreenToWorldPoint(Vector3 position)
これはスクリーン座標をワールド座標に変換する事が出来ます。()の中にInput.mousePositionを入れるとInput.mousePositionのスクリーン座標を変換してくれるといいのですが…
Input.mousePositionはz座標を持っていませんのでそのままクリックするとMainCameraの座標をとってきたりします。なので、z座標をカメラよりも全面の位置に指定して上げて下さい。
void Update () {
if (Input.GetMouseButtonDown (0)) {
Debug.Log ("スクリーン座標" + Input.mousePosition);
Vector3 screen_point = Input.mousePosition;
screen_point.z = 2.0f;
Debug.Log ("ワールド座標" + Camera.main.ScreenToWorldPoint (screen_point));
}
}
こんな感じにして早速確認してみましょう。Cubeオブジェクトはx0y0z0の位置に配置しています。
お気づきかもしれませんが、CubeオブジェクトをクリックしてもCubeオブジェクトと同じxy座標にはなりません。若干ずれてしまいます。
その原因がこちら
3Dの世界では奥行きがあるので、その分ずれてしまいます。
このずれはProjectionを変更する事でひとまず解消してくれます。
こうする事でクリックした位置とコンソールに表示される座標の誤差はなくなったと思います。ただ、このカメラのモードだと3Dでは問題が出てきそうですが…
Camera.main.WorldToViewportPoint(Vector3 position)
つぎにこちら。これはワールド座標をビューポート座標に変換してくれます。
ビューポート座標は左下がx座標0y座標0になり、右上がx座標1y座標1となります。
Canvasの座標をとりたい
CanvasのRectTransformを動かしたいと思った時に座標をどうやってとればいいのか色々考えてたのですがスクリーン座標のままでもいけます。
ただ、Anchor Presetsを変更する必要があります。
左下に設定して下さい。
void Update () {
if (Input.GetMouseButtonDown (0)) {
Debug.Log ("Canvas座標" + Input.mousePosition);
}
}
そう、Input.mousePositionのスクリーン座標のままだとAnchorPresetをBottmLeftに設定すると同じ数値になりました。
RectTransform
左下 PosX0 PosY0
真ん中 PosX216 PosY212
右上 PosX431 PosY424
全てAnchorPresetはBottomLeftですが、Middle Centerにすると真ん中は0,0でTopRightにすると右上は0,0の位置に設定してますが、すべてBottomLeftでのPositionの数値になります。
これで動かしてクリックしてみましょう。
左下から真ん中右上の順番でクリックしてます。左下と右上は画面外にオブジェクトがはみ出ているので大きさは違って見えててなんだかわかりづらいですね…
オブジェクトの中心を押す能力が自分自身にないので誤差はありますが、ほぼ一緒ですね。Canvas上のRectTransformはどうやって取得したらいいのかとものすごい悩んでたのですが、以外にも簡単に終わってしまいました。
たしか昨日のJoystickも結構大変なコードになってたと思うのでその辺綺麗にしないと…
また間違えてたらちゃんと後日なおします!