Unity Webビルドのプロファイルと最適化
この記事では、Unity Webプロジェクトを最適化するためのヒントを提供します。
以前は「WebGL」と呼ばれていたUnity Webプラットフォームのサポートには、より多くのデバイスの摩擦を減らし、最新のグラフィックスAPIを活用することで、最も野心的なWebゲームでもスムーズなフレームレートと卓越したパフォーマンスを保証する、重要な進歩が含まれています。
これには、ブラウザに2Dおよび3Dグラフィックスを高速でレンダリングするJavaScript APIであるWebGLのサポートも含まれる。Google Chrome、Mozilla Firefox、Safari、Microsoft EdgeはすべてWebGL 2コンテンツをサポートしています。WebGL 2はOpenGL ES 3.0をベースにしています。
グラフィックAPIに関係なく、Unity Webゲームは、ウェブサイトやソーシャルメディアに配布したり埋め込んだりするのに効率的なように、サイズを小さくすることを目指すべきです。Webビルドは、プロトタイピングやゲームジャムなど、配布が容易であることが重要な場合にも使用できます。
ウェブゲームはローカルファイルやハードウェアにアクセスできないため、一般的にネイティブコンパイルされたゲームより若干パフォーマンスが劣る。
注:新しいAPIであるWebGPUは、Unity 6ベータ版(2023.3.0b1ベータ版)で早期アクセス可能です。WebGPUはまだ開発中であり、本番環境での使用は推奨されていない。
WebGPUは、最新のGPU機能をウェブで利用し、公開することを目標に設計されました。この新しいウェブAPIは、DirectX12、Vulkan、MetalなどのネイティブGPU APIを介して内部実装される最新のグラフィックスアクセラレーションインターフェースを提供します。具体的なネイティブ実装は、ブラウザのプラットフォームと利用可能なグラフィックドライバに依存する。WebGPUを使い始めるための詳細やその他のWebGPUデモは、グラフィックス・フォーラムでご覧いただけます。
Unity Webプラットフォームにデプロイするには、まずUnity EditorにWebモジュールを追加してWebビルドを作成する必要があります。Unity Hubでインストールを見つけ、Settingsアイコンをクリックし、Add modulesを選択します。
新しいダイアログボックスで、下にスクロールしてWeb Build Supportを見つけ、それを選択してDoneをクリックします。
プロジェクトを再度開き、[File] > [Build Settings]でターゲット・プラットフォームを切り替えます。ゲーム開発中は、Development Buildオプションを使用してください。スタックトレース、詳細なエラーメッセージ、ロギング情報などの追加デバッグ情報を提供し、トラブルシューティングやゲームへの変更を支援します。ゲーム・コード、アセット、設定に小さな変更を加えれば、完全なビルド・プロセスを必要とすることなく、その変更をブラウザ上で素早く再構築し、テストすることができます。
最終的な公開ビルドでは、ビルド設定の開発ビルドオプションのチェックを外してください。
Build And Run(ビルドして実行)を選択すると、プレイテスト用のブラウザで動作するバージョンのゲームが作成されます。Google Chromeは多くの開発者ツールを提供しているので、プレイテストに適している。
ビルドの場所を選択するプロンプトが表示されます。ビルド内のファイルには、HTML5のCanvas要素をDocument Object Model(DOM)に追加するindex.htmlファイルが含まれます。DOMは、ウェブ上のドキュメントの構造とコンテンツを構成するオブジェクトのデータ表現です。ゲームはこのキャンバスにレンダリングされる。ビルドファイルには、TemplateDataフォルダとBuildフォルダも含まれる。TemplateDataフォルダには、ブラウザのアドレスバーで使用されるファビコンや、ページのHTMLマークアップで使用される画像など、ページで使用されるHTMLアセットが含まれています。
自動ビルドを設定することもでき、Unity Build Automationはそのためのオプションの1つだ。
Webゲームには、ビルトインレンダリングパイプラインまたはユニバーサルレンダリングパイプライン(URP)を使用できます。しかし、URPを推奨する理由は、複数のハードウェア・デバイスに対してコンテンツの効率的なカスタマイズとスケーリングが可能だからです。
ビルトインレンダリングパイプラインからURPにプロジェクトを移行するための詳細なインストラクションを電子書籍で入手できます。 Unity上級クリエイターのためのUniversal Render Pipeline入門.
コンソールをターゲットにする場合、メモリやCPU、GPUの使用率について正確なスペックがある。ウェブはまったく別物だ。あなたのゲームをより多くの人に楽しんでもらうためには、制限されたメモリ環境でもうまく動作するようにする必要があります。
ローエンドのハードウェアでゲームをスムーズに動作させるためのヒントを、電子書籍から抜粋してご紹介します。 モバイルゲームのパフォーマンスを最適化する.
1.ゲーム資産の最適化
テクスチャやモデルなどのアセットをウェブ用に最適化する。たとえば、圧縮テクスチャを使用したり、モデルのポリゴン数を減らしたりする。決まったルールがあるわけではありませんが、パフォーマンスの一貫性を確保するために、チーム内でいくつかの一般的なガイドラインを取り決めましょう。
2.オブジェクト・プーリングを使用する
オブジェクト・プーリングは、新しいオブジェクトを生成・破棄する代わりにオブジェクトを再利用することで、パフォーマンスを向上させるテクニックだ。これは、スポーンやデスポーンが多いゲームで役に立つ。フライホイールのような他のプログラミング・デザインパターンも役に立つ。電子書籍を見る ゲームプログラミングパターンでコードをレベルアップを参照してください。
3.ユニバーサルレンダリングパイプラインとSRPバッチャーの使用
シーンに応じてCPUレンダリングを高速化するUnityのSRPバッチャシステムでパフォーマンスを向上。これは、シェーダーやテクスチャーなどの共有マテリアル・プロパティに基づいて描画コールをグループ化することで、レンダリング中に必要な状態変更の回数を減らすことで機能する。
4.オクルージョンカリングを使用する
Unityのオクルージョンカリングシステムは、プレイヤーに見えるオブジェクトだけをレンダリングすることで、パフォーマンスを向上させるのに役立ちます。オクルージョンカリングは、廊下でつながった部屋のように、小さくて明確なエリアがソリッドなGameObjectで区切られているシーンで効果的です。
5.内蔵のLOD(詳細レベル)システムを使用する
UnityのビルトインLODシステムは、プレイヤーから遠いオブジェクトの複雑さを軽減することで、パフォーマンスを向上させます。カメラとオブジェクトの距離が離れると、LODシステムは自動的にオブジェクトの高詳細バージョンと低詳細バージョンを入れ替え、首尾一貫した外観を維持しながらレンダリングの作業負荷を軽減します。
4.可能な限り照明を焼く
ライトマップと ライトプローブを使ってシーンのライティング情報を事前に計算し、パフォーマンスを向上させましょう。
4.不必要な文字列の作成や操作を減らす
C#では、文字列は参照型であり、値型ではない。JSONやXMLのような文字列ベースのデータファイルの解析は避け、代わりにScriptableObjectやMessagePackやProtobufのような形式でデータを保存する。また、永続的なゲームデータ(セーブゲーム)を保存する場合などには、バイナリ形式を検討することもできる。実行時に文字列を構築する必要がある場合は、StringBuilderクラスを使用する。
4.Addressable Asset System を試す
Addressable Asset Systemは、AssetBundleを "アドレス "または別名でロードすることで、コンテンツ管理を簡素化します。この統合システムは、ローカルパスまたはリモートのコンテンツ・デリバリー・ネットワーク(CDN)のいずれかから非同期にロードする。
4.後処理効果を制限する
フルスクリーンのポストプロセッシングエフェクトはパフォーマンスを低下させる可能性があるため、ゲームでは控えめに使用しましょう。
Unity Webビルドを作成すると、Unityはテンプレートを使用してゲームを表示するWebページを生成します。
デフォルトのテンプレートは以下の通り:
- デフォルト:グレーのキャンバスにローディング・バーのある白いページ
- 最小限だ:ゲームの実行に必要な最小限のボイラープレート
- プログレッシブ・ウェブ・アプリ(PWA):これにはウェブマニフェストファイルとサービスワーカーが含まれます。適切なデスクトップブラウザでは、アドレスバーにインストールボタンが表示され、プレイヤーの起動可能なアプリケーションにゲームが追加されます。
<UnityInstallation>/PlaybackEngines/ WebGLSupport/ BuildTools/ WebGLTemplates/から見つけることができます。 Macの場合、アプリケーションフォルダにUnityインストールフォルダがあります。
テンプレートをコピーし、自分のProject/Assets/WebGLTemplatesフォルダに置き、後で識別できるように名前を変更します。ゲーム内容、配備サイト、ターゲットプラットフォームに合わせてカスタマイズできるようになりました。
プロジェクトのWebGLTemplatesフォルダにあるテンプレートは、Edit > Project Settings... > Player > Resolution and Presentationパネルに表示されます。テンプレートの名前は、そのフォルダと同じです。このオプションにサムネイル画像をつけて簡単に参照できるようにするには、テンプレート・フォルダーに128×128ピクセルの画像を追加し、名前をthumbnail.pngとします。
ビルドプロセス中、Unityはテンプレートファイルをプリプロセスし、それらのファイルに含まれるすべてのマクロと条件ディレクティブを評価します。エディターが提供する値ですべてのマクロ宣言を見つけて置き換え、テンプレートフォルダー内のすべての.html、.php、.css、.js、.jsonファイルを自動的に前処理します。
例えば、次のコードを見てみよう:
<canvas id="unity-canvas" width={{{ WIDTH }}} height={{{ HEIGHT }}} tabindex="-1"></canvas>
解像度とプレゼンテーション」パネルで「デフォルトのキャンバスの幅」を960に、「デフォルトのキャンバスの高さ」を600に設定すると、前処理後のコードは次のようになります:
<canvas id="unity-canvas" width="960" height="600" tabindex="-1"></canvas>.
三重中括弧は、指定された変数の値を見つけるようコンパイラに指示する。
また、デフォルトのテンプレートには、#if、 #else 、 #endifを使った条件付きディレクティブの例もあります:
#if EXPRESSION
//EXPRESSIONが真理値として評価された場合
#else
//EXPRESSIONが真理値として評価されない場合
#endif
カスタムテンプレートを使用したい場合は、Unity AssetStoreに多くのオプションが用意されています。
ブラウザベースのゲーム用プラットフォームでゲームを共有する場合は、index.htmlページを仕様に合わせる必要があります。その方法については、ウェブゲームの人気プラットフォームのドキュメントを参照してください:
レスポンシブ・デザインに対応するために、ブラウザ・ウィンドウのサイズを変更したいことがよくあるでしょう。JavaScriptでは、これを実現するために「Promise」を使うことができる。Promiseは、まだ完了していないが、将来完了することが期待されている操作を表す。
各テンプレートのindex.htmlページ(以下のコード例を参照)で、script.onloadを見つける。script.onloadは、Unityのエンジンスクリプトのロードが完了したときにトリガーされるイベントです。myGameInstanceはUnityインスタンスへの参照を保持し、myGameLoadedはゲームのロードが終了したかどうかを示し、デフォルトはfalseです。これらはvarとして宣言されているので、グローバル・スコープを持ち、スクリプトのどこにでもアクセスできる。
createUnityInstance()関数は、Unityゲームの新しいインスタンスを作成するために呼び出されます。この関数は、ゲームが完全にロードされ、レンダリングの準備ができたときに解決されるPromiseを返します(createUnityInstance Promiseのthenブロック)。
then()内では、myGameInstanceにUnityインスタンスが代入され、myGameLoadedがtrueに設定される。その後、resizePage()関数が呼び出され、最初にゲームのサイズが設定されます。そして、ウィンドウのサイズ変更イベントにイベントリスナーが追加され、ウィンドウのサイズが変更されるたびにゲームのサイズが更新されます。以下のコード・スニペットを参照。
次のコード・スニペットに示すように、スクリプトの一番下にresizePage関数があります。ゲームが読み込まれると、ゲームを表示するキャンバスのスタイル値をウィンドウのサイズに合わせて設定し、ウィンドウいっぱいに表示します:
function resizePage(){
if (myGameInstance !== undefined && myGameLoaded === true)
{
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
}
}
ブラウザをターゲットにした多くのゲームでは、ユーザーログインやハイスコア表などをサポートするウェブサービスを呼び出したり、ブラウザのDOMとやりとりしたりするために、JavaScriptコードとやりとりする必要があります。C#スクリプトから呼び出せるように直接追加するJavaScriptは、拡張子が.jslibで、Assets/Plugins フォルダに置く必要があります。これはmergeIntoメソッドでラップされるべきである。これには2つのパラメータが必要である:LibraryManager.libraryと、次に1つ以上の関数を含むJavaScriptオブジェクト。関数は標準的なJavaScriptである。GetExchangeRatesは、以下のシンプルなJSON配信ウェブサービスの使い方を示しています。
ビルドを作成すると、これらの関数がBuild/<ゲーム名>.framework.js ファイルに追加されます。このコード例に示すように、関数をDllImportとして宣言することで、C#スクリプトからこれらの関数を呼び出すことができます:
public class SphereController :MonoBehaviour
{
[DllImport("__Internal")]
private static extern void GetExchangeRates();
private void Start()
{
GetExchangeRates();
}
}
詳細情報
C#がJavaScriptの関数を呼び出すだけでなく、JavaScriptがC#のメソッドを呼び出すこともできる。このメカニズムにはメッセージング・プロトコルが使われている:
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, 5)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, ‘A string’)
SendMessageを使うには、スコープ内のゲームインスタンスへの参照が必要です。通常のテクニックは、index.htmlを編集してグローバル変数を追加し、先に見たようにscript.onload Promiseのthenブロックにこの変数を代入する。このシンプルな関数は、SphereというGameObjectに付けられたMonoBehaviour Componentの一部として追加される。
public void SetHeight( float height )
{
Vector3 pos = transform.position;
pos.y = height;
transform.position = pos;
}
F12キーでクロームのコンソールを開き、直接次のように入力します:
myGameInstance.SendMessage('Sphere', 'SetHeight', 3)
Enter キーを押して、関数Moving the Sphere を呼び出します。動きがレンダリングに反映されるのは、Run In Backgroundが 設定されているか、Application.runInBackgroundをtrueに設定した場合のみです。デフォルトでは、レンダリングはキャンバス・ウィンドウにフォーカスがあるときにのみ行われるからだ。
ブラウザ・プラットフォームのデバッグにはDebug.Logを使用する。メッセージはすべてブラウザのコンソールに送られる。クロームの場合、F12キーを押し、コンソールタブに切り替えると表示されます。しかし、Debugクラスにはもっと多くのオプションがある。Debug.LogErrorを使うと、コンソールにスタックトレースが表示されるので便利です。
詳細情報
開発中はDevelopment Buildオプションを使用することをお勧めしますが、ゲームをライブサイトにデプロイする際にはこのオプションのチェックを外してください。リリースビルドの場合、圧縮のオプションがある。圧縮を使用する場合、サーバーの設定を調整する必要があるかもしれません。
開発サイクル全体を通してプロジェクトをプロファイリングすることは、パフォーマンスの問題をいち早くキャッチするために重要である。Unity Profilerは、ゲームのパフォーマンスボトルネックを特定し、修正するための優れたツールです。CPUとメモリの使用状況を追跡し、最適化が必要なゲームの領域を特定するのに役立ちます。また、Profile Analyzer、Memory Profiler、Web Diagnostics Overlayを並行して使用することもできます。
電子書籍をダウンロードする Unityゲームプロファイリングアルティメットガイドをダウンロードして、Unityのプロファイリングについて詳しく学びましょう。
Unity Webビルドのプロファイリングを始めるためのヒントを見てみましょう。
Unityのプロファイラを有効にする
EditorのFile > Build Settingsで、Development Build andAutoconnect Profilerを 選択し、WebビルドでProfilerを使用する。
CPU Usageモジュールを選択
このモジュールを使用して、コードのパフォーマンスを分析し、パフォーマンスの問題を引き起こしている箇所を特定します。関数呼び出し、スクリプト実行、ガベージコレクションなどの要素を分析する。
Memory Profilerモジュールを選択
UnityのWebビルドは、他のプラットフォームに比べてメモリリソースが限られています。このモジュールを使用して、アプリケーションのメモリ使用量を分析し、最適化のための領域を特定します。
Chrome DevToolsのパフォーマンスパネルを使用する
Chrome DevToolsには、ゲームのボトルネックを掘り下げるのに役立つパフォーマンスパネルがあります。その他の機能としては、JavaScriptファイルにブレークポイントを追加するためのSources パネルと、デバッグメッセージを表示したりJavaScriptコードを入力したりするためのConsole パネルがあります。
さまざまなデバイスでパフォーマンスを測定
これにより、特定のデバイスやブラウザに特有のパフォーマンスの問題を特定し、それに応じてゲームを最適化するのに役立ちます。
ドローコールの回数を減らす
ドローコールはUnity Webビルドの主なパフォーマンスボトルネックの1つです。Unity Profilerを使用して、描画コールの多いエリアを特定し、その数を減らしてみてください。
ローエンドデバイスでのパフォーマンス分析
ローエンドのデバイスでテストし、アプリケーションが幅広いハードウェアに最適化されていることを確認します。
プロファイリング中に「バックグラウンドで実行」を有効にする
WebGL Player Settings でRun In Backgroundを有効にするか、Application.runInBackground を有効にすると、canvas やブラウザ ウィンドウのフォーカスが外れてもコンテンツが実行されます。
Unity Webビルドは、ゲームを幅広いユーザーに配信するための素晴らしい方法です。開発中は、ジオメトリとテクスチャを適度なサイズに抑え、描画コールを減らし、幅広いデバイスでプロファイルとテストを行うことを目指すべきである。最後に、URPを使用して、最も幅広いハードウェアで確かなパフォーマンスを確保する。
詳細情報
Unity 2023.3の新しいWebGPUバックエンドへの早期アクセス
ウェブランタイムの公式アップデートはこちらブラウザを次のレベルへ
Unityのベストプラクティス・ハブでは、Unityの先進的な電子書籍や記事をすべてご覧いただけます。