
Unity Webビルドの分析と最適化
この記事では、Unity Webプロジェクトを最適化するためのヒントを提供します。
以前は「WebGL」と呼ばれていた Unity Web プラットフォームのサポートには、より多くのデバイスの摩擦を減らし、最新のグラフィックス API を活用して、最も野心的なウェブゲームでもスムーズなフレームレートと並外れたパフォーマンスを実現する重要な進歩が含まれています。
これには、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 デモは、グラフィックスフォーラムで確認できます。

ビルドの作成
Unity Web プラットフォームにデプロイするには、まず Unity エディターに Web モジュールを追加して Web ビルドを作成する必要があります。Unity Hub でインストールを見つけ、「Settings」アイコンをクリックして「Add modules」を選択します。
新しいダイアログで、下にスクロールして「Web Build Support」を探し、それを選択して「Done」をクリックします。
プロジェクトを再度開き、「ファイル」>「構築設定」でターゲットプラットフォームを切り替えます。ゲーム開発中は Development Build オプションを使用してください。スタックトレース、詳細なエラーメッセージ、ロギング情報など、ゲームのトラブルシューティングや変更に役立つ追加のデバッグ情報を提供します。ゲームコード、アセット、設定に小さな変更を加え、完全なビルドプロセスを必要とせずにブラウザーでその変更をすばやく再構築してテストできます。
ビルド設定の Development Build オプションのチェックを外さないようにしましょう。
「Build And Run」を選択して、テストプレイのためにブラウザーで実行されるゲームのバージョンを作成します。Google Chrome は多くの開発者ツールを提供しているため、テストプレイに適しています。
ビルドの場所を選択するよう求められます。ビルド内のファイルには、HTML5 Canvas 要素を Document Object Model(DOM)に追加する index.html ファイルが含まれています。これは、ウェブ上のドキュメントの構造とコンテンツを構成するオブジェクトのデータ表現です。ゲームはこのキャンバスにレンダリングされます。ビルドファイルには TemplateData フォルダーと Build フォルダーも含まれます。TemplateData フォルダーには、ブラウザーのメニューバーで使用されるファビコンや、ページの HTML マークアップで使用される画像など、ページで使用される HTML アセットが含まれています。
また、自動ビルドを設定することもできます。Unity Build Automationはそのためのオプションの1つです。

ビルトインレンダーパイプラインから URP
Web ゲームには、ビルトインレンダーパイプラインまたはユニバーサルレンダーパイプライン(URP)を使用できます。しかし、URP はコンテンツの効率的なカスタマイズと複数のハードウェアデバイスへのスケーリングを可能にするため、お勧めです。
eBook「Introduction to the Universal Render Pipeline for advanced Unity creators(上級Unityクリエイターのためのユニバーサルレンダーパイプライン入門)」で、プロジェクトをビルトインレンダーパイプラインからURPに移行する方法について詳しく説明します。

