Search Unity

LoadAssetsAsync fails but LoadResourceLocationsAsync succeeds

Discussion in 'Addressables' started by ohthepain, Dec 7, 2021.

  1. ohthepain

    ohthepain

    Joined:
    May 31, 2017
    Posts:
    100
    We have shrunk our app bundle from 350 mb to less than 100 using addressables. Nice!

    Now I need to implement a loading bar. But to do that I need to load the assets as a list. So far all of the assets are loaded individually.

    I am trying to load a list of assets using LoadAssetsAsync. My keys look like
    "Assets/UI/Prefabs/Misc/HUD/CurrencyHUD.prefab" for example.

    Here is a method with 3 attempts to load. The first 2 fails. The 3rd succeeds, but loads individual assets in a loop. They all use the same keys.

    Code (CSharp):
    1.     public async Task Load(Action<AsyncOperationHandle> completed)
    2.     {
    3.         // This fails
    4.         AsyncOperationHandle handle = Addressables.LoadAssetsAsync<UnityEngine.Object>(keyMap.Keys, (gameObject) =>
    5.         {
    6.             Debug.Log($"Load: got object {gameObject.name}");
    7.         });
    8.  
    9.         // Result.Count is always 0
    10.         var validateAddress = Addressables.LoadResourceLocationsAsync(keyMap.Keys);
    11.         await validateAddress.Task;
    12.         if (validateAddress.Status == AsyncOperationStatus.Succeeded)
    13.         {
    14.             if (validateAddress.Result.Count > 0)
    15.             {
    16.                 Debug.Log($"Load: got resource location");
    17.             }
    18.         }
    19.  
    20.         // This succeeds
    21.         int numLoaded = 0;
    22.         List<Task> tasks = new List<Task>();
    23.         foreach (var keyValuePair in keyMap)
    24.         {
    25.             string key = keyValuePair.Key;
    26.             AsyncOperationHandle<IList<IResourceLocation>> h = Addressables.LoadResourceLocationsAsync(key);
    27.             Assert.IsFalse(handles.ContainsKey(key));
    28.             handles[key] = h;
    29.             h.Completed += (handle) =>
    30.             {
    31.                 Log($"Load: Completion for key {key}. Resource locations:");
    32.                 List<IResourceLocation> locations = new List<IResourceLocation>(handle.Result);
    33.                 foreach (var resourceLocation in handle.Result)
    34.                 {
    35.                     Log($"Load result: {resourceLocation.PrimaryKey} {resourceLocation.ResourceType} {resourceLocation.InternalId}");
    36.                     ++numLoaded;
    37.                 }
    38.             };
    39.  
    40.             tasks.Add(h.Task);
    41.         }
    42.  
    43.         await Task.WhenAll(tasks.ToArray());
    44.         tasks.Clear();
    45.         keyMap.Clear();
    46.  
    47.         completed.Invoke(handle);
    48.     }
    So why do the list operations fail to load any of the assets? The results from the individual asset calls all show keys that match the keys in my list operations.

    I would love to see example that uses addresses as keys. The examples I have found all seem to use labels, like "enemy" rather than asset addresses.
     
  2. ohthepain

    ohthepain

    Joined:
    May 31, 2017
    Posts:
    100
    Does anybody have an example of using Addressables.LoadAssetsAsync or Addressables.LoadResourceLocationsAsync with a list of keys?

    Or am I way off base here?
     
    Last edited: Dec 10, 2021
  3. andymilsom

    andymilsom

    Unity Technologies

    Joined:
    Mar 2, 2016
    Posts:
    294
  4. ohthepain

    ohthepain

    Joined:
    May 31, 2017
    Posts:
    100
    Thanks Andy, I added the merge mode and it works now.

    I see what happened. The overload of Addressables.LoadAssetsAsync that takes a callback parameter assumes MergeMode.Intersection. So the solution was to use the non-callback version _add_ the merge mode.