Unityでクリックした位置にprefabを作成する(Perspective編)
検証環境
Unity:5.6.1f1
カメラの設定
Unityのカメラ設定でProjectionという項目があります。
どのように空間を映すかという設定なのですが、
- Orthographic
- Perspective
の2パターンがあります。
この記事ではPerspectiveの場合について説明します。
Orthographicはこちら code.hildsoft.com
Perspective
設定はカメラのProjectionで変更可能です。
OrthographicもPerspectiveも3次元を2次元に投影する方法ですが、
PerspectiveではPerspectiveとは違いカメラに対して前後の概念も奥行きも影響してきます。
遠くにあるものは小さく、近くにるものは大きく表現されます。
Z正方向を見たカメラに2つのキューブを置きました。
シーンビューで斜め上からPerspectiveで見た図がこちらです。
赤いキューブのZ座標は-5で、緑のキューブのZ座標は0です。
緑から青色の長方形で構成される四角錘台に含まれるものがカメラに映されます。
実際にカメラに映し出されるのがこの図になります。
同じ大きさのキューブですが、赤は遠くにあるため小さく、緑は近くにあるため大きく見えます。これがPerspectiveの特徴です。
通常のカメラでの撮影や人の目の見え方はこの方式になります。
クリックした座標のとり方
画面のクリック位置を取る方法はこちらの記事を参照してください。
prefabを作成
public GameObject prefab; // prefabはインスペクタから与えてください。 private Camera cam; void Start () { this.cam = FindObjectOfType<Camera>(); } void Update () { if (Input.GetMouseButtonUp(0)) { var mousePosition = Input.mousePosition; mousePosition.z += 18f; // カメラのZ座標に+18 //mousePosition.z -= this.cam.transform.position.z; // XY平面上に var worldPoint = this.cam.ScreenToWorldPoint(mousePosition); GameObject.Instantiate(this.prefab, worldPoint, Quaternion.identity); } }
Input.mousePositionのZは常に0です。
Camera.ScreenToWorldPoint(Vector3 v)
で変換すると、カメラが見ている範囲のx,y座標に変換してくれますが、Zはカメラの座標からの相対値が返されます。
Orthographicとは違い、カメラからの距離によって大きさが変わるため、Zの値によってx,y座標も変わってきます。
Zの値を変更しないとカメラと同じ位置にインスタンスを作成されて見えないので、少し前に移動させます。
Orthographicでもそうですが、ScreenToWorldPointを使用しても座標が変わらない、オブジェクトが見えないなどはこの辺が原因であることが多いです。
この例ではカメラのZ=-20に対して+18に設定し、赤と緑のキューブの間に生成されるようにしました。
実行して適当にクリックしてみたのがこの図です。
赤と緑のキューブの間にprefabで指定したキューブが作成されています。
奥行きについて
画面上は同じ座標になっても、奥に行くほどX,Y座標は変わっていきます。
同じ大きさの比較できる物体があれば前後感は分かるようになります。
しかし、遠くに大きな物、近くに小さなものを配置すると画面上の大きさは同じようになります。 Orthographicと同様プログラム内で位置を知りたい場合はraycastなどで調べることになります。
補足
Perspectiveを使う時に大事なパラメータにField of Viewという項目があります。
これは視野を調整するもので、カメラを動かしたときに人間の目との違和感を感じやすい部分になるので3D酔いの原因になります。
人により差があるため、できればユーザーが設定できるようにプログラムを作成した方が良いでしょう。
その際にクリック位置などの補正が必要になることもあるので注意してください。