アセットバンドルはアセットの集合で,実行するときにロードできるようパッケージ化されてます。アセットバンドルによりアプリケーションに新しいコンテンツを動的にロード,アンロードすることが出来ます。アセットバンドルはリリース後の動的コンテンツローディングの実装に使用できます。
ゲームが最初にデプロイされたとき,ディスク上で使用するスペースを削減するために使用できます。すでにパブリッシュされたゲームに新しいコンテンツを追加することにも使用できます。
アセットバンドルを作成するためには,ビルドパイプライン エディタ クラスを使用します。Editor クラスを使用する全てのスクリプトは,Assetsフォルダの任意の場所で,Editorと名前のついたフォルダに配置する必要があります。C#でのそのようなスクリプトのサンプルは次の通りです:
using UnityEngine;
using UnityEditor;
public class ExportAssetBundles {
[MenuItem("Assets/Build AssetBundle")]
static void ExportResource () {
string path = "Assets/myAssetBundle.unity3d";
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
BuildAssetBundleOptions.CollectDependencies
| BuildAssetBundleOptions.CompleteAssets);
}
}
エディタスクリプトはゲームオブジェクトに適用する必要はありません。その代わり,エディタによって使用されます。前述のサンプルではエディタのAssetsメニューにBuild AssetBundleという名前の新規のアイテムを作成します。
このサンプルを使用するためには:
BuildAssetBundle 関数の行でアセットバンドルを作成し,指定した場所に保存します。最初の引数によりメインアセット,すなわちアセットバンドルからアセットをロードするときにmainAssetプロパティによって直接取得することのできる特別なアセット,を指定します。メインアセットの指定は必須ではなく,使用しない場合は引数のnullを指定できます。二つ目の引数はアセットバンドルを構成するオブジェクトの配列です。三つ目の引数はアセットバンドルを保存するディスク上の場所です。最終の引数はアセットバンドルをビルドする際の,ビルド フラグまたはオプションです。ビットまたはOR(|)によりアセットバンドルをビルドするオプションを合成します。この例ではBuildAssetBundleOptions.CollectDependencies により他のオブジェクトにより参照されるアセットを含むようになり,さらにBuildAssetBundleOptions.CompleteAssetsによりアセットが完全に含まれるようになります。
アセットバンドルのビルドはパブリッシュ前のステップであり,一つの関数コールによって一回のみ発生し,例えば,メニューアイテムによって全てのアセットバンドルをビルドします。アプリケーションを開発するとき,ヘルパー関数を記述すべきであり,ターゲットプラットフォームで全てのアセットバンドルを,シングルクリックまたはバッチモードでユーザによるアクションなく,ビルドします。
さらにアセットバンドルを作成する他の関数があります。詳細については ここ を参照下さい。
アセットバンドルで作業するときに主に2つのステップがあります。最初のステップはアセットバンドルをサーバまたはディスク上のロケーションからダウンロードします。これはWWWクラスにより行います。二つ目のステップはアセットバンドルからアセットをロードし,アプリケーションで使用します。次がC#スクリプトでのサンプルです:
using UnityEngine;
using System.Collections;
public class BundleLoader : MonoBehaviour{
public string url;
public int version;
public IEnumerator LoadBundle(){
using(WWW www = WWW.LoadFromCacheOrDownload(url, version){
yield return www;
AssetBundle assetBundle = www.assetBundle;
GameObject gameObject = assetBundle.mainAsset as GameObject;
Instantiate(gameObject );
assetBundle.Unload(false);
}
}
void Start(){
StartCoroutine(LoadBundle());
}
}
このスクリプトはゲームオブジェクトにコンポーネントとして追加されます。アセットバンドルは次の方法によりロードされます:
Please note that for simplicity the previous example is not doing any safety checks. Please look at the code here for a more complete example.
アプリケーションの作成は反復的なプロセスなので,かなりの頻度でアセットを何度も修正し,これによりテストするためにはアセットバンドルを毎回の変更の度に再ビルドする必要が出てきます。エディタにアセットバンドルをロードすることは可能ですが,これは推奨できるワークフローではありません。その代わりに,エディタをテストする際は,Reources.LoadAssetAtPath ヘルパー関数を使用して,アセットバンドルを使用するときに再ビルドを回避できます。この関数によりアセットバンドルからロードしたかのようにアセットをロードできますが,ビルドプロセスはスキップされアセットは常に最新となります。
次はヘルパースクリプトの例で,エディタで実行しているかどうかにかかわらずアセットをロード出来ます。このコードを AssetBundleLoader.cs というC#スクリプトにコードを入れてください:
using UnityEngine;
using System.Collections;
public class AssetBundleLoader {
public Object Obj; // The object retrieved from the AssetBundle
public IEnumerator LoadBundle<T> (string url, int version, string assetName, string assetPath) where T : Object {
Obj = null;
#if UNITY_EDITOR
Obj = Resources.LoadAssetAtPath(assetPath, typeof(T));
if (Obj == null)
Debug.LogError ("Asset not found at path: " + assetPath);
yield break;
#else
WWW download;
if ( Caching.enabled ) {
while (!Caching.ready)
yield return null;
download = WWW.LoadFromCacheOrDownload( url, version );
}
else {
download = new WWW (url);
}
yield return download;
if ( download.error != null ) {
Debug.LogError( download.error );
download.Dispose();
yield break;
}
AssetBundle assetBundle = download.assetBundle;
download.Dispose();
download = null;
if (assetName == "" || assetName == null)
Obj = assetBundle.mainAsset;
else
Obj = assetBundle.Load(assetName, typeof(T));
assetBundle.Unload(false);
#endif
}
}
AssetBundleLoaderスクリプトを使って,ビルドしたアプリケーションを実行したときであっても,またはエディタ実行時にプロジェクトフォルダからアセットを直接ロードのときであっても,アセットをアセットバンドルからロードすることが出来ます:
using UnityEngine;
using System.Collections;
public class ExampleLoadingBundle : MonoBehaviour {
public string url = "http://www.mygame.com/myBundle.unity3d"; // URL where the AssetBundle is
public int version = 1; // The version of the AssetBundle
public string assetName = "MyPrefab"; // Name of the Asset to be loaded from the AssetBundle
public string assetPath; // Path to the Asset in the Project folder
private Object ObjInstance; // Instance of the object
void Start(){
StartCoroutine(Download());
}
IEnumerator Download () {
AssetBundleLoader assetBundleLoader = new AssetBundleLoader ();
yield return StartCoroutine(assetBundleLoader.LoadBundle <GameObject> (url, version, assetName, assetPath));
if (assetBundleLoader.Obj != null)
ObjInstance = Instantiate (assetBundleLoader.Obj);
}
void OnGUI(){
GUILayout.Label (ObjInstance ? ObjInstance.name + " instantiated" : "");
}
}
前述のスクリプトにより,Assetsフォルダの中に ExampleLoadingBundle.cs というファイルを保存します。正しい値にパブリック変数をセットして実行した後,AssetBundleLoaderクラスを使用してアセットをロードします。次にインスタンス化されて,GUIで表示されます。
WWW.LoadFromCacheOrDownload を使用して,自動的にアセットバンドルをディスクに保存することが出来ます。WebPlayerでは合計で上限50MB(全てのWebPlayerで共通)に制限されていることに留意して下さい。より多くのスペースが必要である場合は,ゲームで別のキャッシングライセンスを購入できます。
If your AssetBundles are stored in the StreamingAssets folder as Uncompressed AssetBundles, you can use AssetBundle.CreateFromFile to reference the AssetBundle on disk. If the AssetBundles in the StreamingAssets folder are compressed, you will need to use WWW.LoadFromCacheOrDownload to create an uncompressed copy of the AssetBundle in cache.
アセットバンドルはプラットフォーム間で互換性があります。次の表をガイドラインとして使用して下さい。
アセットバンドルのプラットフォーム間の互換性 | |||||
Standalone | Webplayer | iOS | Android | ||
Editor | Y | Y | Y | Y | |
Standalone | Y | Y | |||
Webplayer | Y | Y | |||
iOS | Y | ||||
Android | Y |
例えば,Webplayerのビルドターゲットが有効であったときに作成されたバンドルはエディタと互換性があり,スタンドアローンのビルドとも互換性があります。しかし,iOSまたはAndroidプラットフォーム向けにブル度されたアプリとは互換性がありません。
アセットバンドルをビルドするときアセットは,拡張子を除いたファイル名で,内部的に識別できます。例えばプロジェクトフォルダの “Assets/Textures/myTexture.jpg” に配置されたテクスチャはデフォルトのモードだと “myTexture” として識別してロードされます。これをより細かく設定するには,アセットバンドルをビルドするときに BuildPipeline.BuildAssetBundleExplicitAssetNames を用いて各オブジェクトに対してカスタムのID(文字列)の配列を提供します。
アセットバンドルにより異なるゲーム間でコンテンツを共有することが出来ます。必要な要件として,アセットバンドルに含まれるゲームオブジェクトにより参照される全てのアセットはアセットバンドルに含まれているか,アプリケーションの中に存在する必要があります(現在のシーンでロードされている)。参照されたアセットがビルドされたときにアセットバンドルに含まれることを保証するためには BuildAssetBundleOptions.CollectDependencies を渡します。
アセットバンドルは Type Tree と呼ばれる構造を含むことが出来て,これによりアセットの種類に関する情報がUnityの異なるバージョンでも正しく理解できるようにしています。デスクトッププラットフォームでは,タイプツリーはデフォルトで含まれていて, BuildAssetBundleOptions.DisableWriteTypeTree をBuildAssetBundle関数に渡すことによって無効化することが出来ます。Webplayerは本質的にタイプツリーに依存していて常に含まれます(すなわち,DisableWriteTypeTreeは効果がありません)。タイプツリーはモバイルやコンソールのアセットバンドルには含まれることがなく,このためこれらの場合にシリアイズのフォーマットが変わった場合ははバンドルを再ビルドする必要があります。これはUnityの新バージョンで発生するかもしれません(バグフィックスを除いて)。さらにMonoBehaviourでアセットバンドルに含まれるシリアイズされたフィールドを追加,削除した場合も同様に発生します。アセットバンドルをロードするときにアセットバンドルの再ビルドが必要なときは,Unityでエラーメッセージが表示されます。
AssetBundle.LoadAll を使用してアセットバンドルに含まれるすべてのオブジェクトを含む配列を取得することが出来ます。識別子の一覧を直接に取得することは出来ません。良くある回避策は,別のTextAssetを保持して,アセットバンドルのアセットの名前を保持することです。