Unity Web ビルドを最適化するための 9 つのヒント
コンソールをターゲットにする場合、メモリ、CPU、GPU の使用状況を正確に把握できます。ウェブはまったく別のものです。ゲームを幅広いオーディエンスに楽しんでもらうためには、メモリが制限されている環境でも問題なく動作することを確認する必要があります。
ここでは、ローエンドのハードウェアでゲームをスムーズに動作させる方法について、eBook「Optimize your mobile game performance」からヒントをいくつか紹介します。
1.ゲームアセットの最適化
テクスチャやモデルなどのアセットをウェブ用に最適化する(例:圧縮されたテクスチャを使用し、必要に応じてモデルのポリゴン数を減らす)。決まったルールはありませんが、パフォーマンスの一貫性を確保するために、チーム内でいくつかの一般的なガイドラインについて合意します。
2.オブジェクトプーリングの使用
オブジェクトプールは、オブジェクトを新規作成して破棄するのではなく、再利用することでパフォーマンスを向上させる手法です。これは、スポーンやデスポーンが頻繁に行われるゲームに便利です。フライホイールのような他のプログラミングデザインパターンも役に立ちます。Unityプロジェクトでデザイン パターンを実装する方法についての高度なヒントについては、eBook「Level up your code with game programming patterns」を参照してください。
3.ユニバーサルレンダーパイプラインと SRP Batcher の使用
Unity の SRP Batcher バッチングシステムにより、シーンに応じて CPU レンダリングを高速化し、パフォーマンスを向上させます。シェーダーやテクスチャなどの共有マテリアルのプロパティに基づいてドローコールをグループ化することで、レンダリング中に必要な状態変更の数を減らすことができます。
4.オクルージョンカリングを使用する
Unity のオクルージョンカリングシステムは、プレイヤーに表示されるオブジェクトのみをレンダリングすることで、パフォーマンスの向上に役立ちます。オクルージョンカリングは、廊下でつながった部屋など、細かく定義された領域がしっかりとしたゲームオブジェクトで区切られているシーンで最適です。
5.組み込みの LOD(詳細レベル)システムを使用する
Unity の組み込みの LOD システムは、プレイヤーから離れたオブジェクトの複雑さを軽減することで、パフォーマンスを向上させます。カメラとオブジェクトの距離が長くなると、LOD システムはオブジェクトの高詳細バージョンを低詳細バージョンに自動的に切り替え、一貫した外観を維持しながらレンダリングのワークロードを軽減します。
6.可能な場合はライティングをベイクする
ライトマップとライトプローブを使用してシーンのライティング情報を事前計算することで、パフォーマンスを改善します。
7.不要な文字列の作成や操作を減らす
C# では、文字列は値型ではなく参照型です。JSON や XML などの文字列ベースのデータファイルの解析は避け、代わりに ScriptableObject や MessagePack や Protobuf などの形式でデータを保存します。また、永続的なゲームデータを保存する(ゲームを保存する)場合などは、バイナリ形式を検討することもできます。実行時に文字列を構築する必要がある場合は、StringBuilder クラスを使用します。
8.Addressable Asset System を使用する
Addressable Asset System は、アセットバンドルを「アドレス」またはエイリアスで読み込むことで、コンテンツを簡単に管理する方法を提供します。この統合システムは、ローカルパスまたはリモートコンテンツ配信ネットワーク(CDN)から非同期的にロードされます。
9.ポストプロセッシングエフェクトを制限
フルスクリーンのポストプロセッシングエフェクトはパフォーマンスを低下させる可能性があるため、ゲームでは控えめに使用してください。
ホスト HTML のカスタマイズ
Unity Web ビルドを作成すると、Unity はテンプレートを使用してゲームを表示する Web ページを生成します。
デフォルトのテンプレートは次のとおりです。
- デフォルト:グレーのキャンバスにローディングバーがある白いページ
- 最小:ゲームの運営に最低限必要なボイラープレート
- プログレッシブ Web アプリケーション(PWA):これには、ウェブマニフェストファイルとサービスワーカーが含まれます。適切なデスクトップブラウザーで、プレイヤーの起動可能なアプリケーションにゲームを追加するためのインストールボタンがアドレスバーに表示されます。
独自のカスタム HTML ページを作成する最も簡単な方法は、/PlaybackEngines/ WebGLSupport/ BuildTools/ WebGLTemplates/ にある 3 つのテンプレートのいずれかを使用することです。 Mac では、Applications フォルダー内の Unity Installation フォルダーにあります。
テンプレートをコピーして、独自の Project/Assets/WebGLTemplates フォルダに置き、後で識別できるように名前を変更します。ゲームコンテンツ、デプロイ先、ターゲットプラットフォームに合わせてカスタマイズできるようになりました。
プロジェクトの WebGLTemplates フォルダ内のテンプレートは、Edit> Project Settings…> Player> Resolution and Presentation パネルに表示されます。テンプレートの名前は、そのフォルダと同じです。このオプションを参照しやすいようにサムネイル画像を指定するには、テンプレートフォルダーに 128 x 128 ピクセルの画像を追加し、thumbnail.png という名前を付けます。
ビルドプロセス中、Unity はテンプレートファイルを前処理し、それらのファイルに含まれるすべてのマクロと条件付きディレクティブを評価します。すべてのマクロ宣言を検索してエディターが指定する値に置き換え、テンプレートフォルダー内のすべての .html、.php、.css、.js、.json ファイルを自動的に前処理します。
例えば、以下のコード行をご覧ください。
「Resolution and Presentation」パネルで「Default Canvas Width」が 960、「Default Canvas Height」が 600 に設定されている場合、前処理後のコードは次のようになります。
.
3 つの波かっこは、コンパイラーが指示された変数の値を検索することを示します。
また、#if、#else、#endif を使用した条件付きディレクティブのデフォルトテンプレートの例も見つかります。
#if EXPRESSION
//EXPRESSION が truey 値に評価された場合
#else
//EXPRESSION が truey 値に評価されない場合
#endif
カスタムテンプレートを使用する場合は、Unity Asset Store で多くのオプションを利用できます。
ゲームとコード共有サイト
ブラウザーベースのゲーム用のプラットフォームでゲームを共有する場合は、index.html ページを仕様に合わせて調整する必要があります。その方法については、ウェブゲーム用の一般的なプラットフォームのドキュメントを参照してください。
レスポンシブデザイン
レスポンシブデザインに対応するために、ゲームではブラウザーウィンドウのサイズを変更する必要があることが多く、そのためにはローディングコードを適応させる必要があります。これを実現するには、JavaScript で「Promise」を使用します。これは、まだ完了していないが、将来完了すると予想される操作を表します。
各テンプレートの index.html ページ (下のコード例を参照) で、 script.onload を探します。script.onload は、Unity のエンジンスクリプトの読み込みが完了したときにトリガーされるイベントです。その直前に、2 つのグローバル変数があります。myGameInstance は Unity インスタンスへの参照を保持し、myGameLoaded はゲームの読み込みが完了したかどうかを示し、デフォルトは false です。var として宣言されているため、グローバルスコープを持ち、スクリプト内のどこにでもアクセスできます。
createUnityInstance() 関数が呼び出され、Unity ゲームの新しいインスタンスが作成されます。この関数は、ゲームが完全に読み込まれ、レンダリングの準備ができたときに解決される Promise を返します (createUnityInstance Promise のその後のブロック)。
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';
}
}
JavaScript の追加と呼び出し
ブラウザーをターゲットにしている多くのゲームでは、ユーザーログインやハイスコアテーブルなどをサポートするためにウェブサービスを呼び出したり、ブラウザーの DOM とインタラクトしたりするために、JavaScript コードとインタラクトする必要があります。C# スクリプトから呼び出せるように直接追加する JavaScript は、拡張子が .jslib で、Assets/Plugins フォルダーに配置する必要があります。mergeInto メソッドでラップする必要があります。これには 2 つのパラメーターが必要です。LibraryManager.library と、1 つ以上の関数を含む JavaScript オブジェクトです。関数は標準の JavaScript です。GetExchangeRates は、ウェブサービスを提供するシンプルな JSON を使用する方法を以下で紹介します。
ビルドを作成すると、これらの関数は Build/.framework.js ファイルに追加されます。これらの関数は、次のコード例に示すように、C# スクリプトから DllImport として宣言することで呼び出すことができます。
public class SphereController :MonoBehaviour
{
[DllImport("__Internal")]
private static extern void GetExchangeRates();
private void Start()
{
GetExchangeRates();
}
}
詳細情報

