Home > Back-end >  Optimal way for managing async loading of assets on game load
Optimal way for managing async loading of assets on game load

Time:12-13

I'm developing a mobile idle game for iOS and Android and I'm now at the stage where I'm building the game's save/load infrastructure.

When opening the game app for loading a previously saved session, after the app has been closed, and before the loading the previously saved session, I'm loading mandatory game assets, mostly ScriptableObjects, with Addressables asynchronously like this:

StartCoroutine(LoadInventoryAssets());
StartCoroutine(LoadCharacterAssets());
StartCoroutine(LoadSoundAssets());

Each LoadAssets function looks roughly like this:

_assetsLoadingOp = Addressables.LoadAssetsAsync<AssetType>("AssetLabel", null);
yield return _assetsLoadingOp;

if (_assetsLoadingOp.IsDone) 
{
     _results = _assetsLoadingOp.Result
}

Finally, when all of these are loaded I run the function that loads the relevant scene, game objects, and injects the saved data. This function must only run after all the previous Addressable assets were loaded.

yield return StartCoroutine(LoadSavedGame());

The problem with the above is that the LoadSavedGame function might run before all of the previous asset loading functions were completed.

I could solve that by adding yield return to all Coroutines, but wouldn't that make each of them load sequentially instead of in parallel?

Any thoughts on what's the best approach for this would be greatly appreciated.

CodePudding user response:

You can just use an integer to count how many functions have been complete. In the end of each LoadAssets function:

if(  task == 3)
    StartCoroutine(LoadSavedGame());

CodePudding user response:

If you call multiple Addressables.LoadAssetsAsync without waiting, you're actually calling them parallel but yield return to multiple handle not possible with Coroutine but with tasks.

        List<Task<object>> _tasks = new List<Task<object>>();
        public void LoadAsset(string address) 
        {
            var handle = Addressables.LoadAssetAsync<object>(address);
            _tasks.Add(handle.Task);
        }

        public void Initialize() 
        {
            LoadAsset("address");
            LoadAsset("address");
            LoadAsset("address");
            Task.WaitAll(_tasks.ToArray()); //Load Assets Parallel but run this
            //method sequitally and block the thread until tasks are completed.
        }
  • Related