アセットバンドルで作業するときに主に 2 つのステップがあります。最初のステップはアセットバンドルをサーバーまたはディスク上のロケーションからダウンロードします。これは WWW クラスにより行います。二つ目のステップはアセットバンドルからアセットを読み込み、アプリケーションで使用します。次が C# スクリプトでのサンプルです。
using UnityEngine;
using System.Collections;
public class BundleLoader : MonoBehaviour{
public string url;
public int version;
public IEnumerator LoadBundle(){
while (!Caching.ready)
yield return null;
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());
}
}
このスクリプトはゲームオブジェクトにコンポーネントとして追加されます。アセットバンドルは次の方法により読み込まれます。
簡単にするために、前の例では、すべての安全チェックを行なっておりませんのでご注意ください。より完全な例については [http://translate.unity3d.com/html/ja/Manual/DownloadingAssetBundles.html] を参照してください。
アプリケーションの作成は反復的なプロセスなので、かなりの頻度でアセットを何度も修正し、これによりテストするためにはアセットバンドルを毎回の変更の度に再ビルドする必要が出てきます。エディターにアセットバンドルを読み込むことは可能ですが、これは推奨できるワークフローではありません。その代わりに、エディターをテストする際は、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 を使用して、自動的にアセットバンドルをディスクに保存することができます。Web Player では合計で上限 50MB (すべての Web Player で共通)に制限されていることに注意してください。より多くのスペースが必要である場合は、ゲームで別のキャッシングライセンスを購入できます。
アセットバンドルを StreamingAssets フォルダーに非圧縮のアセットバンドルとして保存している場合、AssetBundle.CreateFromFile でディスク上のアセットバンドルを参照します。アセットバンドルを StreamingAssets フォルダーに圧縮したアセットバンドルとして保存している場合、キャッシュに AssetBundle の圧縮されていないコピーを作成され WWW.LoadFromCacheOrDownload を使用する必要があります。
アセットバンドルはプラットフォーム間で互換性があります。次の表をガイドラインとして使用してください。
アセットバンドルのプラットフォーム間の互換性 | |||||
Standalone | Webplayer | iOS | Android | ||
エディター | ○ | ○ | Y* | Y* | |
Standalone | ○ | ○ | |||
Webplayer | ○ | ○ | |||
iOS | ○ | ||||
Android | ○ |
例えば、Webplayer のビルドターゲットが有効であったときに作成されたバンドルはエディターと互換性があり、スタンドアロンのビルドとも互換性があります。しかし、iOS や Android プラットフォーム向けにビルドされたアプリとは互換性がありません。
(*) モバイルプラットフォーム向けにビルドされたアセットバンドルは、エディターの実行されているプラットフォームと互換性のない、最適化された特定プラットフォーム向け形式で保存されたデータを含んでいる可能性があります。公開するゲームでは、プラットフォームごとにアセットバンドルを作成する必要があると考えて問題ありません。具体的には、シェーダーはプラットフォーム間でデータの持ち方が異なります。
例えば GI データは、ARM アーキテクチャ向けに最適化された形式で保存されているので x86 CPUs では読み込むことができません。 シェーダーは OpenGLES 2 の設定に合わせて保存されており、DX9/11 レンダラーを使用するエディターでは読み込めません。(OpenGLCore レンダラーでは読み込めます。) 開発中は、次のチュートリアルにも記述のある Simulation Mode を使用するのがお奨めです。 AssetBundles and the AssetBundle Manager これにより、エディターとモバイルプラットフォームが非互換を回避することができます。
アセットバンドルをビルドするときアセットは、拡張子を除いたファイル名で、内部的に識別できます。例えばプロジェクトフォルダーの “Assets/Textures/myTexture.jpg” に配置されたテクスチャはデフォルトのモードだと “myTexture” として識別して読み込まれます。これをより細かく設定するには、アセットバンドルをビルドするときに BuildPipeline.BuildAssetBundleExplicitAssetNames を用いて各オブジェクトに対してカスタムの ID (文字列)の配列を提供します。
アセットバンドルにより異なるゲーム間でコンテンツを共有することができます。必要な要件として、アセットバンドルに含まれるゲームオブジェクトにより参照されるすべてのアセットはアセットバンドルに含まれているか、アプリケーションの中に存在する(現在のシーンで読み込まれている)必要があります。参照されたアセットがビルドされたときにアセットバンドルに含まれることを保証するためには BuildAssetBundleOptions.CollectDependencies を渡します。
アセットバンドルは type tree と呼ばれる構造を含むことができて、これによりアセットの種類に関する情報が Unity の異なるバージョンでも正しく理解できるようにしています。デスクトッププラットフォームでは、タイプツリーはデフォルトで含まれていて、BuildAssetBundleOptions.DisableWriteTypeTree を BuildAssetBundle 関数に渡すことによって無効化することができます。Webplayer は本質的にタイプツリーに依存していて常に含まれます(すなわち、DisableWriteTypeTree は効果がありません)。タイプツリーはモバイルやコンソールのアセットバンドルには含まれることがなく、このためこれらの場合にシリアライズの形式が変わった場合ははバンドルを再ビルドする必要があります。これは Unity の新バージョンで発生するかもしれません(バグフィックスを除いて)。さらに MonoBehaviour でアセットバンドルに含まれるシリアライズされたフィールドを追加、削除した場合も同様に発生します。アセットバンドルを読み込むときにアセットバンドルの再ビルドが必要なときは、Unity でエラーメッセージが表示されます。
AssetBundle.LoadAllAssets を使用してアセットバンドルに含まれるすべてのオブジェクトを含む配列を取得することができます。識別子の一覧を直接に取得することはできません。良くある回避策は、別の TextAsset を保持して、アセットバンドルのアセットの名前を保持することです。
例えば、バンドル A が、マテリアルとテクスチャを持つプレハブを含んでいるとします。そしてバンドル B は、その同じプレハブのインスタンスを持つシーンを含んでいるとします。Bundle B はマテリアルにアクセスできる必要があります。マテリアルが特定のアセットバンドルに含まれているのでなければ、バンドル A と B の両方に含められます。