AssetBundle関連を使用する上で便利な上位層APIとして、AssetBundle ManagerがAssetStoreで公開されています。これが思ってたより便利だったので、改めて紹介します。
AssetBundleを簡単に使う為のAsset Bundle Manager
AssetBundle Managerは、AssetBundleを使用するAPIをラッピングして使いやすくまとめたアセットです。例えば、以下のような機能が備わっています。
- AssetBundleを構築する
- ローカルサーバーを構築し、そこからAssetBundleをダウンロードするモード
- AssetBundleを構築することなく、AssetBundleの読込動作をエミュレートする
- 同一のAssetBundleを二重にロードした際も正しいAssetBundleを返す
- AssetBundleの依存関係を自動的に解決する
AssetBundleを構築する
AssetBundle ManagerにはAssetBundleを構築する機能があります。
Assets>AssetBundles>Build AssetBundlesを選択 すると、現在のプラットフォームでAssetBundleが構築されます。
構築したAssetBundleはAssetsと同じフォルダに作成されるAssetBundlesフォルダ以下にプラットフォーム毎に格納されます。
ローカルサーバーを構築してAssetBundleを配置する
AssetBundleを「ダウンロードして」云々の工程を行いたい場合、ローカルサーバーを立てるのが望ましいです。この微妙に面倒な工程をAssetBundle Managerはボタン一発で行ってくれます。
Assets>AssetBundles>Local AssetBundle Serverにチェックを入れると、自動的にサーバーが起動し、AssetBundleのファイル群を配置してくれます。
これ、実はAssetBundle以外のファイルも配置出来ます。具体的にはAssetsと同じフォルダに作成されるAssetBundlesフォルダ以下のファイルがサーバーにアップロードされるみたいです。
アクセスは「192.168.100.103:7888/」から行います。
例えばAssetBundles以下にtwitter_icon.pngを作成し、ブラウザに「192.168.100.103:7888/twitter_icon.png」と記述すれば、ファイルがダウンロードされます。
ちなみに、この「192.168.100.103:7888/」はAssetBundleServerURLから持ってきた物です。この値はSetDevelopmentAssetBundleServerで使用するものなので、実際に運用する場合は使いません。
なおサーバーが起動してない状態かつシミュレーションモードも行って居ない状態の場合「Failed downloading bundle *** from http://192.168.100.103:7888」みたいなエラーが出ます。
AssetBundleを構築せず動作をシミュレート
AssetBundle ManagerにはAssetBundleをロードする際「AssetBundleの動作をシミュレートし、ローカルファイルから直接アセットを読み込む」機能が付いています。
これを利用すれば、開発時はローカルリソースから読み込み高い反復性を維持、開発完了後はAssetBundleからロードに切替…なんて事も出来ます(プロジェクトによってはステージ調整後毎回数時間のビルドをかけてたりするので、是非とも導入してほしいフロー)
シミュレートを行うには Assets>AssetBundles>Simulation Modeにチェックを入れます。
少しややこしいのが、このモードはLocal AssetBundle Serverよりも優先されます。またこのモードを使用している場合、基本的にAssetBundleに対してアクセスしません。開発中の項目だけこのモードみたいなのは出来ないみたいなので、やるなら内部コードを少し書き換える必要がありそうです。
同一のAssetBundleを呼んでもOK
AssetBundle ManagerのAPIは既に同一のAssetBundle(assetbundle名で判断してるっぽい)を開いている場合でもnullを返しません。
というか、動作がアセット単位になるので接続・非接続みたいなイメージでやると良いかもしれません。
依存関係を解決してくれる
AssetBundle Managerには依存関係を見て依存してるAssetBundleがあれば事前に読んでくれるコードが組み込まれているので、依存関係があっても気にせずロード出来ます。
…これ、逆を言えば「依存してるAssetBundleがあれば勝手に接続される」事を意味するので、AssetBundleのフォーマットや運用方法によっては注意が必要です。
まあAssetBundleManager.UnloadAssetBundleで依存してるAssetBundleが他から参照されてなければ自動で解放してくれるみたいなので、そこまで運用に神経質にならなくても良いかもしれませんが。
感想
依存関係の解決と、AssetBundleのエミュレートが結構便利です。特にキャラクターやステージを別AssetBundleに格納して配信するタイプのコンセプトで作ってるゲームの場合、これは非常にマッチすると思います。
ただ、上辺の部分を結構やってしまうため、ワークフローによっては使いにくくなるかもしれません。まぁその場合は、自分にあったワークフロー用のアセットを作ればよいと思います。
本当はバリアントの機能も紹介したかったのですが、なんか以前と挙動が異なるような気がするので後回しで。
関連
Unity-Technologies / AssetBundleDemo — Bitbucket