Quest 開発チームのパートナーは、Quest 用にビルドする際に、Unity の最新バージョンがパフォーマンスやイテレーション速度にどのような影響を与えるかを理解したいと考えていました。Quest 開発チームは Unity と協力して、Unity の LTS と Tech ストリームを含むいくつかのバージョンのエディターをテストし、パフォーマンスを比較しました。同チームの調査結果は、Oculus Developer Blog で発表され、Oculus Developer ドキュメンテーションで詳細な記事を見ることができます。
このブログ記事では、Unity エディターのパフォーマンスの改善に注目し、Quest の開発者が VR 体験のビルドに要する時間を短縮するための情報提供を目的としています。ここで紹介する変更を加えると、皆さんのプロジェクトに若干の修正が必要となる場合があります。あらかじめご了承ください。 テストプロジェクトの詳細と、このドキュメントに示されているデータについては、Oculus Developer ドキュメンテーションの付録をご覧ください。
Unity はバージョンを重ねるごとにビルド時間の短縮が進み、年々驚くほどの進歩を遂げています。たとえば、Quest に携わるパートナーは、テストプロジェクトで次のようなことを発見しました。
これがビルド時間の短縮と安定性の向上のために、最新の LTS を推奨している理由です。最新の LTS へのアップグレード方法はこちらをご覧ください。
Oculus Link を使えば、プロジェクトのイテレーションを素早く行うことができます。ヘッドセットをコンピューターに接続し、エディターでシーンの再生を開始すると、デバイスからの入力による結果がヘッドセット上に直接表示されます。この方法は、ロジックコードの変更、アセットの位置決め、アセットの更新など、デバイスから独立した変更を行う場合に有効です。シェーダーやレンダリングなどデバイスに依存する要素や、デバイス固有のロジックに対するイテレーションを行う場合、この方法はあまり有益ではありません。
開発者がコードだけに変更を行った場合に、生成された APK にパッチを適用するオプションを導入しました。このようなビルド方法を取ると、変更点のビルドにかかる時間をかなり短縮することができます。パッチのビルド方法については、アプリケーションのパッチ処理のドキュメントに詳細が記載されています。
ここでは、主な項目を紹介します。
テストでは、APK にアセットがあるプロジェクトについて、変更されたコードのみをビルドするようにすると、ビルド時間を 45% 短縮できることがわかりました。
Addressable アセットシステムは、アセット構築プロセスとコード構築プロセスを分離します。こうすることで、変更点のみに着目して構築する時間を短縮することができます。
アセットバンドルを基礎として構築された Addressable アセットシステムは、アセット管理全体を簡単にしてくれます。このシステムにより、アセットのグループ分けが効率化され、バンドルにその依存先が確実に含まれるようになります。
また、Addressables にリモートでアセットを読み込ませることも可能です。つまり、Unity の開発マシンにローカルのアセットサーバーを設置し、デバイスに直接アセットを提供することができます。言い換えると、アセットが変更された場合は Addressables をビルドし、デバイス上でアプリを再起動するだけでよいということです。デバイスへの展開は必要ありません。
下の表は Unity LTS 2020.1.15f1 の標準的なプロジェクトと Addressables プロジェクトの比較です。
アセットとコードのビルドを分けることで、APK のビルドが 50% 以上高速化されました。APK を再構築することなく、アセットのみを変更した場合は、高速化率は約 75% に跳ね上がります。
また、使用したマテリアル、プレハブ、メッシュの共有により、アセットは 4 つのグループに分けられています。小さなグループであれば、再ビルドにかかる時間は短くなります。 もう 1 つ重要なのは、複数のグループに依存関係を重複させないことです。例えば、Material1 に依存する Scene1 と Scene2 を考えてみましょう。Scene1 は Group1、Scene2 は Group2 に入っています。Material1 が明示的にグループに含まれていない場合は、両方のグループに含まれることになります。この場合、Material1 を更新すると、Group1、Group2 も同様に更新する必要があります。この場合、メモリの追加やバッチングができないことにより、Material1 のインスタンスが 2 つになってしまうため、実行時に問題が発生する可能性があります。Material1 は、共有グループに入れて、Addressables Analyze ツールで検証した方が良いでしょう。詳細についてはこちらをご覧ください。
テストでは、複数のシーンで同じシェーダーを使用する場合、シェーダーを変更するとビルド時にコストがかかることがわかりました。Addressables システムは、シェーダーに依存する各シーンのロード・アンロードを行い、必要なバリアントをチェックします。1000 シーンを超えるプロジェクトでは、このためビルド時間が長くなってしまいます。
バンドルはマテリアルが、そのマテリアルの使われているシーンに明示的に含まれるように変更されます。つまり、どのシーンで使われているかを基準として、マテリアルをグループに追加していくことになります。Addressables のシステムは、各シーンを開く必要はありませんが、マテリアルを扱うときに止まってしまうのです。
なお、Non-Recursive Dependency Calculations を使うには、Addressable の設定を行う必要があります。 この設定は、Addressable Asset Settings ファイル、または Windows > Asset Management > Addressables > Settings で行うことができます。
以下のデータは、私たちが見出したことを反映しています。
Addressables のドキュメントは、その設定方法を理解するための素晴らしいリソースです。Addressables グループを設定しても、最終製品ではローカルとリモートの両方のグループを設定することになるかもしれません。しかし、すべてリモートにしておいたほうが、イテレーションをするときに便利です。これには、Addressables プロファイルを使用します。ローカルグループをリモートグループと同じ場所にビルドすることができる新しいプロファイルを作成します。読み込みパスもリモートの読み込みパスと同じにします。
ステップ
現在のプロジェクトで Addressables を使用するために変換するのは時間がかかりすぎるという場合、スピーディーに解決する方法があります。Meta 社のチームは、OVR Quick Scene Preview というツールを開発しました。このツールは、プロジェクトをバンドルに分割して、デバイスに直接プッシュすることができます。
ここでは、Unity 2020 LTS と組み合わせた場合の本ツールの性能について、いくつかのデータをご覧いただけます。
クリーンビルドを除くすべての領域で 53% 以上の改善が見られることに注目してください。最初のビルドにかかる時間的コストは高いが、その後のビルドではかなり改善されるということです。
エディターのパフォーマンスやイテレーションにかかる時間の短縮など、今後も進化を続けていきますので、ぜひご自身でも検証してください。 プロジェクト途中での Unity のアップグレードは複雑な作業となる場合があります。最新の LTS の採用とパフォーマンス向上のトレードオフを慎重に判断する必要があります。しかし、Unity Hub を使えば、複数のバージョンの Unity でプロジェクトをテストし、アップグレードに伴う内容を確認することが可能です。さらに詳しい情報は、Unity ワークフローの高速化に関するブログ記事をご覧ください。