To begin creating an asset bundle, you must first select an asset from your project folder that you would like to include in a bundle. At the very bottom of the inspector window for that asset, there is an Asset Bundle menu. Clicking this will reveal the names of any currently defined asset bundles, plus the option to define a new bundle:
If you haven’t yet defined the a bundle, click ‘New’, and enter a name for your bundle.
You can then continue to add other assets to this bundle by selecting those assets in your project view, then assigning them to the named bundle using this menu at the bottom of the inspector window.
By default the AssetBundle option for Assets is set to None, meaning the asset will not be written into an AssetBundle and will instead be packaged with the main project itself. Using this menu, you can create one or more Asset Bundles, give them names, and then use these new AssetBundle names as the destination for the asset.
In the picture the Asset asset has been added to an AssetBundle called environment/desert. This AssetBundle may contain other assets which have previously been added. AssetBundle names are always lower-case. If you use upper-case characters in the name they will be converted to lower-case. Using a forward slash in the name of the AssetBundle effectively creates folders, and the menu will have sub-menus, as the picture above shows.
If you create AssetBundles which have no assets assigned to them, then the “Remove Unused Names” option can be used. This will delete the empty AssetBundle.
The meta file belonging to an Asset will have the chosen AssetBundle name written into it.
AssetBundles are exported from the editor using script code. The following script exports AssetBundles:
using UnityEditor;
public class CreateAssetBundles
{
[MenuItem ("Assets/Build AssetBundles")]
static void BuildAllAssetBundles ()
{
BuildPipeline.BuildAssetBundles ("AssetBundles");
}
}
This script creates a menu item at the bottom of the Assets menu. Whn you select this menu item to call the function and build the AssetBundles, you will see a build dialog with a progress bar. The BuildPipeline.BuildAssetBundles function creates the AssetBundles that have been labelled, and puts them into an output folder called “AssetBundles”. (Please note that you need to create the “AssetBundles” folder in your project folder in advance of running this script.)
Each AssetBundle that is exported will have the name created in the AssetBundle menu. Additionally, each AssetBundle will have an associated file with a .manifest extension. This manifest file is a text file that you can open with any text editor. It provides information such as the file CRC and asset dependencies. The AssetBundle in the example above has a manifest file that looks like this:
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: {}
In addition to these, there are another two files created: Another AssetBundle and another manifest file. These two are always created whenever AssetBundles are created. They are created for each folder that AssetBundles are created in, thus if you always create AssetBundles in the same place, you will only get two extra files. The additional manifest file - in this example AssetBundles.manifest - can be used in much the same way as other manifest files but will show information on how AssetBundles relate and depend on each other. In this case, since we only have a single AssetBundle, it has no other dependencies.
ManifestFileVersion: 0
AssetBundleManifest:
AssetBundleInfos:
Info_0:
Name: scene1assetbundle
Dependencies: {}
The following editor script can display the names of the AssetBundles which the build process can create.
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);
}
}
You can use the OnPostprocessAssetbundleNameChanged method from the AssetPostprocessor class, to get a callback when the AssetBundle an asset is associated with changes.
using UnityEngine;
using UnityEditor;
public class MyPostprocessor : AssetPostprocessor {
void OnPostprocessAssetbundleNameChanged ( string path,
string previous, string next) {
Debug.Log("AB: " + path + " old: " + previous + " new: " + next);
}
}
AssetBundle Variants is a new 5.x feature. This can be used to achieve a result similar to virtual assets. For example, you can set AssetBundle a variants like “MyAssets.hd” and “MyAssets.sd”. Make sure the assets exactly match. The objects in these two variant AssetBundles will have the exactly same internal IDs which is ensured by the Unity build pipeline. So these two variant AssetBundles can be switched out arbitrarily with AssetBundles of different variant extension at runtime.
How to set assetbundle variants: 1. From the editor use the one extra variant name, to the right of the asset labels GUI. 2. In code use AssetImporter.assetBundleVariant option.
The full AssetBundle name will be the combination of the AssetBundle name and the variant name. For example, if you want to add “MyAssets.hd” as a variant AssetBundle, you should set the AssetBundle name to “MyAssets” and AssetBundle variant to “hd”. And the final AssetBundle is “MyAssets.hd”.
But if you only set the AssetBundle name like “MyAssets.hd”, then it’s just a normal AssetBundle which is not variant AssetBundle. “MyAssets”+“hd” and “MyAssets.hd”+”” cannot coexist as they lead to the same full AssetBundle name.
Simple APIs are available to build AssetBundles, BuildPipeline.BuildAssetBundles(). These APIs are pretty simple, you only need to provide:
A manifest file is created for every AssetBundle which contains the following information:
We generate a single manifest file which includes:
It only contains an AssetBundleManifest object which has following APIs:
Now we have:
A typetree is written to the AssetBundle by default. The only exception is Metro as it has different serialization solution.