Addressables.DownloadDependenciesAsync() によるダウンロードを、アセットバンドルごとに分けて行う

はじめに

Addressables のダウンロードを行う場合、普通にコードを書くと以下のようになります。

// ※ラベル名を指定してダウンロードする場合

// Addressable アセットのラベル名
string labelName = "LABEL_NAME";

// 指定したラベルを持つすべての Addressable アセットの IResourceLocation を取得する
IList<IResourceLocation> locations = await Addressables.LoadResourceLocationsAsync(labelName);

// 取得した IResourceLocation が含まれるアセットバンドルをすべてダウンロードする
await Addressables.DownloadDependenciesAsync(locations);

この場合、ダウンロードするアセットバンドルが複数あっても一度にダウンロードを行うため、以下のような問題が起こります。

  • 現在ダウンロード中のアセットバンドルの情報が取得できない。
    • 例えば、「全体のうち何 % のダウンロードが完了したか」は取得できるが、「今ダウンロードしているアセットバンドルのうち何 % のダウンロードが完了したか」は分からない。
  • サーバーの設定によっては、ダウンロードに時間がかかりすぎるとサーバー側から通信を打ち切られる場合がある。

アセットバンドルごとにダウンロードする

こうした問題を防ぐため、各アセットバンドルごとに別々にダウンロードを行うようにします。

これは、以下のようなコードで実現できます。

// Addressable アセットのラベル名
string labelName = "LABEL_NAME";

// 指定したラベルを持つすべての Addressable アセットの IResourceLocation を取得する
IList<IResourceLocation> locations = await Addressables.LoadResourceLocationsAsync(labelName);

// DependencyHashCode でグルーピングする
foreach (IGrouping<int, IResourceLocation> groupedLocations in locations.GroupBy(x => x.DependencyHashCode))
{
    // グループごとに IResourceLocation のダウンロードを行う
    await Addressables.DownloadDependenciesAsync(groupedLocations.ToList());
}

解説

IResourceLocation は、 DependencyHashCode というパラメータを持ちます。

これは他の IResourceLocation との依存関係を示すハッシュコードなのですが、依存関係が同じ=所属しているアセットバンドルが同じなので、この値をもとにグループ分けすれば、アセットバンドルごとに IResourceLocation を分けることができます。

あとは、分けたグループごとに Addressables.DownloadDependenciesAsync() を実行してやれば OK です。

補遺

これを応用すると、以下のようなダウンロード画面を実装できます。

f:id:Gigacee:20211228195551g:plain
プログレスバー 2 本のダウンロード画面。上:全体の進行度、下:アセットバンドルごとの進行度

The coloring of this site is Dracula PRO🧛🏻‍♂️
This website uses the FontAwesome icons licensed under CC BY 4.0.

2020 GIGA CREATION