Downloadables · Tutorial

T1: AssetBundles (Unity) – Part 1

AssetBundles are just great. I love using them and playing with them around. But we’re here for the basics and how to use them, explained in a real-example way. This is some sort of tutorial how to basically load all your assets from the bundles and access them at runtime. But first, how to build them and how to create them.

Using Unity’s asset inspector

This part (1) we’ll keep it simple – we just use Unity’s default asset Bundle name and variant setting, which is extremely simple.

Set the name there, and the other dropdown next to the longer one is setting the variant. Do this to all assets you want to be bundled, and which names/files (bundles). Be aware that you cannot add a scene in a bundle that other assets (prefabs, per example) already are named under.

You don’t really have to put every image of a prefab (model) in specifical bundles – except if you want a bundle only with images/sounds/etc, because Unity automatically adds them in the same bundle as the prefab requires dependent assets to it.

So, we’re done with learning how to do that. Now building the bundles!

Building

Create an script named “BuildAssetBundles.cs” and place it in Assets/Scripts/Editor folder.

Now you should get the Build/AssetBundles menu item on the top bar in the Unity Editor.

That’ll build all the bundles that you’ve set in the editor manually for assets under your project’s folder, next to your Assets folder, in Bundles folder. It should contain a “Bundles” file and same named AssetBundles with *.manifest extension. The manifest files aren’t required to be there, so you can add your own script that removes all the *.manifest files from all subfolders too (you can build bundles under subfolders too with a name like “test/myBundle.bundle”). It should compile just fine.

Loading – LoadAssetBundles wrapper

It’s not as heavy to understand, and quite easy to do.

We create a object (not static) class that holds 2 dictionary lists, holding the bundle name, and the actual AssetBundle loaded (Bundles field). The other one (Files field) holds a unique path for an asset and the loaded bundle that the asset is in.

public AssetBundle LastLoadedBundle; it’s just for debugging. And public string Error; is only for showing in text what the problem is if the asset loading fucks up – to throw an exception, for instance. Also holding the Bundles folder path under public static string BundlesPath.

LoadBundle(string shortBundleName, string bundlePath, int version, bool loadAllAssetAsync) is just for loading bundles, to make it’s files available to use at runtime.

LoadAsset ( string fileName, bool clear, bool withSubassets = false ) where T : UnityEngine.Object is used only after the LoadBundle function was used – after the bundles have been loaded. It is self explanatory, that you’re able to grab assets by any type from the bundle at path.

The clear parameter is just for one-use-only loading of an asset. Which means, after the asset has been loaded, the bundle that the asset has been loaded from is going to be unloaded and it’s files unaccessible. The withSubassets parameter is used to just load to memory all the sub-assets the asset you’re searching for depends to.

Loading – Bootstrapper

I created a MonoBehaviour inherited class that holds a LoadAssetBundles instance, ready to use and few other functions. Start () initializes the Init () routine.

In the Init () routine is where all the loading happens. First getting the asset bundle names from the main Bundle file, loading all assets and returning just the assets with the AssetBundleManifest type, and selecting it’s first index, in which we have the bundles string array.

We then loop for each assetBundle in the assetBundles string array from the manifest, check if the bundle files exist.

Now getting the files from the bundles, adding them in the Files list and loading them to memory. We’ve now successfully loaded all AssetBundles and can access the files!

After the warmup you’re ready to just do initializations of the game, installing managers or loading scenes.

I also recommend you to call Resources.UnloadUnusedAssets (); at the end of the bundle loading to memory, because it will significantly reduce memory usage – nothing is lost, you can still access all your assets.

To load assets you must write the whole asset path, with the “assets/bundled/etc” as well.

Project Repository