- Home /
How to maintain asset bundle compatibility?
I'm working on an app that has a lot of downloaded content via asset bundles. When we make updates to our app in the future, how can I insure that compatibility is maintained so that the previously created asset bundles don't have to be rebuilt and downloaded by the users?
I understand that removing any key assets or functionality from the core app is a bad idea, though my tests have shown that adding functionality and assets work fine without causing problems. But perhaps there are some more specific rules or things not to do.
Will future updates of Unity support asset bundles built in earlier versions? Or do we need to commit to using a specific version of Unity?
one thing to beware is that assetbundles are not compatible cross platform. An assetbundle created for desktop/web will not be loadable on mobile and vice versa.
Regarding Unity versions, I have not had any problems with incompatibility between versions. IIRC assetbundles from 2.6 was loadable by 3.0, but that is of course no guarantee for future versions.
Cross platform compatibility would be nice, but we can live with separate bundles for each platform. It's helpful to know that assetbundles from 2.6 are still working with 3.0. We are just going to have to be very careful to test bundle compatibility before releasing updates to our core app.
I'd go a lot further: will future bundle versions be loadable from current or older updates of Unity? So we can keep backward compatibility on our binaries in only 1 central repository. Otherwise, we'd still need to (or maybe need even more) commit to using a specific version of Unity, I suppose.
Answer by davebuchhofer · Dec 21, 2011 at 02:13 PM
(Recording discussion between Aubrey and Joachim here for posterity!)
(1) Is it intended AssetBundle behavior for script references to break when scripts are moved to a different compilation pass?
Yes.
(2) What can I do about this? Keep them in the same compilation Unit when building asset bundles / using asset bundles.
(3) How exactly does the script referencing system work, and what else might cause it to break in the future that I should be concerned about now? Here's a perfect UnityAnswers post (with no definitive answers as of yet) to compliment this question: http://answers.unity3d.com/questions/175310/how-to-maintain-asset-bundle-compatibility.html
Script references are identified by 3 strings when built into an asset bundle.
classname
namespace (Only provided when the script is contained in a .NET dll built outside of Unity) * assembly name (name of the dll when built outside of Unity or )
On PC / Mac / Web:
A TypeTree data structure is used to provide full backwards compatibility. Public variables can arbitrarily be removed / added / moved in the scripts and it will do "the right thing". (Removed properties are ignored, moved properties are identified by name, Added properties use the default value)
On iOS / Android:
A hash of all serialized script properties is used to detect if the binary data has the same data layout. If it doesn't match loading the asset bundle fails. This optimization reduces code size and massively improves load times on mobile. If the serialized data layout of builtin classes changes (eg. from 3.4 to 3.5) then the asset bundle is also detected as incompatible and will fail to load.
Joachim Ante,
This information is very helpful. It didn't occur to me that iOS would use a different check for compatibility, so it's definitely something I have to test more carefully.
Thanks for posting that, I was going to but you beat me to it :)
Based upon what I learned from this conversation, I am rewriting the AssetBundle creation logic of a world loading library I am working on. Now it will, among other things, automatically replace component script instances with a placeholder script, who's job will be to store serialized parameters for the script it replaced and then replace the original script back when the AssetBundle is loaded. Very little added overhead, tremendous added long term flexibility.
I can't imagine backwards compatibility for basic assets like textures and TerrainData ever being broken, as Unity has a tramendous number of webplayers in the wild which their latest plugin will always need to be able to decompress and run.
Huh? Link to a "perfect UnityAsnwers post" is to this very same post!
would someone $$anonymous$$d elaborating on this point ?
classname
namespace (Only provided when the script is contained in a .NET dll built outside of Unity) assembly name (name of the dll when built outside of Unity or )
I believe that I might be running into this issue but do not yet understand it.
Answer by KvanteTore · Oct 11, 2011 at 06:19 AM
Although assetbundles are quite convenient, it is very much a closed format, and I'd be a bit wary to rely on any closed format for a project that needs to have backwards compatibility across Unity versions. An alternative would be to roll your own format or use something like ULib (I'm not affiliated with Viktor Abdulov in any way, nor have I tried ULib myself) to serialize your assets.
There are also some memory management issues with assetbundles. It is not always trivial to free the memory used by an assetbundle after it has been loaded.
For my our project I started out using assetbundles, but when I discovered that they are not loadable across platforms I decided to roll my own, based on ICSharpZipLib and custom serialization (I only need to serialize textures and meshes).
That is an interesting approach, however we are dealing with some very complex assets with a lot of behaviors and animations associated with them. Rebuilding entire scenes from a custom format may be possible, though would come with a big development cost and potentially a lot of lurking bugs. Asset bundles are already working for us very well, so I don't see any need to build a custom solution. We just want to make sure the bundles will continue to work for us in the future and avoid any thing that would make them incompatible.
yeah, for arbitrary complex objects it would be a nightmare keeping up with the unity feature list for your own s11n solution.
I would guess that the most likely thing to break in the future is the connected scripts. The scripts are part of the compiled project and not the assetbundle, so the client has to match the correct script at runtime.
$$anonymous$$y hope is that as long as I do not rename, move, or delete any scripts or referenced assets that the bundles will be ok.
$$anonymous$$oving assets should be fine. Unity uses a guid to identify assets. If you're using external version control, that guid is stored in the .meta file next to the asset, and as long as you keep those files together you should be fine.
I'm not entirely sure how unity identify monobehaviours. I know, at least, that when I moved all my scripts to a precompiled dll all my prefabs lost it's script references. $$anonymous$$y guess is that you'll be fine until Unity decides to change the way script compilation works.
I don't know your project, but I would recommend building in an option to redistribute all the assetbundles if Unity should decide to break backwards compatibility in the assetbundle format at some point..
Your answer
Follow this Question
Related Questions
AssetBundle incompatibility 2 Answers
How can I remotely update my customers game scripts? 0 Answers
Same models packaged into assetbundle got different result? 0 Answers
AssetBundle's multiple build results are inconsistent in version 2020.1.1f1 0 Answers
How can I use AssetBundles created from different Unity versions? 0 Answers