Unityが無料で発行している公式eBook "Optimize Your Mobile Game Performace"の読み解き企画!今回はユーザー・インターフェイス編となります。
UIは2Dレンダリングを含み、GPUは2Dレンダリングが意外と負荷になるようなので気をつけていきたい部分です。
User interface
UnityUI(UGUI)は往々にしてパフォーマンス上の問題の原因となります。キャンバス(Canvas)・コンポーネントは、UI要素のためのメッシュを生成と更新、GPUに対するドローコールの発行を行います。
この機能はとてもコストが高く、UGUIで作業する際には、各要因について把握するように気をつけてください。
キャンバスを分割しよう
数千の要素を持つ、巨大な一つのキャンバスの場合、ある一つのUI要素を更新しようとするのに伴い、キャンバス全体の更新も強制され、それが潜在的にCPUスパイクを発生させます。
複数キャンバスをサポートする、UGUIの能力の優位点を活用しましょう。各UI要素をそれぞれの求められる更新頻度によって分割してください。
静的なUI要素はそれ用のキャンバスに隔離し、同時に更新される動的要素は小さめのサブ・キャンバスに置くようにしましょう。
各キャンバス内の全ての要素が同じZ値、マテリアルとテクスチャを持つようにしてください。
見えないUI要素を隠す
あるタイミングでしか表示されないUIがあるかもしれません。(ダメージを受けた時にのみ表示される体力バーなど)
そうした見えないUIがアクティブだと、表示されていなくてもドロー・コールを使用している場合があります。
明示的にそうした見えないUIコンポーネントを無効化し、必要になったら再アクティブ化するようにしてください。
キャンバスの可視性を切れさえすればいい場合は、ゲームオブジェクトではなくキャンバス・コンポーネントを無効しましょう。これによって、メッシュと頂点の再構築を抑えられます。
GraphicRaycasterを制限し、Raycast Targetを無効化する
スクリーンタッチやクリックのような入力イベントにはGraphicRaycasterコンポーネントが必要です。これはスクリーン上の各入力ポイントを巡る単純なループで、UnityのRectTransform内にそのポイントがあるかをチェックします。
親ヒエラルキーにあるキャンバスにデフォルトで装着されているRaycasterは削除してください。代わりに相互作用が必要な個別のUI要素ごとにそれぞれRaycasterを装着するようにしましょう。
また、操作が必要ない全てのUIテキストや画像のインスペクター上で、Raycast Targetの項目を無効にしてください。
もし、UIが多くの要素を持ち複雑な場合は、こうした小さな変更の積み重ねによって、不要な計算を減らすことが出来ます。
Layout Groupを避ける
Layout Groupは非効率的に更新されるので、使うならほどほどに。あなたのコンテンツが動的でないなら、完全に避けましょう。均一なレイアウトをするには、代わりにアンカーを使ってください。
あるいは、UIをセットアップした後にLayout Groupを無効にするコードを書いてください。
もし、あなたが動的な要素にLayout Group(横方向、縦方向、グリット状)を使う必要がある場合、ネストを取り除いてパフォーマンスを改善させましょう。
巨大なリスト表示、グリッド表示を避ける
巨大なリスト、グリット表示はコストが高いです。数百のアイテムが並ぶ、巨大な装備品画面のようなリスト、グリッド表示を作る必要がある場合、アイテムごとにUI要素を作るかわりに、保有する小さなUI要素を再利用する、ということを考慮してください。
スクロール・リストのサンプルを確認してみてください。
要素を何枚もたくさん重ねない
多くのUI要素を重ねると、オーバー・ドローが発生します。(カードゲームにおけるカードの積み上げ、など)
ゲーム実行時に、重ねられた要素を少数の要素、batchに統合できるようコードをカスタマイズしてください。
複数の解像度やアスペクト比を使う
モバイルごとに最良の体験が得られるように、別々の違う解像度、アスペクト比を使って、UIの別バージョンを作りましょう。
デバイス・シミュレーターを使って、サポートするデバイス全域に渡り、UIを確認してください。XcodeやAndroid Studioを使って、ヴァーチャル・デバイスを作ることが出来ます。
全画面UIを使う時はその他は全て隠す
シーン上で、ポーズ画面やスタート画面がその他全てを覆うならば、3Dシーンのカメラのレンダリングを無効にしてください。同様に、トップにあるキャンバスによって隠される背景のキャンバスも無効化しましょう。
全画面UIを表示している間、60FPSも必要無いので、Application.targetFrameRateを使って、FPSを下げるということも考えてみてください。
カメラをワールド空間とカメラスペース・キャンバスにアサインする
キャンバスのインスペクターにおいて、Event CameraあるいはRender Cameraの欄を空欄のままにすると、Unityにメインカメラを使わせることを強制しますが、これは不必要にコストが高いです。
もし可能であるなら、キャンバスのRenderModeにはScreen Space - Overlayを使用してください。このモードはカメラが不要です。
(World Space Render Modeを使う場合、Event Cameraの欄はきちんと入力する)
というわけで、ユーザー・インターフェイス編でした。今回も細かいながらも重要な情報ばかりではなかったでしょうか。
これ以降の章は短いものばかりになりますが、一つずつ記事にしていきたいと思います。ラストまでもう少し!走り切るぞい!!
次回はAudio編です。