Version: 5.5
アセットバンドル
アセットバンドルの圧縮

アセットバンドルのビルド

アセットバンドル (スクリプトと Unity エディターでは AssetBundle と呼ばれます) の作成を始めるには、まず最初に、バンドルに含めたいプロジェクトフォルダーからアセットを 1 つ選択する必要があります。そのアセットの Inspector ウィンドウの最下部に、AssetBundle メニューがあります。これをクリックすると、その時点で定義されているすべてのアセットバンドルの名前と、新規のバンドルを定義するオプションが表示されます。

アセットバンドルの作成
アセットバンドルの作成

バンドルの定義をまだ行っていない場合は、New… をクリックしてバンドルの名前を入力してください。

このバンドルにさらにアセットを追加するには、Inspector ウィンドウの 1番下のメニューを使って Project ウィンドウのアセットを選択し名前がついたバンドルに割り当てます。

初期値では、Assets の AssetBundle オプションは None に設定されています。この場合アセットは AssetBundle には書き込まれず、代わりにプロジェクト本体自体とともにパッケージ化されます。このメニューを使用して、1つあるいは複数のアセットバンドルを作成し、それに名前を付け、その新しいアセットバンドルの名前をアセットの移動先として設定することができます。

アセットバンドルの作成
アセットバンドルの作成

この画像では、アセットが environment/desert という名前のアセットバンドルに追加されています。このアセットバンドルは、以前追加された他のアセットを含む場合もあります。アセットバンドルの名前は小文字のみで構成されます。大文字を使うと自動的に小文字に変換されます。名前中にフォワードスラッシュ(/)を使用することで効率良くフォルダーが作成され、画像のように、メニュー中にサブメニューが表示されます。

あなたが、割り当てられたアセットを持たないアセットバンドルを作成する場合は、Remove Unused Names オプションを使用することができます。これは空のアセットバンドルを削除します。

アセットに属しているメタファイルには、それに書き込まれた選ばれたアセットバンドル名を持つことになります。

アセットバンドルのエクスポート

アセットバンドルはスクリプトコードを使ってエディターからエクスポートされます。下記は、アセットバンドルをエクスポートするスクリプトです。

using UnityEditor;

