注意: AssetBundle Manager は Unityバージョン 2018.2 以降では非推奨です。Asset Store からは利用できなくなりましたが、AssetBundleDemo Bitbucket リポジトリ からダウンロードすることは可能です。Unity バージョン 2018.2 以降を使用する場合は、Addressable アセット のドキュメントを参照してください。
AssetBundle Manager は、アセットバンドルの使用をもっと効率化するために Unity によって作られたツールです。
AssetBundle Manager パッケージをダウンロードしてインポートすると、アセットバンドルをロードし使用するために新しい API の呼び出しが追加されます。また、それだけでなく、ワークフローをストリームライン化するためのエディター機能が追加されます。この機能は、 Assets メニューオプションに表示されます。
この新しい AssetBundles 項目には以下のオプションが含まれています。
Simulation Mode を有効にすると、AssetBundle Manager はアセットバンドルを処理できますが、実際にバンドル自体をビルドする必要はありません。エディターは、実際にアセットバンドルからアセットを引き出すのではなく、アセットバンドルに割り当てられたアセットを見て、アセットを直接使用します。
Simulation Mode を使用する主な利点は、毎回アセットバンドルを再ビルドして実装する必要なしに、アセットを修正し、更新し、加えることができるということです。
なお、アセットバンドルバリアントは Simulation Mode では機能しないので注意してください。バリアントを使う必要がある場合は、Local AssetBundle Server オプションの使用が必要です。
AssetBundle Manager は、エディター、または、ローカルのビルド (モバイルを含む) でアセットバンドルをテストするのに使用する Local AssetBundle Server を開始することもできます。
Local AssetBundle Server を動作させるための条件は、プロジェクトのルートディレクトリ (Assets フォルダーと同じ階層) に AssetBundles というフォルダーを作成する必要があることです。以下の図はその例です。
AssetBundles フォルダーを作ったら、このフォルダーにアセットバンドルをビルドします。そうするには、新しいメニューオプションから Build AssetBundles を選択します。これで、そのディレクトリにビルドされます。
さて、アセットバンドルをビルドし (または、Simulation Mode を使うことにし) 、アセットバンドルのロードを開始する準備ができました。新しく使用できるようになった API の呼び出しを AssetBundle Manager で見てみましょう。
この機能は AssetBundleManifest オブジェクトをロードします。AssetBundle Manager でアセットのロードを開始する前に、これを呼び出す必要があります。とても簡略化した例にすると、AssetBundle Manager の初期化は以下のようになります。
IEnumerator Start()
{
yield return StartCoroutine(Initialize());
}
IEnumerator Initialize()
{
var request = AssetBundleManager.Initialize();
if (request != null)
yield return StartCoroutine(request);
}
AssetBundle Manager は、Initialize() の間にロードするこのマニフェストを使用して、シーンにある依存関係の管理を含むさまざまな機能をサポートします。
AssetBundle Manager を使い、初期化も終わりました。これで、アセットをロードする準備ができました。 それでは、アセットバンドルをロードし、そのバンドルからオブジェクトをインスタンス化する方法を見てみましょう。
IEnumerator InstantiateGameObjectAsync (string assetBundleName, string assetName)
{
// アセットを assetBundle からロード
AssetBundleLoadAssetOperation request
= AssetBundleManager.LoadAssetAsync(assetBundleName, assetName, typeof(GameObject) );
if (request == null)
yield break;
yield return StartCoroutine(request);
// アセットを取得
GameObject prefab = request.GetAsset<GameObject> ();
if (prefab != null)
GameObject.Instantiate(prefab);
}
AssetBundle Manager はすべてのロード操作を非同期的に実行するので、yield return StartCoroutine(request); を呼び出す時にバンドルをロードするロード操作のリクエストを返します。そこから必要なのは、GetAsset<T>() を呼び出してアセットバンドルからゲームオブジェクトをロードするだけです。
シーンにアセットバンドルの名前を割り当て、そのシーンをロードする必要がある場合は、わずかに違うコードパスを使う必要があります。パターンは比較的似ていますが、わずかな違いがあります。 アセットバンドルからシーンをロードする方法は次のとおりです。
IEnumerator InitializeLevelAsync (string levelName, bool isAdditive)
{
// assetBundle からレベルをロード
AssetBundleLoadOperation request
= AssetBundleManager.LoadLevelAsync(sceneAssetBundle, levelName, isAdditive);
if (request == null)
yield break;
yield return StartCoroutine(request);
}
ご覧のように、シーンのロードもまた非同期であり、LoadLevelAsync は、シーンをロードするために StartCoroutine に渡す必要があるロード操作のリクエストを返します。
AssetBundle Manager を使用してバリアントをロードしても、実際には、シーンやアセットでロードする必要があるコードは変更されません。必要なのは、AssetBundleManager の ActiveVariants プロパティーを設定することです。
ActiveVariants プロパティーは、文字列の配列です。単に、アセットに割り当てるときに作成したバリアントの名前を含む文字列の配列を作成するだけです。シーンのアセットバンドルを高解像度バリアントでロードする方法は以下のとおりです。
IEnumerator InitializeLevelAsync (string levelName, bool isAdditive, string[] variants)
{
//activeVariants を設定
AssetBundleManager.ActiveVariants = variants;
// assetBundle からレベルをロード
AssetBundleLoadOperation request
= AssetBundleManager.LoadLevelAsync(variantSceneAssetBundle, levelName, isAdditive);
if (request == null)
yield break;
yield return StartCoroutine(request);
}
バリアントを渡す文字列の配列は、コード内で任意に設定できます (例えば、ボタンのクリックやその他の方法で)。配列を作成することにより、可能な場合は、設定されている有効なバリアントと一致するバンドルをロードします。