コンテンツ更新ビルド
Addressables パッケージには、リモート配信するコンテンツの更新のサイズを小さくするために使用できるツールが付属しています。
コンテンツ更新ツールには以下のものがあります。
- Check for Content Update Restrictions (コンテンツ更新の制限の確認) ツール: グループ設定に基づいて、コンテンツ更新ビルド用にグループを編成する準備を行います。
- Update a Previous Build (以前のビルドの更新) スクリプト: コンテンツ更新ビルドを実行するビルドスクリプトです。
Important
将来更新する予定のあるビルドごとに、デフォルトビルドスクリプトによって作成される addressables_content_state.bin ファイルを保存しておく必要があります。このファイルは、ビルドスクリプトを実行するたびに更新されます。必ず、公開するコンテンツビルド用に作成されたバージョンを保存してください。以前のコンテンツ状態ファイルの使用方法の扱いに関連する Addressable 設定については、[設定] を参照してください。
コンテンツ更新のための Addressable (アドレス指定可能) グループの設定の詳細については、[グループ設定] を参照してください。
コンテンツ更新ビルドの実行方法の詳細については、[コンテンツ更新ビルド] を参照してください。
コンテンツ更新のしくみに関する一般的な情報と例については、[概要] を参照してください。
Note
独自のパッチシステムを提供するプラットフォーム (Switch や Steam など) や、コンテンツのリモート配布をサポートしていないプラットフォームでは、コンテンツ更新ビルドを使用しないでください。このようなゲームの各ビルドは、完全な新規コンテンツビルドにする必要があります (この場合、プラットフォーム用の各ビルドの後に生成される addressables_content_state.bin ファイルは、破棄または無視することができます)。
概要
コンテンツをリモートで配布する場合は、アプリケーション全体の再ビルドと再公開を行わなくても、コンテンツに変更を加えることができます。Addressables システムがランタイム時に初期化されるとき、更新されたコンテンツカタログがあるかどうかが確認されます。該当するカタログがある場合は、新しいカタログがダウンロードされ、アセットのロード時に、すべての AssetBundle の新しいバージョンがダウンロードされます。
ただし、新しいコンテンツカタログを使用してすべてのコンテンツを再ビルドした場合は、インストール済みのプレイヤーでも、そのプレイヤー内のアセットが変更されたどうかにかかわらず、すべてのリモート AssetBundle の再ダウンロードが必要になります。コンテンツが大量な場合、すべてを再ダウンロードするにはかなりの時間がかかる可能性があり、プレイヤーリテンション率の低下につながるおそれがあります。このプロセスの効率を高めるために、Addressables パッケージには、変更されたアセットを特定し、コンテンツ更新ビルドを作成するために使用できるツールが用意されています。
以下の図は、Addressables のツールを使用して、より小さいサイズのコンテンツ更新を作成する方法を示しています。この更新では、プレイヤーがダウンロードする必要があるのは、新規コンテンツまたは変更されたコンテンツのみとなります。
コンテンツ更新のサイズを小さくするためのワークフロー
フルアプリケーションをリリースするときは、最初に通常どおりに Addressables コンテンツをビルドしてから、プレイヤービルドを作成します。プレイヤービルドにはローカル AssetBundle が含まれます。リモート AssetBundle は、コンテンツデリバリネットワーク (CDN) またはその他のホスティングサービスにアップロードします。
Addressables コンテンツビルドを作成するデフォルトビルドスクリプトでは、addressables_content_state.bin ファイルが常に作成されます。これは、コンテンツのみの更新を効率的に公開するために必要となるファイルです。このファイルを、(各プラットフォームの) 公開されるフルアプリケーションリリースごとに保存する必要があります。
フルアプリケーションリリースでは、ユーザーが新しいプレイヤービルドをダウンロードしてインストールする必要がありますが、このようなリリースの合間に、プロジェクト内の Addressable アセットに変更を加えることができます (AssetBundle にはコードが含まれないため、アセット変更の開発に使用するプロジェクトバージョンでは、コードに変更を加えないでください)。ローカルとリモートの両方のアセットを変更できます。
コンテンツ更新を公開する準備ができたら、Check Content Update Restrictions ツールを手動で実行するか、更新ビルドプロセスの一環として確認が必ず実行されるようにすることをお勧めします。詳細については、[設定] に関するセクションを参照してください。この確認により、addressables_content_state.bin ファイルが調べられ、変更されたアセットが、その所属グループの設定に従って新しいリモートグループに移動されます。
更新された AssetBundle をビルドするには、Update a Previous Build スクリプトを実行します。このツールでも addressables_content_state.bin ファイルが使用されます。これにより、すべてのコンテンツが再ビルドされますが、作成されるカタログが変わります。このカタログは、変更されていないコンテンツには元の AssetBundle からアクセスし、変更されたコンテンツには新しい AssetBundle からアクセスします。
最後のステップは、更新したコンテンツを CDN にアップロードすることです (新しく作成されたすべての AssetBundle をアップロードすることも、名前が変更されたものだけをアップロードすることもできます。変更されていないバンドルには元のバンドルと同じ名前が使用され、それによって元のバンドルが上書きされます)。
同じプロセスに従って、追加のコンテンツ更新を作成できます。常に、元のリリースから作成された addressables_content_state.bin ファイルを使用してください。
具体的な手順については、[コンテンツ更新ビルド] を参照してください。
再フルビルドが必要な場合
Addressables で配布できるのは、コードではなく、コンテンツだけです。コードの変更には、一般に新規プレイヤービルドが必要であり、通常はコンテンツも新しくビルドする必要があります。CDN にある既存の古いコンテンツを新規プレイヤービルドで再び使用することはできますが、既存の AssetBundle 内のタイプツリーに新規コードとの互換性があるかどうかを慎重に分析する必要があります。これは上級者向けの方法で、慎重な調査が求められます。
Addressables 自体はコードであるため、Addressables や Unity のバージョンを更新するには、新規プレイヤービルドと新規コンテンツビルドの作成が必要になる可能性があります。
設定
コンテンツ更新を公開するには、アプリケーションで既にリモートカタログが使用されていて、アクセス可能なサーバーでリモートコンテンツがホストされている必要があります。コンテンツのホスティングと配布の設定の詳細については、[リモート配布の有効化] を参照してください。
コンテンツのリモート配布の有効化に加えて、各グループの Update Restriction (更新の制限) 設定をどのように指定するかを検討する必要もあります。この設定により、グループ内の変更されたコンテンツが Check for Content Update Restrictions ツールでどのように処理されるかが決まります。適切な設定を選択して、コンテンツ更新のダウンロードサイズが最小になるようにしてください。[グループの Update Restriction 設定] を参照してください。
Addressable アセット設定には、以前のビルドを更新するためのセクションも含まれています。
ここには 2 つの設定があり、その 1 つである Check For Update Issues (更新の問題の確認) は、Check For Content Update Restrictions の確認を自動的に実行するかどうかと、検出された問題の処理方法をシステムに知らせます。もう 1 つは Content State Build Path (コンテンツ状態のビルドパス) です。この場所は、以下の 2 つの目的で使用されます。
- 新しいコンテンツビルドでは、以前の状態ファイルを配置する場所を示します。
- Update a Previous Build では、自動的にこの場所から以前の状態ファイルの取得が試みられます。
以前の状態ファイルをサーバー上で共有する場合は、Content State Build Path にリモートの場所を指定できます。以前の状態ファイルがリモートの場所にある場合は、システムの処理が少し変わります。
- 新しいコンテンツビルドでは、以前の状態ファイルが
ContentUpdateScript.PreviousContentStateFileCachePath
に配置されます。これは、デフォルトではLibrary/com.unity.addressables/AddressablesBinFileDownload/
です。 - Update a Previous Build では、リモートの以前の状態ファイルが
ContentUpdateScript.PreviousContentStateFileCachePath
にダウンロードされてから、通常どおりに読み取られます。このファイルがリモートの場所になくても、既にキャッシュパスに配置されている場合は、ローカルファイルがロードされます。
コンテンツを動的に (アプリケーションの起動時ではなく) 更新する場合に考慮するべきもう 1 つの設定として、Unique Bundle IDs (一意のバンドル ID) 設定があります。このオプションを有効にすると、アプリケーションセッションの最中に、更新された AssetBundle を簡単にロードできるようになりますが、通常はビルドにかかる時間が長くなり、更新のサイズも増大します。[Unique Bundle IDs 設定] を参照してください。
Group の Update Restriction 設定
Group とそのアセットがコンテンツの更新時にどのように処理されるかは、プロジェクト内のグループごとに、Update Restriction (更新の制限) スキーマによって決定されます。以下の設定があります。
- Prevent Updates (更新の禁止): オンにすると、そのグループ内のアセットは静的コンテンツとして扱われ、更新が発生するとしても頻度は低いと見なされます。すべてのローカルコンテンツでは、この設定を使用する必要があります。
グループ内のコンテンツのタイプと、そのコンテンツで想定される更新 (アプリケーションのフルプレイヤービルドの合間に発生する更新) の頻度に基づいて設定を選択してください。
グループ内のコンテンツは、どちらの設定を選択したかにかかわらず変更が可能です。相違点は、Check for Content Update Restrictions ツールと Update Previous Build ツールでグループ内のアセットが処理される方法と、最終的に、インストール済みのアプリケーションから更新されたコンテンツにアクセスする方法にあります。
Important
フルビルドを実行している場合以外は、グループの Update Restriction 設定を変更しないでください。コンテンツ更新の前にグループ設定を変更すると、更新ビルドに必要な変更を Addressables で正しく生成できなくなります。
Prevent Updates の有効化 (静的コンテンツ)
Prevent Updates を有効にすると、Check for Content Update Restrictions ツールは、変更されたすべてのアセットを新しいグループに移動します。このグループは、リモートパスからビルドとロードを行うように設定されます。この動作は、Updating a Previous Build に自動的に統合できる確認プロセスと同じです。手動でツールを実行するか、Update a Previous Build による自動確認に任せるかにかかわらず、その後のコンテンツ更新では、変更されたアセットには新しいバンドルからアクセスし、変更されていないアセットには元のバンドルからアクセスするようにリモートカタログが設定されます。
Note
更新ビルドでは、変更されたアセットを含まない元のバンドルのバージョンが作成されますが、インストール済みのアプリケーションでは、ローカルにキャッシュされたバージョンが何らかの理由で削除されていない限り、このバージョンがダウンロードされることはありません。
更新の頻度が低いと想定されるコンテンツは、Prevent Updates を有効にしたグループにまとめます。通常、このようなグループのバンドルをユーザーが何度もダウンロードする必要は生じないため、これらのグループは、サイズの大きいバンドルを少ない頻度で作成するように設定できます。
ローカルロードパスからロードするためのグループはすべて、常に Prevent Updates に設定する必要があります。同様に、サイズの大きいリモートバンドルを作成するグループも、すべて Prevent Updates に設定します。これにより、それらのグループ内のアセットが変更された場合に、ユーザーは変更されたアセットだけをダウンロードすれば済むようになります。
Prevent Updates の無効化 (動的コンテンツ)
グループに Prevent Updates が設定されていない場合は、グループ内のいずれかのアセットが変更されると、コンテンツ更新によってバンドル全体が再ビルドされます。Update a Previous Build スクリプトは、インストール済みのアプリケーションでグループ内のすべてのアセットが新しいバンドルからロードされるように、カタログを設定します。
頻繁な変更が想定されるコンテンツは、Prevent Updates を無効にしたグループにまとめます。これらのグループでは、いずれかのアセットが変更されるとすべてのアセットが再公開されるため、通常は、少数のアセットを含む小さいサイズのバンドルを作成するようにグループを設定する必要があります。
Unique Bundle IDs 設定
[Addressable アセット設定] には、コンテンツ更新ビルドに影響するオプションである Unique Bundle IDs が含まれています。アプリケーションカタログをランタイム時に更新するときに AssetBundle ID の競合が発生する場合は、このオプションを有効にする必要があるかどうかを検討できます。
Unique Bundle IDs オプションを有効にすると、元のバンドルをメモリ内に保持しながら、変更されたバージョンの AssetBundle をロードできます。一意の内部 ID を持つ AssetBundle をビルドすることで、AssetBundle ID の競合を引き起こさずにランタイム時にコンテンツを更新することが簡単になります。
ただし、このオプションには欠点もあります。有効にすると、変更されたアセットを参照するアセットが含まれている AssetBundle も、すべて再ビルドが必要になります。コンテンツ更新のために更新する必要のあるバンドルが増え、ビルドにかかる時間が長くなります。
通常、一意のバンドル ID を使用する必要があるのは、Addressables システムが既に初期化され、アセットのロードを開始した後にコンテンツカタログを更新する場合だけです。
以下の方法のいずれかを使用すると、AssetBundle のロードの競合を回避でき、一意の ID を有効にする必要がなくなります。
- Addressables の初期化の一部としてコンテンツカタログを更新する。デフォルトで、Addressables は初期化時に新しいカタログを確認します (ただし、Addressable アセット設定で Only update catalogs manually オプションを有効にしている場合は除きます)。この方法を選択すると、セッションの途中でアプリケーションコンテンツを更新することはできなくなります。
- コンテンツカタログを更新する前にすべてのリモート AssetBundle をアンロードする。リモートのバンドルおよびアセットをすべてアンロードすることでも、バンドル名の競合を回避できます。ただし、新しいコンテンツがロードされるまで待つ間、ユーザーのセッションが中断される可能性があります。
更新コンテンツのビルド
コンテンツ更新をビルドするには、以下の手順で Update a Previous Build スクリプトを実行します。
- Update a Previous Build で自動的に確認を実行しない場合は、Check for Content Update Restrictions ツールを実行することをお勧めします。
- Unity エディターで Addressables Groups (Addressables グループ) ウィンドウを開きます (Window > Asset Management > Addressables > Groups)。
- ツールバーの Build (ビルド) メニューから Update a Previous Build スクリプトを実行します。
ビルドによって、コンテンツカタログ、ハッシュファイル、AssetBundle が生成されます。
生成されるコンテンツカタログには、元のアプリケーションビルドのカタログと同じ名前が使用され、古いカタログとハッシュファイルは上書きされます。アプリケーションは、ランタイム時にハッシュファイルをロードして、新しいカタログが使用可能かどうかを判別します。変更されていないアセットは、アプリケーションに同梱されていた既存のバンドル、またはアプリケーションが既にダウンロードした既存のバンドルからロードされます。
システムは、addressables_content_state.bin ファイルのコンテンツバージョン文字列と場所情報を使用して AssetBundle を作成します。更新されたコンテンツを含まない AssetBundle は、更新用に選択されたビルドのファイル名と同じ名前を使用して書き込まれます。更新されたコンテンツが AssetBundle に含まれている場合は、その更新されたコンテンツを含む新しいバンドルが新しいファイル名で生成されます。これは、コンテンツホスティングサービス上で新しいバンドルと元のバンドルが共存できるようにするためです。コンテンツをホストしている場所には、新しいファイル名の AssetBundle のみをコピーする必要があります (ただし、すべてをアップロードしても問題はありません)。
ローカル AssetBundle など、変更できないコンテンツの AssetBundle もシステムによってビルドされますが、それらは Addressables アセットエントリーから参照されないため、コンテンツをホストしている場所にアップロードする必要はありません。
新規プレイヤーをビルドしてからコンテンツ更新を作成するまでの間には、ビルドスクリプトを変更しないようにしてください (プレイヤーコード、Addressables など)。変更すると、アプリケーションで想定外の動作が発生する場合があります。
また、Addressables ビルドで作成されたローカルコンテンツバンドルを Project Library フォルダーから削除すると、ゲームまたはアプリケーションをエディターで実行して Use Existing Build (requires built groups) (既存のビルドの使用 (ビルド済みグループが必要)) 再生モードスクリプトを使用するときに、それらのバンドル内のアセットをロードできなくなります。
Check for Content Update Restrictions ツール
Check for Content Update Restrictions ツールは、コンテンツ更新ビルド用にグループを編成する準備を行います。このツールでは、addressables_content_state.bin ファイルとグループ設定が調べられます。以前のビルドでグループの Update Restrictions オプションが Prevent Updates に設定されていた場合は、ツールによって、変更されたアセットを新しいリモートグループに移動するオプションが提示されます。特に理由がない限り、提案された変更を適用するか、これらのアセットへの変更を取り消すことをお勧めします。更新ビルドを作成すると、新しいカタログでは、変更されたアセットが新しいリモート AssetBundle にマップされ、変更されていないアセットは元の AssetBundle にマップされたままになります。Check for Content Update Restrictions では、Prevent Updates が無効になっているグループは確認されません。
このツールを実行する手順は以下のとおりです。
- Unity エディターで Addressables Groups ウィンドウを開きます (Window > Asset Management > Addressables > Groups)。
- グループウィンドウで、ツールバーの Tools メニューから Check for Content Update Restrictions を実行します。
- 必要に応じて、ツールによって加えられたグループの変更を確認します。ツールで作成された新しいリモートグループの名前は変更できますが、アセットを別のグループに移動すると、想定外の結果となる可能性があります。
重要: Check for Content Update Restrictions ツールを実行する前に、バージョン管理システムでブランチを作成する必要があります。このツールでは、コンテンツの更新に適した方法でアセットグループが再編成されます。ブランチを作成すると、次回のフルプレイヤービルドの出荷時に、自分の希望するコンテンツ配置に戻ることができます。
ランタイム時のコンテンツ更新の確認
カスタムスクリプトを加えて、新しい Addressables コンテンツ更新があるかどうかを定期的に確認することができます。更新を開始するには、以下の関数呼び出しを使用します。
ここで、List<string> には、変更されたロケーター ID のリストが含まれます。このリストをフィルタリングして特定の ID のみを更新することも、リスト全体を UpdateCatalogs API に渡すこともできます。
新しいコンテンツがある場合は、更新を実行するボタンをユーザーに表示するか、自動的に更新を実行することができます。古いアセットを確実に解放するのは開発者の責任です。
カタログのリストは null である可能性があり、その場合は以下のスクリプトによって、更新が必要なカタログがすべて更新されます。
戻り値は、更新されたロケーターのリストです。
カタログを更新した結果、参照されなくなったバンドルキャッシュエントリーの削除が必要になる場合があります。この場合は、代わりに UpdateCatalogs API の以下のバージョンを使用します。ここで、追加パラメーター autoCleanBundleCache
を使用すると、不要なキャッシュデータを削除できます。
バンドルキャッシュの詳細については、[AssetBundle のキャッシング] を参照してください。
ランタイム時のコンテンツの更新の詳細については、[Unique Bundle IDs 設定] を参照してください。
コンテンツ更新の例
以下の解説では、架空の例を使用して、コンテンツ更新時に Addressable コンテンツがどのように処理されるかをわかりやすく説明しています。この例では、出荷されたアプリケーションが、以下の Addressables グループでビルドされているとします。
Local_Static | Remote_Static | Remote_NonStatic |
---|---|---|
AssetA | AssetL | AssetX |
AssetB | AssetM | AssetY |
AssetC | AssetN | AssetZ |
Local_Static と Remote_Static は Cannot Change Post Release グループに含まれています。
このバージョンはライブであるため、既存のプレイヤーのデバイスには Local_Static が存在します。また、リモートバンドルのいずれかまたは両方がローカルにキャッシュされている可能性もあります。
各グループからアセットの 1 つ (AssetA、AssetL、AssetX) を変更した後、Check for Content Update Restrictions を実行すると、ローカルの Addressable 設定は以下のような結果となります。
Local_Static | Remote_Static | Remote_NonStatic | content_update_group (非静的) |
---|---|---|---|
AssetX | AssetA | ||
AssetB | AssetM | AssetY | AssetL |
AssetC | AssetN | AssetZ |
実際には準備操作によって Cannot Change Post Release グループが編集され、直観的ではないように見える可能性があります。重要なのは、システムによって上記のレイアウトがビルドされますが、このようなグループのビルド結果は破棄されるという点です。したがって、プレイヤーの観点からは以下のような結果となります。
Local_Static |
---|
AssetA |
AssetB |
AssetC |
Local_Static バンドルは既にプレイヤーデバイス上にあり、開発者は変更できません。この古いバージョンの AssetA は参照されなくなります。これは、無用のデータとしてプレイヤーデバイスに残されます。
Remote_Static |
---|
AssetL |
AssetM |
AssetN |
Remote_Static バンドルは変更されていません。プレイヤーのデバイスにまだキャッシュされていない場合は、AssetM または AssetN がリクエストされたときにダウンロードされます。AssetA と同様に、この古いバージョンの AssetL は参照されなくなります。
Remote_NonStatic (古い) |
---|
AssetX |
AssetY |
AssetZ |
Remote_NonStatic バンドルは古くなりました。サーバーから削除することも、そのままにしておくこともできますが、どちらの場合も、この時点以降はダウンロードされません。キャッシュされている場合は、削除しない限りずっとプレイヤーデバイスに残ります。詳細については、[AssetBundle のキャッシング] を参照してください。AssetA や AssetL と同様に、この古いバージョンの AssetX は参照されなくなります。
Remote_NonStatic (新しい) |
---|
AssetX |
AssetY |
AssetZ |
古い Remote_NonStatic バンドルは、新しいバージョンに置き換えられます。これは、ハッシュファイルで見分けることができます。変更されたバージョンの AssetX は、このバンドルを使用して更新されます。
content_update_group |
---|
AssetA |
AssetL |
content_update_group バンドルは、これ以降に参照される、変更されたアセットで構成されています。
上の例には、以下のような意味があることに注意してください。
- 変更されたローカルアセットは、ユーザーのデバイスで使用されないまま、いつまでも残ります。
- 静的でないバンドルが既にキャッシュされている場合、ユーザーは、変更されていないアセット (この例では AssetY と AssetZ) を含めて、そのバンドルを再ダウンロードする必要があります。理想的には、ユーザーがまだバンドルをキャッシュしていなければ、新しい Remote_NonStatic バンドルをダウンロードするだけで済みます。
- Static_Remote バンドルが既にキャッシュされている場合、ユーザーは、更新されたアセット (この例では content_update_group の AssetL) をダウンロードする必要があるだけです。この場合はこれが理想的な状況です。バンドルがキャッシュされていない場合は、content_update_group の新しい AssetL と、変更されていない Remote_Static バンドルの古くなった AssetL の両方をダウンロードする必要があります。最初のキャッシュ状態に関係なく、いずれかの時点で、ユーザーのデバイスには古くなった AssetL が配置され、使用されることがなくても無期限にキャッシュされます。
リモートコンテンツにとって最適な設定は、それぞれのユースケースによって異なります。
コンテンツ更新での依存関係の処理方法
コンテンツ更新の一部としてアセットの再ビルドが必要であることを示すフラグを付ける方法は、そのアセットを直接変更することだけではありません。更新のビルド時にはあまり考慮されない要素ですが、アセットの依存関係を変更する方法があります。
例として、上の例の Local_Static グループで説明します。
Local_Static |
---|
AssetA |
AssetB |
AssetC |
ここでは、このグループの各アセットに依存関係チェーンがあるとします。AssetA は Dependency1 に依存し、Dependency1 は Dependency2 に依存します。AssetB は Dependency2 に依存します。AssetC は Dependency3 に依存します。これらの 3 つの依存関係のすべてに、Addressable アセットと Addressable でないアセットが混在しています。
ここで、Dependency1 のみを変更し、Check For Content Update Restrictions を実行した場合、その結果は以下のようなプロジェクト構造になります。
Local_Static | content_update_group |
---|---|
AssetA | |
AssetB | |
AssetC |
Dependency2 のみを変更した場合は、以下のようになります。
Local_Static | content_update_group |
---|---|
AssetA | |
AssetB | |
AssetC |
最後に、Dependency3 のみを変更した場合は、以下のようになります。
Local_Static | content_update_group |
---|---|
AssetA | |
AssetB | |
AssetC |
これは、依存関係が変更されると、依存関係ツリー全体の再ビルドが必要になるためです。
別の依存関係ツリーの例を見てみましょう。AssetA は AssetB に依存し、AssetB は Dependency2 に依存し、AssetC は Dependency3 に依存します。この場合、Dependency2 を変更すると、以下のようなプロジェクト構造になります。
Local_Static | content_update_group |
---|---|
AssetA | |
AssetB | |
AssetC |
これは、AssetA が AssetB に、AssetB が Dependency2 に依存するためです。チェーン全体の再ビルドが必要であるため、AssetA と AssetB の両方が content_update_group に入れられます。