Why and How I Refactor My AssetBundle Manager

Comparing to putting asset inside of Resources folder, using asset bundle system has a lot of benefits. While using resources system, Unity engine will create a index table for all resources inside Resources folder, in order to fasten the speed of Resources.Load. It is really fast but every time we add something into the folder, engine will need to rebuild the table, as the number of resources increase, the table also increase and need a lot of memory. By using asset bundle, we can load asset bundle manually, so compare to resources system, we usually get a faster launch time and a fast enough asset loading time. But here comes the problem, we need to manually manage the bundle.

The most popular operation with asset bundle are Load and Unload, synchronously or asynchronous, so these API are involved:

(LoadFromMemory and LoadFromMemoryAsync are bad in practice because the data is stored redundantly in three location: The memory that store the binary data, the stack and the asset itself.)

The first 6 API are toward asset bundle and the last 2 are toward asset, my new solution is create asset bundle handler, it contains:

Every time I call my LoadAssetSync or LoadAssetAsync function, the manager checks if the asset bundle is loaded, if not, load it. It doesn’t increase the reference count until the asset is loaded. Once the asset is loaded, we increase the reference count for asset bundle handler and asset handler.

For unload, notice that the asset cannot be unload individually, the API Resources.Unload is for asset that loaded though resources system, so I only decrease the reference count of asset handler, when it hits 0, also decrease the reference count of asset bundle handler by 1. My asset bundle will only be unload when the reference count becomes 0 or UnloadAllAsetBundles is called, when switching scene.

When I implementing this system, I was thinking to combine RAII with this manager, as we need to unload asset manually, which is quite unsafe. However, we cannot destroy object (not gameobject) by C#, we might also want to reuse the asset a period of time after loaded, so I decide to believe the garbage collection of C# and the programmer who use this manager.