はじめに
以前Addressable Asset Systemについての基本操作の記事を書いたのですが、Asset Bundleの知識もマトモに得ずにけしからんと怒られてしまうかもしれないのでAsset Bundleの基礎を学んでいこうかなと思います。(Addressableは内部的にAssetBundleを利用している)
www.hanachiru-blog.com
また公式ドキュメントはこちら。
docs.unity3d.com
概要
Asset Bundleについての説明を公式ドキュメントより引っ張ってきます。
AssetBundle (アセットバンドル) はランタイムに読み込むプラットフォーム特有のコード以外のアセット (モデル、テクスチャ、プレハブ、オーディオクリップ、シーン全体) を含むアーカイブファイルです。アセットバンドルは互いの依存関係を示すことができます。例えば、あるアセットバンドル のマテリアルは他のアセットバンドルのテクスチャを参照できます。ネットワークを使った効果的な配布のために、アセットバンドルはその使用要件に応じてビルトインのアルゴリズムの中の 1 つで圧縮されます (LZMA と LZ4)。
アセットバンドルはダウンロードコンテンツ (DLC) に有用で、初期インストールサイズを削減し、エンドユーザーのプラットフォームのために最適化されたアセットを読み込み、ランタイムのメモリにかかる負担を軽減します。
AssetBundleに格納するアセットとしてモデル、テクスチャ、プレハブ、オーディオクリップ、シーン全体が紹介されていますが、ScriptableObjectを格納することもできます。ただScriptableObjectを定義している.csファイル自体はプロジェクトのアセンブリに含まれていなければならないことに注意してください。
利用の流れ
Asset Bundleを利用するにあたって以下のフローを行います。
- アセットバンドルにアセットを割り当てる
- アセットバンドルをビルドする
- アセットバンドルとアセットをロードする
またAsset Bundleは必ずリモートからダウンロードしなければならないわけではなく、ローカルに配置することもできます。
- サーバーに配置した
Asset Bundleをダウンロードして利用する StreamingAssets内に配置したAsset Bundleを読み込んで利用する
後気をつけてほしい点としてBuildTargetというどのプラットフォーム向けにビルドするか設定しなければならず、指定したプラットフォーム以外だと利用できないことも注意してください。
- StandaloneOSX
- StandaloneWindows
- iOS
- Android
- StandaloneWindows64
- WebGL
- WSAPlayer
- StandaloneLinux64
- PS4
- XboxOne
- tvOS
- Switch
- Stadia
- CloudRendering
- PS5
BuildTarget - Unity スクリプトリファレンス
加えて圧縮の仕方を指定することができ、以下の3つから選びます。(LZ4を利用する方が多いよう)
- 非圧縮
- LZMA
- LZ4
アセットバンドルにアセットを割り当てる
Projectビューより対象のアセットを選択し、Inspectorビューの下部にAsset Bundleと書かれた左にあるセクションをクリック、Newよりアセットバンドル名を指定します。


このときSampleFolder/Sampleのように/をつけることでフォルダー構造にすることができます。
アセットバンドルをビルドする
アセットバンドルをビルドするにはコードを書かなければいけません。正直めんどくさいですが、サンプルを公式ドキュメントより引用させていただきます。
using UnityEditor; using System.IO; public class CreateAssetBundles { [MenuItem("Assets/Build AssetBundles")] static void BuildAllAssetBundles() { string assetBundleDirectory = "Assets/AssetBundles"; if(!Directory.Exists(assetBundleDirectory)) { Directory.CreateDirectory(assetBundleDirectory); } BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); } }
https://docs.unity3d.com/jp/current/Manual/AssetBundles-Workflow.html
コードの説明をざっくりするとこんな感じ。
MenuItemでUnityの上にあるメニューバーにあるAssets/Build AssetBundlesを選択することで、メソッドを実行するAssets/AssetBundlesフォルダ内にビルド後のファイルを出力するBuildPipeline.BuildAssetBundlesでビルドを行う
BuildPipeline.BuildAssetBundlesの引数は結構色々と設定することができます。
Unity - スクリプティング API: BuildPipeline.BuildAssetBundle
一番気をつけてほしいのは前述もしましたがBuildTargetで、適切なものを選択してください。
またBuildAssetBundleOptions.Noneに関しては以下の記事が参考になるかと。
アセットバンドルのビルド - Unity マニュアル

