こんにち(ばん)は。
菅原だ。
今回は、解像度やアスペクト比の異なる端末への対応方法の話をする。
GUIの話ではなく、3D空間上のオブジェクトの話だ。
やりたいこと
どんな解像度の端末でも、画面幅ピッタリにオブジェクトを表示したい
利用用途としては、
・オセロとか将棋で盤を画面いっぱいに表示したい
・ボンバーマンみたいな上からステージ全体を見下ろすゲーム
とか。
考えると他にも浮かんでくるZE。
これを実現するために・・・
パッと思い浮かぶ方法は、
カメラとオブジェクトの距離を調整する
だろうか。
今回はそれを自動化する方法を紹介しよう。
【カメラとオブジェクトの距離を調整する】
カメラとオブジェクトの関係を横から見てみるとわかりやすい。
求めたいのは「FocalLength(焦点距離)」の部分だ。
※上図ではわかりやすく下半分を薄くしてあるが、FOVもapertureも上下合わせた部分となる
三角関数を駆使すると求めることが出来る。
この処理をメソッド化してみた。
/*!
@brief 焦点距離(FocalLength)を求める
@param[in] fov 視野角(FieldOfView)
@param[in] aperture 画面幅いっぱいに表示したいオブジェクトの幅
@return 焦点距離(FocalLength)
*/
float focalLength (float fov, float aperture) {
// FieldOfViewを2で割り、三角関数用にラジアンに変換しておく
float nHalfTheFOV = fov / 2.0f * Mathf.Deg2Rad;
// FocalLengthを求める
float nFocalLength = (0.5f / (Mathf.Tan (nHalfTheFOV) / aperture));
// Unityちゃんは画面高さ(Vertical)なFOVなので画面アスペクト比(縦/横)を掛けとく
nFocalLength *= ((float)Screen.height / (float)Screen.width);
return nFocalLength;
}
使い方はこんな感じ。
// 例えば、サイズが10.0のオブジェクトを画面幅いっぱいに表示したい場合(上から見下ろすカメラにしてみる)
// カメラを取得
Camera cam = gameObject.GetComponent();
// FocalLengthを求める
float nFocalLength = focalLength (cam.fieldOfView, 10.0f);
// 上から見下ろすカメラにするので、position.yの値をFocalLengthにする
cam.transform.position = new Vector3(transform.position.x, nFocalLength, transform.position.z);
これで、どんな解像度、アスペクトでも画面幅いっぱいにオブジェクトを表示できるようになった。
インスペクタビューのPositionのYに注目してもらいたい。
ここが自動で算出された値だ。
iPhone5
iPhone4
iPad
一点、注意しなくてはいけないがある。
ここで求めたのは、カメラと表示面との距離なので、
厚みのあるオブジェクトの場合は、その厚みを考慮しなくてはいけない。
例えば、半径10の球体を画面幅に表示したい場合は、
「上記のメソッドで求めた距離 + 10」が答えとなる。
■終わりに
わかりやすく「画面幅ピッタリにオブジェクトを表示したい」としたが、
オブジェクトに限らず、表示したい範囲を調整するのに便利だ。
ところでところで、実はUnityではもっと簡単な方法で出来たりするんじゃないだろうか。
出来そうな気もするが、まだ、Unityの知識が浅いため答えにはたどり着いていない・・・。
良い方法をご存知の方がおりましたら、ご教示頂けると幸いです。