UnityEdior というか Unity での作業フローの良いところは、インスペクタがあり GUI ベースで作業できるところですよね。
これってモック等ではトライ&エラー出来て速度アップなんですが、いざ仕様や作業フローが決まって”お仕事”となるとアナログの手入力ってのはミスの元でエンジニア的には排除したい方法なんです。
#要求仕様
で、今回のお題。
- 対象のオブジェクト(Mesh等)のサイズは不定、個数も不定、でも画面一杯に描画されるカメラの位置を全て設定したい!
こんな場合に、
- 担当が、オブジェクトやカメラの座標をインスペクでN個分のオブジェクトに対して全て UnityEdior で設定する
- その作業を Editor 拡張して Tool 化して作業しやすくした!
なんてやってませんか?
実はこの手の設定は、数学的に計算出来て Script による制御で全てまかなえます。
味のあるアナログ設定が欲しいんだよ! 的な要求仕様ならば仕方ありません、アナログ作業でいきましょう、、
しかしエンジニアの力は、そのアナログ作業がアプリに致命的なバグや不具合を及ぼさないような仕組みやフローに注力するべきです。
デバッグでチェックするなんて、高度な作業が出来る人間の力という物の無駄遣いの最たるものだと断じます!
(今回の要求仕様のチェックという意味で)
#要件定義
- オブジェクトの大きさは球(円)として持つ(スカラーが1つ)
- 画面の横にフィットさせる(スマフォ縦持ちを想定)
これは今回の説明をしやすくする為で、オブジェクトに縦横の大きさがあり、画面の縦横に対して自動で最大になるように等の細かい要求仕様になるならば、紹介する処理を拡張してください。
#数式
前フリが長くなってしまいましたが、この数式は Unity のドキュメントにもあるんです。
3Dプログラミングでカメラが出てくると使われる"視錐台"ってやつです。
この視錐台の特定の距離の時に切り出した四角形のサイズが求められるって数式(Unityの)です。
この数式の特定の距離ってのを、今回求める値にします。
その代り、四角形のサイズ(これがオブジェクトの大きさ)は既に分かっている。
つまり、式の変形です。
#コード
Unity のドキュメントベースで解説します。
まずオブジェクトの横幅を、特定距離の視錐台の四角形の frustumWidth と捉えます。
そして frustumHeight に変換するためにカメラのアスペクトで除算します。
で、distance(距離)を求める公式にぶち込むだけです(笑)
public float GetCameraDistanceWithWidthSize(Camera camera, float width) {
if (camera == null || width <= 0.0f) {
return 0.0f;
}
float frustumHeight = width / camera.aspect;
return frustumHeight * 0.5f / Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
}
これはカメラ真正面から見た距離なんで俯瞰とかしたいなら、この距離のベクトルを回転させて、それをカメラ座標等にすれば良いだけです。
あとは、オブジェクトのカメラの収まりに遊びを持たせたいなら width 値に掛算して小さくしたり(カメラに収まらなくなる)、大きくしたり(余白ができる)等々と、あなたの発想次第!
ともかく色々と拡張やらすれば大抵の事は実装できるはずです。
コピペして意味もわからず使いたいだけ等の方はゴメンなさいとしか(笑)