ビルドされたファイル群
AssetBundles |--- AssetBundles |--- AssetBundles.manifest |--- samplefolder |--- sample |--- sample.manifest
Manifestファイル
上記のAssetBundles.manifestとsample.manifestの中身を覗いてみましょう。
// sample.manifest ManifestFileVersion: 0 CRC: 307180686 Hashes: AssetFileHash: serializedVersion: 2 Hash: 46b1de024bbcb1a0d43b0604c3474f58 TypeTreeHash: serializedVersion: 2 Hash: 4df8c69f2c8a6ad9e3cbf82bb83e4dc3 HashAppended: 0 ClassTypes: - Class: 28 Script: {instanceID: 0} - Class: 213 Script: {instanceID: 0} SerializeReferenceClassIdentifiers: [] Assets: - Assets/Sprites/AssetBundle/assetbundle.png Dependencies: []
sample.manifestには含まれるアセット、依存関係等の情報が書き込まれています。
// AssetBundles.manifest ManifestFileVersion: 0 CRC: 1670162852 AssetBundleManifest: AssetBundleInfos: Info_0: Name: samplefolder/sample Dependencies: {}
対してAssetBundles.manifestにはアセットバンドルの関連情報と依存関係を表しています。
またドキュメントにmanifestファイルの読み込み方・利用の仕方の紹介がされていますね。
アセットバンドルを使いこなす - Unity マニュアル
AssetBundle ファイル
AssetBundlesとsampleがAssetBundleファイルに該当します。
アセットバンドルファイルは複数のファイルを内部に持つアーカイブであり、バイナリデータです。
またAsset Bundleファイルに何が含まれるかについては以下のような説明がありました。
- シリアル化したファイル。個々のオブジェクトに分割され、この 1 つのファイルに書き出されたアセットが含まれています
- リソースファイル。特定のアセット (テクスチャとオーディオ ) 用に別々に格納されたバイナリデータのチャンクで、Unity が別のスレッドのディスクから効率的にロードできるようにします。

アセットバンドルとアセットをロードする
今回は分かりやすくローカルのStreamingAssetsからロードを行なってみます。
StreamingAssetsフォルダを作成し、先ほどビルドしたファイル群を移動させます。

サンプルを参考にしながらコードを作成しました。
using System.IO; using UnityEngine; using UnityEngine.UI; public class LoadFromFileExample : MonoBehaviour { [SerializeField] private Image image; private void Start() { // AssetBundleのメタ情報のロード var assetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "samplefolder/sample")); if (assetBundle == null) { Debug.Log("Failed to load AssetBundle!"); return; } // テクスチャをメモリにロード var sprite = assetBundle.LoadAsset<Sprite>("assetbundle"); image.sprite = sprite; // AssetBundleのメタ情報をアンロード assetBundle.Unload(false); } }

また今回はAssetBundle.LoadFromFileを利用しましたが、以下の4種類が存在します。
- AssetBundle.LoadFromMemoryAsync
- AssetBundle.LoadFromFile
- WWW.LoadfromCacheOrDownload
- UnityWebRequestAssetBundle の DownloadHandlerAssetBundle (Unity 5.3 以降のもの)
詳しくは上記記事を参照してみてください。
ひとこと
AssetBundleの基本しか触れませんでしたが、Unloadであったり依存解決であったりと難しい箇所がまだまだ潜んでいます。
qiita.com
今から利用するのであればUnity公式がAddressable Asset Systemを用意してくれているので、特に理由がなければそちらを使っていけば良いとは思います。