improving AssetBundle Variants

So, I’d really love some way to script the creation of the data in asset bundle variants. Our current layout is to have different variants for different texture resolutions/compression settings; at load time, we select a variant for the device based on memory, screen size, etc. For the most part, our variants are only used for texture data.

However, given that we support 4 variant levels, this means 4 copies of every texture in our tree. This is error prone, wasteful of drive space, and increases caching time substantially. I’d really love to get rid of these completely, and only have one copy of each texture.

Recently I’m working on running on low memory devices on Android. This is problematic because of the lack of universal texture compression which supports alpha. If I want to use the variant system for this, it would be a 4x on all of my textures. So instead, I’m building versions of all of our asset bundles for each of the various texture compression formats on android (dxt, pvr, astc, etc). This basically works by switching the texture type and re-building the asset bundles for each format, which is also incredibly slow.

This has lead me to the idea of not using the variant system at all, writing a custom editor for textures which allows me to tag them with the needed data, then building one copy of the asset bundles for each variant/compression/platform combination (roughly 25 copies of my asset bundles). It saves me from having duplicate data in my tree, but will most likely destroy our build times and make our lives painful in new and undiscovered ways.

Ideally, I would be able to use the actual variant system without duplicating data or building multiple copies of the asset bundles. (ie: Single manifest per platform, variants for resolution - and extra variants for texture type on android). However, to do this, we’d need a different set of APIs that would allow the creation of these variants at build time. I posted an idea for how this might look here:

http://feedback.unity3d.com/suggestions/callbacks-for-asset-processing-or-generation-on-assetbundle-builds

The basic idea is a callback when each asset is built into the bundle, which allows you to manipulate the data and it’s importer settings before it’s put into a bundle, or add it to multiple bundles/variants.

1 Like

@jbooth_1 The asset bundle system still appears to be a total pain to use in the kind of powerful way you are describing. Could you post an update on where you went with this and how your custom system worked out? It seems like a really nice idea if it didn’t explode build times too much.

I am working on similar platform support issues at the moment with a very texture-hungry app. Any help / pointers would be much appreciated.

Well, if I was approaching this issue now, I’d wait until the new system ships if I could. From what I’ve gathered, they seem to have arrived at the same conclusions I did, and ended up with a similar set of solutions. What we used for The Walking Dead : March to War, our last game, is something like this:

  • Only mark assets into bundles if you explicitly load them into the game. Do not mark any dependencies, etc.
  • At build time, scan all the dependencies and auto generate your own bundles. If an asset is large (texture, sound, etc) it goes into it’s own bundle. If an asset is small and used by many assets, then put it into it’s own bundle (we do a post process to group these if possible). If an asset is not used by any other asset, do not put it into a bundle and it will get sucked into the parent bundle.
  • We don’t use variants anymore. They suck. Instead, we find all textures and sounds at build time, check them out from perforce, modify their settings according to a set of rules which the user can override on a per-file or per-directory basis, and build a separate set of bundles for that level of detail.
  • When the client connects, it chooses a detail level based on the device (memory mostly) and modifies the download path to that set of bundles.

This was a ton of work to get working (several months of full time work); we wrote our own perforce integration, distribute work across machines, and ran into all kinds of gotchas (like, your data will change if you build the game then build the bundles, so always run a fresh unity for the asset bundles, and another for the game). But we have very few issues with asset bundles anymore- the system mostly just works, and it has only a small amount of conceptual ‘leakage’ into our daily workflow. But it was a ton of work to get there, and stuff I really don’t think the average user should have to do.