RedditPP Mascot

RedditPP

r/unity • … • u/TehTuringMachine

Trying to asynchronously load assets at the start of a scene using Addressables

Hello everyone,

Some friends and I want to create a loading system that will allow us to asynchronously load multiple assets at once and wait until all of the assets are done loading before starting the main game logic.

A basic example of our approach is at the bottom of the post. We using [AsyncOperationHandles](https://docs.unity3d.com/Packages/[email protected]/manual/AddressableAssetsAsyncOperationHandle.html) returned by [Addressables.LoadAssetAsync](https://docs.unity3d.com/Packages/[email protected]/manual/LoadingAddressableAssets.html) in order to get an array of Tasks that we can use with [Tasks.WaitAll()](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitall?view=net-5.0). However, when we try to run this code in unity it freezes as soon as we press the play button and we can't stop it or interact with it at all. We have tried commenting out code to figure out exactly were the issue was and the problem is either with Tasks.WaitAll() or our LoadAddressable method.

We have done a ton of searching to look at different ways of accomplishing this (including using coroutines), but those types of implementations don't let us wait for all of the assets to load or had similar problems.

I know this is a complicated problem, but I'm open to any and all suggestions. Let me know if there is any other information I can add. Thanks in advance for all of your help!

void Start() { //Check if instance already exists if(instance == null) //if not, set instance to this instance = this;

//If instance already exists and it's not this: else if(instance != this) //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager. Destroy(gameObject);

//Sets this to not be destroyed when reloading scene DontDestroyOnLoad(gameObject);

// Create a list of tasks to load our sprites Task[] spriteTasks = new Task[AssetPaths.SpritePaths.Length]; int task_counter = 0; foreach(String Path in AssetPaths.SpritePaths) { spriteTasks[task_counter] = GameUIController.LoadAddressable<Sprite>(Path); task_counter++; }

// Create a list of tasks to load our prefabs Task[] minionTasks = new Task[AssetPaths.PreFabPaths.Length]; task_counter = 0; foreach(String Path in AssetPaths.PreFabPaths) { minionTasks[task_counter] = GameUIController.LoadAddressable<GameObject>(Path); task_counter++; }

Task.WaitAll(minionTasks); Task.WaitAll(spriteTasks); }

/// <summary> /// This method loads our sprites asynchronously /// </summary> /// <returns>An enumerator which will allow this method to run as a coroutine.</returns> public static Task<T> LoadAddressable<T>(string Path) { // Allow for parallel loading of sprites AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>(Path);

// Wait for the sprites to be loaded into RAM (?) return handle.Task; }

— 0