4
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

【Unity3D】共有アセットバンドル

複数のアセットバンドルを扱う際、共通のマテリアル、メッシュ等が無駄に複製されてメモリを浪費する問題を回避する方法について。

ビルド

private void BuildAssetBundle(BuildTarget platform, Object[] commons, Object[] objects)
{
        //DeterministicAssetBundleが必要。
        //後で一部のアセットバンドルを再ビルドする際、オブジェクトの識別に利用される。
        //IDを付けない場合、共有アセットバンドルだけ後で再ビルドした時、リソースの関連付けが出来なくなるらしい。
        BuildAssetBundleOptions option =
                BuildAssetBundleOptions.CollectDependencies |
                BuildAssetBundleOptions.CompleteAssets |
                BuildAssetBundleOptions.DeterministicAssetBundle;

        BuildPipeline.PushAssetDependencies();

        // 共有アセットバンドルをビルド
        BuildPipeline.BuildAssetBundle(null, commons, "common.unity3d", option, platform);

        for(int i = 0; i < objects.Length; ++i)
        {
                // 個別のアセットバンドルもPush, Pop で囲む
                BuildPipeline.PushAssetDependencies();

                // 個別のアセットバンドルをビルド
                BuildPipeline.BuildAssetBundle(objects[i], new Object[]{objects[i]}, objects[i].name + ".unity3d", option, platform);

                BuildPipeline.PopAssetDependencies();
        }

        BuildPipeline.PopAssetDependencies();
}

ロード

IEnumerator LoadAssetBundle(string fileName, bool isCommon, DownloadCallback callback)
{
    // 共有アセットバンドルの読み込み.
    WWW loader = WWW.LoadFromCacheOrDownload("common.unity3d", 0);
    while(!loader.isDone) yield return new WaitForSeconds(0.1f);

    // LoadAll()で一旦全てロードすることで、リソースがメモリ上に乗る。
    // 多分シェーダーのコンパイルも行われる。
    // 依存するアセットバンドルからロードを行うまではUnload()しない。
    AssetBundle commonAB = loader.assetBundle;
    Object[] commonObj = commonAB.LoadAll();

    // 依存しているアセットバンドルA
    loader = WWW.LoadFromCacheOrDownload("AssetBundleA.unity3d", 0);
    while(!loader.isDone) yield return new WaitForSeconds(0.1f);

    // 必要なオブジェクトをロードして、アセットバンドルは即解放.
    AssetBundle ab = loader.assetBundle;
    Object objA = ab.Load("objectA", typeof(GameObject));
    ab.Unload(false);

    // 依存しているアセットバンドルB
    loader = WWW.LoadFromCacheOrDownload("AssetBundleB.unity3d", 0);
    while(!loader.isDone) yield return new WaitForSeconds(0.1f);

    ab = loader.assetBundle;
    Object objB = ab.Load("objectB", typeof(GameObject));
    ab.Unload(false);
}

参考サイト

参考サイト

Unity公式:アセット依存関係の管理 / Managing asset dependencies
http://docs.unity3d.com/ja/current/Manual/managingassetdependencies.html

keijiroさん:アセットバンドルとシェーダー
https://github.com/keijiro/unity-shader-bundle

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What are the problem?