Unity's standard scene management weaknesses

When you start any serious project, it is hard to satisfy yourself with Unity's simplified scene management system:

  • when you load a scene, everything is destroyed
    • this behaviour is probably aiming at limiting memory leaks
    • it is possible to do incremental scene load and you can specifically tell unity to not destroy things, but still asset survival is very closely linked to scene creation and destruction
  • because the loading and instantiation process is very intensive, you will experience app lockdowns during loads
  • download and load of scene is tightly coupled with a "get it when you need it" approach which is not very user friendly ^^
  • when you want to instantiate a prefab that is not in your scene (ie from code outside a MonoBehaviour), you have a problem...

These problems are especially limiting on mobile, where memory, processing power, and network bandwidth is very limited.

Asset bundles help but you'll have to handle a lot by yourself

Unity comes with a powerful "Asset Bundle" system that can automatically package assets in compressed files that can be used to later access. There are nice additions in the inspector to specify in which bundle each asset should go, but it clearly looks more like a "mod" than a true feature of the engine. For example, you will have to code the creation of asset bundles by yourself in the build process, you will also have to manage loading and dependencies of asset bundles by yourself. In other words Unity gives you the tools and an example on how to do it, but you will have to create your own pipeline for this to work.

Also when you look closer you find additional problems with the way files are loaded or embedded, for example:

  • the larger your asset bundle, the higher the chance that loading will fail on an instable mobile network connection. Unfortunately Unity's system will start loading the file from zero, and therefore chances are high that the download will fail again in the middle. A very frustrating situation for the user!
  • on Android, the assets are embedded in the jar file, and therefore they are compressed twice and cannot be accessed with standard I/O functions

My AssetMgr and SceneSystem

  1. All assets that the game uses need to be assigned to small bundles in the inspector
  2. My custom build process builds asset bundles and optionally uploads them on an ftp server, and/or embeds them in the APK/IPA/EXE
  3. Asset bundles can be overiden to simulation in Unity Editor so the game can run instantly without building the asset bundles*
  4. On runtime, everything is downloaded & loaded by my SceneSystem through the AssetMgr before the Scene starts
  5. Download is not the same process as loading asset to memory, and can decide if it's best to use embedded assets. Download is managed through BestHTTP, which provides functionality to resume load if it got interrupted. Files can still be discarded at load time in case they are corrupted, thanks to Unity's AssetBundle MD5 check.
  6. The game code makes intensive use of AssetMgr to get loaded asset and instantiate prefabs on the fly
  7. Scene switching is managed by my SceneSystem (each SceneSystem is actually a prefab and not a  Unity Scene), and all scenes can run either in the game as a whole, or stand alone. This makes it quicker to jump directly to your scene for debugging purposes.

* this also solves an issue with bundle shaders, since asset bundles are platform-specific it will not contain shaders for your Editor system if you target mobile for example. This will cause some infamous magenta shaded elements in your game if you run it in the editor while using inappropriate bundles.