Android開発
このセクションでは、Unity Androidアプリのパフォーマンスを向上させるためのガイドラインを示します。
優れたパフォーマンスはすべてのVRアプリにとって重要ですが、スタンドアローン開発に固有の制限については特に慎重に考慮する必要があります。
関連リソース:
このセクションでは、Androidプロジェクトの推奨ターゲットと設定について説明します。
最初からパフォーマンスを控えめに設定します。
- ドローコールを少なめにします。
- テクスチャーの使用方法と帯域幅に注意します。
- 幾何学的な複雑さを最小限に抑えます。
- フィルレートに注意します。
Unityには、バッチ処理やカリングなどのドローコールを削減するためのいくつかの機能が組み込まれています。
Unityは、実行時にオブジェクトを結合し、1回のドローコールでそれらのオブジェクトを描画しようとします。これにより、CPUのオーバーヘッドを減らすことができます。ドローコールのバッチ処理のタイプには、静的バッチ処理と動的バッチ処理の2つがあります。
静的バッチ処理は、移動、回転、スケールしないオブジェクトに使用され、オブジェクトごとに明示的に設定する必要があります。オブジェクトを静的でマークするには、オブジェクトインスペクターの[Static (静的)]チェックボックスをオンにします。

- テクスチャー圧縮: テクスチャー圧縮は、パフォーマンスの面で大きなメリットをもたらします。ASTC圧縮テクスチャー形式を優先します。
- テクスチャーミップマップ: ゲーム内のテクスチャーには常にミップマップを使用します。Unityはインポート時にテクスチャーのミップマップを自動的に生成します。使用可能なミップマップオプションを表示するには、テクスチャーインスペクターの[Texture Type (テクスチャータイプ)]を[Advanced (詳細)]に切り替えます。
- テクスチャーフィルタリング: ほとんどの場合、VRではトリリニアフィルタリングを使用することをおすすめします。パフォーマンスコストはかかりますが、使用する価値はあります。異方性フィルタリングも使用できますが、フラグメントごとに1つの異方性テクスチャールックアップとなるようにしてください。
- テクスチャーサイズ: 幾何学的な詳細よりもテクスチャーの詳細を優先します。例えば、より多くの三角形で高解像度のテクスチャーを使用します。テクスチャーメモリは十分に用意されているので、パフォーマンスの観点から見ると非常に自由度は高いといえます。とはいえ、アセットストアのテクスチャーは、多くの場合、スタンドアローンでは無駄な解像度になってしまいます。多くの場合、これらのテクスチャーのサイズを小さくしても、それほど違いはありません。
- フレームバッファー形式: ほとんどのシーンは、16ビット深度のバッファー解像度で動作するようにビルドしてください。さらに、大部分の作業で圧縮テクスチャーが使用されている場合は、16ビットカラーバッファーを利用できます。
- スクリーン解像度: スクリーン解像度を低い解像度に設定すると、ほとんどのUnityアプリで大幅な高速化を実現できます。
幾何学的な複雑さを最小限に抑えます。控えめなターゲットとして、片目ごと、ビューごとに50,000個の静的な三角形を設定します。
モデルの頂点数がスタンドアローンに適していることを確認します。通常、アセットストアのアセットは忠実度が高いので、スタンドアローン向けのチューニングが必要になります。
頂点シェーダーがスタンドアローンに対応していることを確認します。組み込みのシェーダーを使用する場合は、シェーダーの[Mobile (モバイル)]または[Unit (ユニット)]バージョンのシェーダーを使用してください。
シーンを作成するときは、ゲームオブジェクトの数に注意してください。シーン内のゲームオブジェクトとレンダラーの数が多いほど、メモリの消費量は多くなり、Unityがシーンをカリングしてレンダリングするのに多くの時間がかかります。
ピクセルの複雑性: テクスチャーの詳細を可能な限りベイク処理して、ピクセルごとの計算を減らします。例えば、スペキュラーハイライトをテクスチャーにベイク処理すると、フラグメントシェーダーでハイライトを計算する必要がなくなります。
フラグメントシェーダーがスタンドアローンに対応していることを確認します。組み込みのシェーダーを使用する場合は、シェーダーの[Mobile(モバイル)]または[Unlit(照明なし)]バージョンのシェーダーを使用してください。
オーバードロー: Unityの不透明キューにあるオブジェクトは、深度テストを使用して前から後の順でレンダリングされるため、オーバードローを最小限に抑えることができます。ただし、透過キューのオブジェクトは、深度テストなしで後から前の順にレンダリングされるため、オーバードローになりがちです。
アルファブレンドされたジオメトリ(例: 密集したパーティクルエフェクト)とフルスクリーン事後処理エフェクトが重複しないようにします。
VRヘッドセットの機能は、デバイスの処理能力と熱を放散する機能による制限を受けます。Fixed Clock Level APIとDynamic Clock Throttlingを使用して、ヘッドセットの熱と電力消費を管理できます。これら2つの機能の詳しい概要については、Mobile SDKガイドの
電源管理のページをご覧ください。
Unityアプリでクロックレベルを設定するには、OVRManager.cpuLevel ( )
およびOVRManager.gpuLevel ( )
を設定します。
このセクションでは、Androidプロジェクトのベストプラクティスについて説明します。
- バッチ処理に対応している必要があります。可能な場合は、マテリアルをシェアし、テクスチャーアトラスを使用します。
- 光源マップされた静的ジオメトリを優先します。
- 文字や移動するオブジェクトには、動的なライティングではなくライトプローブを優先します。
- 事前計算されたGIではなく、ベイクされたライトマップを常に使用します。
- 非平行光源マッピングを使用します。
- 詳細を可能な限りテクスチャーにベイク処理します(例えば、スペキュラー反射、周囲オクルージョンなど)。
- 片目につき1つのビューのみをレンダリングします。シャドウバッファー、反射、マルチカメラのセットアップなどを付けません。
- レンダリングパスの数を最小限に抑えます。そのためには、動的ライティングなし、ポストエフェクトなし、バッファーを解決しない、シェーダーでのグラブパスを使用しないなどの方法があります。
- アルファテスト/ピクセル破棄の透過性を回避します。アルファテストでは、パフォーマンスのオーバーヘッドが高くなります。可能であれば、アルファブレンドで置き換えます。
- アルファブレンドされた透過性を最小限に抑えます。
- 必ずテクスチャー圧縮を使用してください。グローバル設定としてASTCテクスチャー圧縮を使用することをおすすめします。
- [Player Settings(プレイヤー設定)]の[Resolution and Presentation(解像度とプレゼンテーション)]ペインにある[Disable Depth and Stencil(深度とステンシルを無効にする)]*チェックボックスをオンにします。
- GPUスロットリングを必ず初期化し、危険な値(-1、または3より大きい)を避けてください。詳細については、Mobile SDK開発者ガイドの電源管理を参照してください。
- フルスクリーンの画像エフェクトを避けます。
- クリア付きの複数のカメラを使用する際は注意してください。使用すると、過剰な充填コストが発生する可能性があります。
- LoadLevelAsyncやLoadLevelAdditiveAsyncの使用を避けます。これはフレームレートに大きな影響を与えます。一般的に、ブラックに移行してから同期的にロードすることをおすすめします。
- 標準シェーダーや標準スペキュラーシェーダーの使用を避けます。
- プロジェクターは使用を避けるか、注意して使用してください。コストが非常に高くなる可能性があります。
- UnityのDefault-Skyboxは避けてください。これはスタンドアローンでは計算コストが高くなります。Skyboxを[None (Material) (なし(マテリアル))]に設定し、[Window (ウィンドウ)] > [Lighting (照明)]で[Ambient Source (アンビエントソース)]を[Color (カラー)]に設定することをおすすめします。Camera.clearFlagsをSolidColorに設定することもできます(Skyboxは使用しないでください)。
- シーンで使用するゲームオブジェクトとコンポーネントの総数に注意してください。
- ゲームデータとオブジェクトを効率的にモデル化します。通常、十分な量のメモリがあります。
- Update()またはFixedUpdate()で実際に計算を実行するオブジェクトの数を最小限にします。
- 物理シミュレーションが実際に必要でない場合は、減らすか無くしてください。
- 実行時に新しいオブジェクトを割り当てるのではなく、オブジェクトプールを使用して、頻繁に使用するエフェクトやオブジェクトを再スポーンします。
- PlayOneShotサウンドではなくプールされたAudioSourcesを使用します。PlayOneShotサウンドはゲームオブジェクトを割り当て、サウンドの再生が終了したらそれを破棄します。
- 可能な限り、コストのかかる数学演算を避けてください。
- 頻繁に使用されるコンポーネントと変換をキャッシュして、フレームごとの検索を避けます。
- Unityプロファイラーを使用して以下のことを行います。
- コストの高いコードを特定し、必要に応じて最適化します。
- 各フレームで発生するガベージコレクションの割り当てを特定して排除します。
- 通常のプレイ中の急なパフォーマンスの上昇を特定して排除します。
- UnityのOnGUI()呼び出しを使用しないでください。
- ジャイロまたは加速度計を有効にしないでください。Unityの現在のバージョンでは、これらの機能はコストの高い表示呼び出しをトリガーします。
- 通常、スタンドアローンアプリとゲーム開発のすべてのベストプラクティスが適用されます。
このセクションでは、開始シーケンスの推奨事項と、スタンドアローンアプリに必要な必須動作について説明します。
優れたVRエクスペリエンスのためには、ユーザーが常に適切な3次元立体画像を見られるように、すべてのグラフィックをレンダリングする必要があります。さらに、ヘッドトラッキングを常に維持する必要があります。開始画面にキューブマップオーバーレイを使用することをおすすめします(
VRコンポジターレイヤーを参照)。これにより、アプリがシーンをアップデートできないときでも一貫したフレームレートでレンダリングされます。
アプリの開始時にこれを行う方法の例は、SDKExamples Startup_Sampleシーンで説明されています。
- 可能な限り短時間で、黒一色のスプラッシュ画像を表示します。
- 3Dロゴと3D回転ウィジェットまたは進行メーターを含む小さなテストシーンがすぐに読み込まれます。
- 小さな開始シーンがアクティブである間に、メインシーンがバックグラウンドで読み込まれます。
- メインシーンが完全に読み込まれると、フェードを使用して開始シーンがメインシーンに移行します。
音量ボタンは予約済みであり、Samsungデバイスの音量調整は自動的に処理されます。音量コントロールダイアログは、Mobile SDK 1.0.3以降、VrApiによっても自動的に処理され、Utilities for Unityバージョン1.5.0以降でサポートされています。独自の音量処理ディスプレイを実装しないでください。実装すると、2つの並置されたディスプレイが表示されます。
VRAPI_FRAME_FLAG_INHIBIT_VOLUME_LAYERをovrFrameParmフラグとして設定することにより、自動音量表示処理をオーバーライドできます。