アセットバンドルにスクリプトを含める
ファイルサイズの削減

アセットバンドル FAQ

どうやってアセットバンドルを使用するのですか?

アセットバンドルで作業するときに主に 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());
    }
}

このスクリプトはゲームオブジェクトにコンポーネントとして追加されます。アセットバンドルは次の方法により読み込まれます。

  • url と version の値はスクリプト実行前にインスペクターで設定しておく必要があります。url はアセットバンドルファイルのロケーションで、通常はインターネット上のサーバーです。version 番号は開発者がアセットバンドルにディスクのキャッシュ上に書き込むときに番号を付与します。アセットバンドルをダウンロードするとき Unity はキャッシュにすでにファイルが存在しているかをチェックします。もし存在する場合は、格納されているアセットと必要バージョンの比較を行います。もし異なる場合、アセットバンドルは再度ダウンロードされます。もし同じ場合は次にアセットバンドルをディスクからロードして、再度ダウンロードしません。これらの引数の詳細についてはスクリプトリファレンスの WWW.LoadFromCacheOrDownload 関数を参照してください。 このスクリプトのスタート関数が呼び出されると、コルーチンのように関数を呼ぶことでアセットバンドルのローディングがスタートします。関数は www オブジェクトとしてアセットバンドルのダウンロードをします。これによって、関数は www オブジェクトがダウンロードを完了するまで、そのポイントで停止します、しかし完了するまでコードの残りの部分の実行をブロックすることもしません。WWW.LoadFromCacheOrDownload でダウンロードされた場合にのみ 1 つの AssetBundle のダウンロードまでフレーム単位で終了することができます。
  • オブジェクトがアセットバンドルをダウンロードすると、.assetBundle プロパティーを使用して AssetBundle オブジェクトを取得します。このオブジェクトはアセットバンドルファイルからオブジェクトを読み込むインターフェースです。
  • この例ではアセットバンドルのプレハブへの参照が、.mainAsset プロパティーを使用して AssetBundle から取得されます。このプロパティーはアセットバンドルをビルドするときに設定され、オブジェクトを一つ目の引数として渡します。AssetBundle の main asset は AssetBundle 内のオブジェクトリストとその他についての情報を格納することもできます。

簡単にするために、前の例では、すべての安全チェックを行なっておりませんのでご注意ください。より完全な例については [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 を渡します。

現在ビルドしたアセットバンドルは将来の Unity バージョンで使用できますか?

アセットバンドルは type tree と呼ばれる構造を含むことができて、これによりアセットの種類に関する情報が Unity の異なるバージョンでも正しく理解できるようにしています。デスクトッププラットフォームでは、タイプツリーはデフォルトで含まれていて、BuildAssetBundleOptions.DisableWriteTypeTree を BuildAssetBundle 関数に渡すことによって無効化することができます。Webplayer は本質的にタイプツリーに依存していて常に含まれます(すなわち、DisableWriteTypeTree は効果がありません)。タイプツリーはモバイルやコンソールのアセットバンドルには含まれることがなく、このためこれらの場合にシリアライズの形式が変わった場合ははバンドルを再ビルドする必要があります。これは Unity の新バージョンで発生するかもしれません(バグフィックスを除いて)。さらに MonoBehaviour でアセットバンドルに含まれるシリアライズされたフィールドを追加、削除した場合も同様に発生します。アセットバンドルを読み込むときにアセットバンドルの再ビルドが必要なときは、Unity でエラーメッセージが表示されます。

アセットバンドルのオブジェクトはどのようにしてリストにできますか?

AssetBundle.LoadAllAssets を使用してアセットバンドルに含まれるすべてのオブジェクトを含む配列を取得することができます。識別子の一覧を直接に取得することはできません。良くある回避策は、別の TextAsset を保持して、アセットバンドルのアセットの名前を保持することです。

アセットバンドルは、他のアセットバンドル中のアセットをどのように参照するのですか?

例えば、バンドル A が、マテリアルとテクスチャを持つプレハブを含んでいるとします。そしてバンドル B は、その同じプレハブのインスタンスを持つシーンを含んでいるとします。Bundle B はマテリアルにアクセスできる必要があります。マテリアルが特定のアセットバンドルに含まれているのでなければ、バンドル A と B の両方に含められます。

アセットバンドルにスクリプトを含める
ファイルサイズの削減