Sponsored By

Unity3d Asset Bundle Series

Improve your mobile games and support dynamic content without app store approvals. This series will give you a head start on making and using bundles in ways you probably didn't consider.

Dennis Piatkowski, Blogger

February 2, 2018

5 Min Read
Game Developer logo in a gray background | Game Developer

Asset bundles in Unity3d. Just saying the name sends shudders down most developers spines. They are potentially so super useful, and yet historically they are difficult to make and use. Originally we used  them to get around the download limits imposed on mobile app downloads. These days you can simply split the application binary to get a similar effect. But with an asset bundles, you get a bunch of features:

  • Faster "first run" startup. Load the bare minimum needed on startup to hook your players quickly

  • Dynamic content. Change your live game look and feel just by telling the client to download a new data set (no app store verification!)

  • Android Multi-GPU texture support. Each device gets the most efficient texture format possible, without complicated client changes

This is a series that dives into many things I've learned about bundles that can reform your own perception of them, solving issues you didn't know you could!

This first article will be updated with links to the rest of the articles as they are written, so be sure to check back later!

In my first installment of this asset bundle series, let's talk about upgrading an older project to Unity 5 bundles.

On this latest project I've been working on with ClutchPlay Games, I was asked to help straighten out a project that was based on the pre-Unity 5 bundle system. We did a lot to help it. First we added the Android GPU class support first, making sure everything worked. But our build times were taking forever, even with code that checksummed the source assets and only building what changed. So I decided to solve it with a crazy idea: let's move this project up to Unity 5's new bundle system.

In Unity 5's asset bundles, they take care of tracking all the source asset changes for you. It has many upsides: it's really fast to make small changes. It's super easy to add assets to any given bundle with the new UI. Building them is a single call, and it works reliably. The sample code for loading the bundles is clean and useful, took less than a day to integrate, and only a week to make it solid. If you're starting a new project, I highly recommend adding support for this early, it will definitely make certain distribution problems very easy.

But what is the value added for projects that still use the older system? On the surface they look completely incompatible. Assets were always added from code, which is perfect for build automation, very wise in large projects. You don't want to manually set every asset's bundle identifier through the UI. That alone would simply take too long. Then you notice the new BuildAssetBundles call that takes the AssetBundleBuild objects. Surely this is how.

But lo! 'Tis not true. It's simply not well documented. You can have the best of both worlds. Simply replace your old calls to BuildPipeline.BuildAssetBundle() with a method that changes the asset bundle assignments for each asset that you would pass to BuildAssetBundle. How, you say? Simple: it's now part of the AssetImporter interface.


AssetDatabase.StartAssetEditing();

for ( string assetPath in desiredAssets ) {
	var importer = AssetImporter.GetAtPath(assetPath);
	// note that you must set the bundle name before the variant.
	// If you want to clear the bundle name, set it to null - it will clear variant for you.
	if (importer.assetBundleName != bundleName)
		importer.assetBundleName = bundleName;
	if (importer.assetBundleVariant != variant && bundleName != null)
		importer.assetBundleVariant = variant;
}

// this might be a little extreme but we've had issues with old versions being used in builds
AssetDatabase.StopAssetEditing();
AssetDatabase.SaveAssets();
EditorApplication.SaveAssets();
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

At that point, everything will be assigned to the bundle names you want. As a separate step you then actually build the bundles through the simplified BuildPipline.BuildAssetBundles(). As a bonus, you can then examine and tweak the bundle assignments through the Editor UI!

Not all is wine and roses, however. There are a few not-so-obvious rules with the names you use for the bundles.

  • Periods confuse the loading system for some reason. The asset extension is ignored during loading, but extra periods in the asset filename or the bundle names confuse things.

  • Underscores have special meaning in bundle names. It's safest to avoid using them. Likewise, be sure not to use them in variant names.

  • Bundle names will always be stored lowercase. This prevents case confusion, and is not a bug.

  • Forward slashes create a "group" in the bundle name selection popup. This is highly useful. Be careful not to accidentally put them right together, like "textures//thing2". It breaks the menu.

There we are! With the new bundle system in place, our build times are down to a few minutes instead of an hour. With this new design, you can do a pass with the bundle assignments, and then edit a specific asset many times, doing only the bundle update over and over again. Because Unity tracks it for you, each bundle update takes only seconds.

Join us next time as we work out how to handle shared assets!

About the Author:

Dennis ends up dealing with all the junk most projects don’t think about until a week before release and realize that not all devices act the same and can’t fit the game into the 100mb limit. He has been writing up his thoughts on game development for a while now. You can see more of his thoughts at DWulf.com

Read more about:

Blogs
Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like