SendMessage を使用する
C# が JavaScript 関数を呼び出す以外に、JavaScript は C# メソッドを呼び出すことができます。このメカニズムでは、メッセージングプロトコルを使用します。
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, 5)
myGameInstance.SendMessage(「MyGameObject」、「MyFunction」、「A string」)
SendMessage を使用するには、スコープ内のゲームインスタンスへの参照が必要です。通常のテクニックは、先ほど見た script.onload Promise の then ブロックでグローバル変数を追加して index.html を編集することです。この単純な関数は、Sphere という名前のゲームオブジェクトにアタッチされた MonoBehaviour コンポーネントの一部として追加されます。
public void SetHeight( float height )
{
Vector3 pos = transform.position;
pos.y = height;
transform.position = pos;
}
Chrome のコンソールを開くには、F12 キーを押し、次のように直接入力します。
myGameInstance.SendMessage('Sphere', 'SetHeight', 3)
Enter キーを押して、関数 Moving the Sphere を呼び出します。「Run In Background」を設定しているか、Application.runInBackground を true に設定している場合にのみ、その動きがレンダーに反映されます。これは、デフォルトではキャンバスウィンドウにフォーカスがある場合にのみレンダリングが行われるためです。
デバッグにブラウザーコンソールを使用する
ブラウザプラットフォーム用にデバッグする場合は、 Debug.Log を使用します。メッセージはブラウザーコンソールに送信されます。Chrome の場合は、F12 キーを押して「Console」タブに切り替えると表示されます。しかし、Debug クラスはより多くのオプションを提供します。Debug.LogError を使用すると、コンソールにスタックトレースが表示されます。
詳細情報
展開
開発中は Development Build オプションを使用することをお勧めしますが、ゲームをライブサイトにデプロイする場合はこのオプションをオフにしてください。リリースビルドでは、圧縮のオプションがあります。圧縮を使用する場合、サーバで設定の調整が必要になる場合があります。その方法については、マニュアルを参照してください。