public class CreateAssetBundles
{
    [MenuItem ("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles ()
    {
        BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal);
    }
}

このスクリプトが Asset メニュー下部にメニューアイテムを作成します。このメニューアイテムを、関数を呼び出してアセットバンドルをビルドするために選択すると、プログレスバーにビルドダイアログが表示されます。 関数 BuildPipeline.BuildAssetBundles は、ラベル付けされたアセットバンドルを作成し、それを “AssetBundles” という名前の出力フォルダーに配置します。([注]このスクリプトを実行するに、プロジェクトフォルダーに “AssetBundles” フォルダーを作成しておく必要があります。)

エクスポートされるそれぞれのアセットバンドルは AssetBundle メニューで作成した名前を持つことになります。さらに、それぞれの アセットバンドルは .manifest 拡張子に関連付けられているファイルを持つことになります。この マニフェスト ファイルは、任意のテキストエディターで開くことができるテキストファイルです。これは、ファイルの CRC とアセットの依存関係などの情報を提供します。上記の例のアセットバンドルには、マニフェスト ファイルがあり、それは次のようになります。

ManifestFileVersion: 0
CRC: 2422268106
Hashes:
  AssetFileHash:
    serializedVersion: 2
    Hash: 8b6db55a2344f068cf8a9be0a662ba15
  TypeTreeHash:
    serializedVersion: 2
    Hash: 37ad974993dbaa77485dd2a0c38f347a
HashAppended: 0
ClassTypes:
- Class: 91
  Script: {instanceID: 0}
Assets:
  Asset_0: Assets/Mecanim/StateMachine.controller
Dependencies: {}

これに加えて2つのファイルが作成されます ― アセットバンドルがもう1つと、マニフェスト ファイルがもう1つです。これら2つのファイルはアセットバンドルが作成される度に作成されます。これらはアセットバンドルが作成された各フォルダーに1つづつ作成されるため、毎回同じ場所にアセットバンドルを作成した場合は、追加ファイルは2つだけになります。追加マニフェストファイル(この例では AssetBundles.manifest )は、もうひとつの マニフェスト ファイルとほぼ同じように使用できますが、アセットバンドル同士の関係・依存関係に関する情報を表示します。この例では、アセットバンドルが1つしかないため、他に依存関係はありません。

ManifestFileVersion: 0
AssetBundleManifest:
  AssetBundleInfos:
    Info_0:
      Name: scene1assetbundle
      Dependencies: {}

シェーダーストリッピング

バンドルにシェーダーを含む場合、Unity のエディターは現在のシーンとライトマッピングの設定を見て、どのライトマップモードを使用するかを決定します。つまり、バンドルを作成するときは設定されたシーンを開いておくことが必要です。

ただし、ライトマップモードを計算するシーンをマニュアルで指定することもできます。これは、バンドルを コマンドライン から作成する場合に必要です。

使用したいシーンを開きます。Graphics Settings Inspector (Edit > Project Settings > Graphics) で、Shader stripping の Lightmap modesManual を選び、From current scene を選択します。

Using AssetBundles with engine code stripping

The engine code stripping feature removes code that is not used in any Scene included in the Build Settings > Scene list. Engine code stripping can reduce the build size, and is only supported on some platforms such as iOS, WebGL and Android. It is enabled by default when IL2CPP is selected as the scripting backend in the Player Settings. Only the Unity engine code is stripped; your scripts are not affected.

Player Settings in the Inspector window, displaying the enabled code stripping feature for iOS
Player Settings in the Inspector window, displaying the enabled code stripping feature for iOS

This has implications for loading AssetBundles at runtime. When an AssetBundle requiring code stripped from the build is later loaded at runtime, an error is thrown because the stripped code is no longer accessible. This can be avoided by listing which AssetBundles might be loaded by the player, so that the required engine code is not stripped.

This is done by calling the BuildPipeline.BuildPlayer function directly. Set the value of the assetBundleManifestPath property of the BuildPlayerOptions class to the additional manifest file generated by the asset bundle build process.

using UnityEngine;

using UnityEditor;

namespace AssetBundles

{

    public class BuildScript

    {

        public static void BuildPlayer()

        {

            BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();   

            // example hard-coded platform manifest path

            buildPlayerOptions.assetBundleManifestPath = "AssetBundles/iOS/iOS.manifest";

            // build the Player ensuring engine code is included for 

            // AssetBundles in the manifest.

            BuildPipeline.BuildPlayer(buildPlayerOptions);

        }

    }

}

The code stripping system then uses all of the AssetBundles listed in that manifest file (along with the Scenes in the build) to determine which engine code to preserve.

For platforms or builds that do not support engine code stripping, or if it is not enabled, the assetBundleManifestPath from BuildPlayerOptions is ignored.

The AssetBundle demo makes use of engine code stripping.

アセットバンドルのエディターツール

アセットバンドルの名前の取得

以下のエディタースクリプトは、ビルドプロセスが作成できる AssetBundle の名前を表示することができます。

using UnityEditor;
using UnityEngine;

public class GetAssetBundleNames
{
    [MenuItem ("Assets/Get AssetBundle names")]
    static void GetNames ()
    {
        var names = AssetDatabase.GetAllAssetBundleNames();
        foreach (var name in names)
            Debug.Log ("AssetBundle: " + name);
    }
}

アセットバンドルが変更されたときに呼び出されるコールバック

アセットバンドルのアセットが変更と関連している場合は、コールバックを受け取るために AssetPostprocessorクラスのOnPostprocessAssetbundleNameChanged メソッドを使用します。

using UnityEngine;
using UnityEditor;

public class MyPostprocessor : AssetPostprocessor {

    void OnPostprocessAssetbundleNameChanged ( string path,
            string previous, string next) {
        Debug.Log("AB: " + path + " old: " + previous + " new: " + next);
    }
}

アセットバンドルのバリアント

これは、仮想アセットと同様の結果を達成するために用いることができます。たとえば、MyAssets.hd と MyAssets.sd のような アセットバンドルのバリアントを設定することができます。アセットが完全に一致することを確認してください。Unity はパイプラインを構築することによって、これら2つのアセットバンドルのバリアント内のオブジェクトに、まったく同じ内部 ID を与えます。そのため、これら2つのアセットバンドルのバリアントは、実行時に別のバリアント拡張のアセットバンドルと任意に切り替えることができます。

アセットバンドルバリアントを設定する方法。

