Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Correct way of instantiate scene content in parallel?

Discussion in 'Addressables' started by jister, Apr 15, 2020.

  1. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    I'm trying to use Addressables to speed up loading times.
    My first attempt was this:

    Code (CSharp):
    1.     Func<AssetReference, Task> InstantiateAsset = async (assetRef) => await assetRef.InstantiateAsync().Task;
    2.     await Task.WhenAll(environment.assetReferences.Select(a => InstantiateAsset(a)));
    and quickly realized that this won't cut it because of await on the iteration. so it's still Instantiating 1 by 1.

    then i found
    Code (CSharp):
    1. InstantiateAll<TObject>(IList<IResourceLocation>, Action<IAsyncOperation<TObject>>, InstantiationParameters)
    2. Instantiate multiple objects.
    which doesn't exist in 1.7.5 anymore.

    so this seems to work, but has some inconveniences:
    Code (CSharp):
    1. public class LoadingManager : MonoBehaviour
    2. {
    3.     public string[] asyncAssets;
    4.     private readonly TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>();
    5.  
    6.     public Task<bool> ExecuteAsync()
    7.     {
    8.         return _tcs.Task;
    9.     }
    10.  
    11.     private async Task Start()
    12.     {
    13.         GameInstance.profileStart = DateTime.Now;
    14.         Load();
    15.         await ExecuteAsync();
    16.         GameInstance.Instance.Init();
    17.     }
    18.  
    19.     private void Load()
    20.     {
    21.         Addressables.LoadAssetsAsync<GameObject>(asyncAssets, LoadCallback, Addressables.MergeMode.Union).Completed += LoadingManager_Completed;
    22.     }
    23.  
    24.     private void LoadingManager_Completed(AsyncOperationHandle<IList<GameObject>> obj)
    25.     {
    26.         _tcs.SetResult(true);
    27.     }
    28.  
    29.     private void LoadCallback(GameObject obj)
    30.     {
    31.         Instantiate(obj);
    32.     }
    33.  
    34. }
    for starters the fact that i only get it to work with asyncAssets being a string[], where i would like if to be a AssetReference[].
    Second, I would like to Instantiate all async, but since InstantiateAll is removed in 1.7.5 I'm not sure how.
    Also the question is if this would improve anything?
    Third how to get rid off the TaskCompletionSource?

    So just to summaries: I'm trying to improve loading time by Async loading (and Instantiating?) a scene's content. Whats the proper way to do this?

    thanks.
     
  2. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    ok so small changes with big results :)
    changed the annoying string[] to a Addressable label and do this:

    Code (CSharp):
    1. public AssetLabelReference assetLabel;
    2. private void Load()
    3.     {
    4.         Addressables.LoadAssetsAsync<GameObject>(assetLabel, LoadCallback).Completed += LoadingManager_Completed;
    5.     }
    went from ca. 3s load to 1s.
    to set labels on addressables in 1.7.5:
    open the addressable groups window (window->Asset Managment ->addressables->groups)
    in the addressable groups window you can set labels per addressable.
     
    Last edited: Apr 15, 2020