プロファイリングの重要性
パフォーマンスの問題をすぐに発見できるように、開発サイクル全体を通してプロジェクトのプロファイリングを行うことが重要です。Unity プロファイラーは、ゲームのパフォーマンスのボトルネックを特定して修正するための優れたツールです。CPU とメモリの使用状況を追跡し、ゲームの最適化が必要な領域を特定するのに役立ちます。Profile Analyzer、Memory Profiler、および Web Diagnostics Overlay を併用することもできます。
eBook『Ultimate guide to profiling Unity games』をダウンロードして、Unityでのプロファイリングについて詳しく学びましょう。
Unity Web ビルドのプロファイリングを始めるためのヒントをいくつか見てみましょう。
Unity のプロファイラーを有効にする
エディターで「File」>「Build Settings」に移動し、「Development Build」および「Autoconnect Profiler」を選択して Web ビルドでプロファイラーを使用します。
CPU Usage モジュールの選択
このモジュールを使用して、コードのパフォーマンスを分析し、パフォーマンスの問題を引き起こしている領域を特定します。関数呼び出し、スクリプト実行、ガベージコレクションなどの要素を分析します。
Memory Profiler モジュールを選択する
Unity Web ビルドは、他のプラットフォームと比較してメモリリソースが限られています。このモジュールを使用して、アプリケーションのメモリ使用量を分析し、最適化が必要な領域を特定します。
Chrome DevTools Performance パネルを使用する
Chromeデベロッパーツールには、ゲームのボトルネックをドリルダウンするのに役立つパフォーマンスパネルが含まれています。特に、JavaScript ファイルにブレークポイントを追加するための Sources パネルと、デバッグメッセージを表示し、JavaScript コードを入力するための Console パネルを備えています。
さまざまなデバイスでパフォーマンスを測定する
これにより、特定のデバイスやブラウザー固有のパフォーマンスの問題を特定し、それに応じてゲームを最適化することができます。
ドローコールの数を減らす
ドローコールは、Unity Web ビルドの主なパフォーマンスボトルネックの 1 つです。Unity プロファイラーを使用してドローコールの数が多い領域を特定し、削減を試みます。
ローエンドデバイスのパフォーマンスを分析
ローエンドデバイスでテストを行い、アプリケーションが幅広いハードウェア向けに最適化されていることを確認します。
プロファイリング中に「Run In Background」を有効にする
WebGL Player Settings で Run In Background が有効になっている場合、または Application.runInBackground が有効になっている場合は、キャンバスまたはブラウザウィンドウがフォーカスを失ってもコンテンツが実行し続けるので、プロファイリング時に便利です。
その他の Unity Web リソース
Unity Web ビルドは、ゲームを幅広いユーザーに配信するのに最適な方法です。開発中は、ジオメトリとテクスチャを適度なサイズに抑え、描画コールを減らし、幅広いデバイスでプロファイリングとテストを行うべきです。最後に、URP を使用して、幅広いハードウェアで安定したパフォーマンスを確保します。
詳細情報
Unity の WebGL モジュールを使用するためのヒントとコツ
Unity 2023.3 の新しい WebGPU バックエンドへの早期アクセス
公式の Web ランタイムアップデートはこちら:ブラウザーを次のレベルに引き上げる
Unity ベストプラクティスハブでは、Unity のすべての上級者向け e ブックと記事が見つかります。