I've got a little problem here that I'd like to ask you if somebody knows a solution to it.
The thing is that I need to have assets to be downloadable from the internet and to load them during runtime. The first and obvious thought would be to use AssetBundles. But AssetBundles have a downside that makes them pretty much useless to me: They NEED to be loaded COMPLETELY into memory to load an asset out of them. You then would either have them stay in memory in case you need another asset later on or you unload the AssetBundle from memory, but then have to load it (and therefore also uncompress it time-consumingly) again if you require another asset at a later point.
Usually, with today's machines, having it persist in memory is not that much of a deal, if you run out of memory the OS will cache it to disk without you having to do anything. But that's not the case on mobile devices where memory management is crucial.
The usual answer on this issue is always: Split your assets into multiple smaller AssetBundles in a smart way so that you will only have to load what you need. And if you need other assets on a later point in your application, load a different AssetBundle. Yes, that might help. But also: Being able to handle a number of assets at once with only one file not kind of the textbook definition of, well, a "bundle"? And despite this being more of a philosophical argument, having to handle multiple AssetBundles is not always the ideal way to go. Downloading them, for example, is MUCH easier when only having to handle a single file instead of multiple bundles. Another case would be if you need all assets at one single point anyway, like when you have to load a scene. As I understand it, right now you would have to uncompress and load the whole AssetBundle into memory. Running on a mobile device, that takes some time and a considerable chunk of your total available memory. Then you would have to load all required assets out of the bundle into memory, which is fine because you would have to do that anyway. And then, after you're done loading and instantiating them you can unload the AssetBundle again to free up the memory it took, luckily there's a method that allows this without loosing your instantiated assets. But this, also, takes a wee bit of time. And for the time frame directly before you unload the bundle, don't you have anything in memory twice? The original binary data of the AssetBundle and then the instantiated version that will persist after unloading the Bundle? That would only allow scenes that aren't bigger then half the memory that is available on the device. That's a little bit too restricting for my taste. Oh, and then comes the idea that you could use multiple small AssetBundles, load the first one, instantiate all the assets, then unload it and load the next, and so on ad nauseam. But please be honest: Who want's to write code to handle this? With all the keeping track of what asset sits in what AssetBundle? Ugh... There's GOT to be a better solution.
Then I took a second thought and it came to mind that the Resources folder kind of does EXACTLY what I need: As you know, everything you put in a folder named Resources in the Editor will be put into a file called resources.assets at the time you build your project. When running your project, Unity is able to pull all the assets you need out of that resources.assets file without having to load the complete .assets file into memory. It seems to just load what it needs without touching everything else in this file, which is simply perfect in terms of performance and memory consumption. I was able, with a bit of memory management concerning visible assets, to handle some considerably large scenes on mobile devices, without ever running out of memory. However, theres a but: The big drawback is that all assets MUST be build with your main application. It doesn't look like there would be a way to do this separately, like with AssetBundles.
And I think that's a shame, really. Because the technology required for this seems already build right into Unity. It's right there! And I can't seem to take use of it for what I need.
So, with that bit of story being told: Is there something that I don't know about that does what I want? Am I missing something obvious here? Or maybe a method, a workaround?
Answer by DaveA
Sep 16, 2011 at 06:28 AM
A workaround is to import some format at runtime. For geometry etc. there are some loaders for OBJ and X3D floating around. Rumor has it Collada is on the way. You can always concoct your own too. More than a few of us hope that Unity supports such things more fully in coming releases.
I gave you a "Correct Answer" for this one even though it's not really what I was asking for. But hey, you threw me a bone and I can appreciate this. ;) I ended up writing a custom and proprietary file format and parser for what I had to use all this for. On one hand I'm a bit angry that I had to do this because Unity's whole business model is (or: once was) built around the idea to make things like that a lot easier for the common guy, but what the hell. At least there's the whole .NET framework to play with and that's actually plenty of tools to do stuff with, if you just know how. So thanks for your answer, that's all I'm sayin'. :)
Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.
The best place to ask and answer questions about development with Unity.
If you are a new user, check out our FAQ for more information.
If you are a moderator, see our Moderator Guidelines page.
We are making improvements to UA, see the list of changes.
For troubleshooting common problems with Unity 5.x Editor (including Win 10).
To help users post good questions and use the site effectively we have posted a user guide. Please check it out.
Answers and Comments
4 People are following this question.
AssetBundle including resources that are in Resources folder
Does UnloadUnusedAssets() unload non-active or occlud
ResourceManager Class Referencing Assets?
About bundle asset and update