  1. Asset Labels GUI の右側にエディターからの1つの追加のバリアント名を使用します。
  2. コード内で AssetImporter.assetBundleVariant オプションを使用します。
AssetBundle バリアント
AssetBundle バリアント

アセットバンドルの省略しない名はアセットバンドル名とバリアント名の組み合わせになります。例えば、アセットバンドルのバリアントとして MyAssets.hd を追加したい場合、アセットバンドル名を MyAssets、アセットバンドルのバリアントを hd に設定する必要があります。

アセットバンドル名を単に MyAssets.hd のように設定すると、バリアントのアセットバンドルではなく標準のアセットバンドルとして作成されます。 “MyAssets” + “hd” と “MyAssets.hd” + "" は、省略しない名で表示するとまったく同じアセット名になるため、共存できません。

スクリプティングのアドバイス

アセットを特定のアセットバンドルに含めるための API

アセットバンドルのビルド

アセットバンドルのビルドをすることができるシンプルな API - BuildPipeline.BuildAssetBundles() - が利用可能です。以下が必要です。

  • すべてのアセットバンドルの出力パス。
  • BuildAssetBundleOptions (see below).
  • BuildTarget 前と同じです。
  • オーバーロードバージョン。アセットバンドルへ含むアセットからのマップを格納する AssetBundleBuild の配列を提供します。これにより、以下のような柔軟性が提供されます。それは、あなたのマッピング情報をオーバーロードバージョンから設定しビルドすることができます。そして、このマッピング情報は、アセットデータベースに存在しているものを破棄/置き換えすることはありません。

アセットデータベースのアセットバンドル名を操作する API

BuildAssetBundleOptions

  • CollectDependenciesDeterministicAssetBundle は常に有効になっています。
  • CompleteAssets 常にアセットからではなく、オブジェクトから開始するため無視されます。デフォルトでは complete でなければなりません。
  • ForceRebuildAssetBundle たとえ、アセットに変更がない場合でも、このフラグを設定するとアセットバンドルを強制的にリビルドできます。
  • IngoreTypeTreeChanges たとえタイプツリーが変更されても、このフラグを設定すると変更は無視されます。
  • DisableWriteTypeTreeIngoreTypeTreeChanges と相反します。タイプツリーを無効にしても、タイプツリーの変更は無視されません。

マニフェストファイル

マニフェスト ファイルは、以下の情報を含むすべてのアセットバンドルのために作成されています。

  • マニフェストファイルは AssetBundle の次にあります。
  • CRC
  • アセットファイルハッシュ。このアセットバンドルに含まれるすべてのアセットのためのシングルハッシュ。インクリメンタルビルドチェックにのみ使用されます。
  • タイプツリーハッシュ。このアセットバンドルに含まれるすべてのタイプのためのシングルハッシュ。インクリメンタルビルドチェックにのみ使用されます。
  • クラスタイプ。このアセットバンドルに含まれるすべてのクラスタイプ。タイプツリーインクリメンタルビルドチェックを行うときに新しいシングルハッシュを取得するために使用されます。
  • アセット名。すべてのアセットは、明示的にこの AssetBundle に含まれます。
  • Dependent AssetBundle 名​​。この AssetBundle が依存するすべての AssetBundles。
  • このマニフェストファイルは、実行時に必要ではなく、インクリメンタルビルドで使用されます。

Single マニフェストファイル

以下を含む 1つの マニフェスト ファイルを生成します。

  • すべてのアセットバンドル。
  • すべてのアセットバンドルの依存関係。

シングルマニフェストアセットバンドル

以下の API を持つ AssetBundleManifest オブジェクト 1つだけが含まれます。

API をロードするアセットバンドル

タイプツリー

タイプツリーは、デフォルトでアセットバンドルに書き込まれます。別のシリアライズのためのソリューションがあるため、Metro だけは例外です。

アセットバンドル
アセットバンドルの圧縮