見出し画像

カメラ範囲の伸縮(Unityメモ)

技の名前っぽいなと思った

前の記事の続き。

ゲーム画面実装のテストとして、UI要素を実装したりしました。そんな中でいろいろと実装を検討しました。

Canvasを使ってUI要素を表示

以下のようなハマり方をする人は他にいないと思いますが念のため。
まず、シーン内にUI要素のSpriteRendererを直に置くのもどうかと思ったので、UIレイヤーにあるCanvasの下に置いたら色が描画されなくて困りました… 2Dライトを用意してUIレイヤーに設定すると色が出ました。Spriteも3Dオブジェクトの延長だと分かった次第。
それと、Canvasのレンダーモードを「ワールド空間」にしないとUnit基準で長さを計算してくれませんでした。他のモードだとピクセル基準(1px = 1Unit)となるので表示が大変なことになりました。
Unit基準でのレイアウト設計をするときはCanvasはワールド空間一択かも。

異なるアスペクト比への対処

・モニタの実寸法に合わせて全体的に伸縮させる
・モニタのアスペクト比が変わっても、UIやユニットの配置は開発時のまま保ちたい
  →背景のみをアスペクト比に応じて伸縮させる

開発中の基準画面。24:12の比率。ゲーム開始直後
22:10表示、ロード時。背景の外枠が表示される
16:9表示、ロード時。UIがはみ出るというより表示範囲が切り落とされる

モニタの実寸法の違いについては、ピクセルではなくUnit基準でレイアウトを設計しておけば問題にはなりにくいです。カメラの画角とモニタのアスペクト比を基に表示幅・高さのUnit数が決まるので、あとはUnityが自動で伸縮してくれます。特にカメラが正射投影の場合、sizeプロパティで高さの半値のUnit数を指定できるので、高さの寸法を基準にしてUIのレイアウトを決められます。
開発テストではsize=6(つまり高さ12Unit), アスペクト比としては24:12(つまり2:1)でレイアウトを作っています。2:1のアスペクト比は、FHDの16:9とiPhoneの約22:10 (19.5:9) の間になる比率として決めました。

少し考える必要があったのはモニタごとのアスペクト比の違いでした。開発時と異なるアスペクト比を使うと、そのままではUIが伸縮します。
開発時より横長なモニタについては、解像度の全画面モードを「全画面表示ウィンドウ」にしてUnity側でレターボックス表示させることで、UIの配置を引き延ばさずキープできます。ちなみに背景をあらかじめ横長の分を含めて確保しておくと、レターボックスになった時にもきれいに表示されます。
しかし縦長になるケースではレターボックスにならず、上の16:9表示のようにUIがはみ出してしまいます。

テスト用の背景画像。縦にも枠を入れたがレターボックスにならなかった

縦長のレターボックスにならないのは、Unityがシーンの描画対象範囲を決めるときに、縦の画角を固定してから表示先のアスペクト比を用いて横幅を決めるためです。このとき、表示先のアスペクト比が正方形に近いほど、開発時の画面寸法に対して表示範囲が端から切り落とされることになります。開発時のアスペクト比24:12よりも16:9の方が横幅が短いため、端が切られて表示された、というわけです。

開発時よりもモニタの横幅が短い、ということは、横幅を揃えるとモニタの方が縦長、ということです。そこで、開発時とモニタとのアスペクト比の差に応じて、カメラのsizeプロパティ、つまり縦の画角を伸ばしてやると、より相対的に縦長なモニタでもUIが切れずに表示できました。

ユニットやメッセージのTween

・ユニットを任意の対象へ向けて往復移動させる
・技名のようなメッセージを一定時間表示する

まずは基本的な演出の実装です。当初はUnityのTimeline機能を使おうとしたのですが、スクリプトで任意の対象を設定するのが難しそうだったので、定番のDOTweenライブラリを使って実装することにしました。

組んだもの

異なるアスペクト比に対して、ゲーム要素を画面に残しつつ背景を伸縮できました。あとユニットの動きの演出を組めるようになりました。
技名のテストで長い名前を探していたのですが、オーソグラフィックプロジェクション(正射投影)がちょうどそれっぽかったので…

22:10表示、ユニット移動中。
背景を伸縮したので外枠は映らない
20:10(基準)、ユニット移動中
16:9表示、ユニット移動中
16:10表示、ユニット移動中
上下が余り過ぎるので枠をつけたほうが良いかも

この記事が気に入ったらサポートをしてみませんか?