How can I load a list of AssetReferences using LoadAssetsAsync?

What I thought would be a simple operation is clearly not.
I have a list of asset references.
I want to load them using Addressables.LoadAssetsAsync.
However, that method wants a list of IResourceLocations. How can I get the resource locations from the list of AssetReferences?

the other method:
Addressables.LoadAssetsAsync(references, callback, Addressables.MergeMode)

doesn’t seem to work all the time. If using MergeMode.Union I get back more loaded assets than I put in??
e.g if I have 3 references to load, I’m getting back a list that contains 5. Why?

MergeMode.None or First only ever returns 1 loaded asset.
Intersection just throws an error:

Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation`1[System.Collections.Generic.IList`1[UnityEngine.Object]], result='', status='Failed': Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=System.Collections.Generic.List`1[System.Object], Type=UnityEngine.Object
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1:<.ctor>b__33_0(AsyncOperationHandle)
DelegateList`1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.12.0/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.AddressableAssets.Initialization.<>c__DisplayClass14_0:<LoadContentCatalogInternal>b__0(AsyncOperationHandle`1)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.12.0/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.ResourceManagement.ChainOperation`2:OnWrappedCompleted(AsyncOperationHandle`1)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.12.0/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.ResourceManagement.ResourceManager:Update(Single)
MonoBehaviourCallbackHooks:Update() (at Library/PackageCache/com.unity.addressables@1.12.0/Runtime/ResourceManager/Util/MonoBehaviourCallbackHooks.cs:15)

I just don’t get it.

How can I simply load a bunch of AssetReferences in bulk?
Using labels is not an option. Assets may belong to many different groups and different labels etc.

Do I somehow need to construct a ChainOperation? I have no idea :frowning:

I ran into the same situation. As far as I can tell, you can use the asset references as keys to load in the locations of the resources first (the merge mode here is of importance as well). After that, you can use that result to load in the actual items:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;

public class TestAddressableFinding : MonoBehaviour
{
    [SerializeField]
    private List<AssetReference> references = new List<AssetReference>();

    private void Start()
    {
        Addressables.InitializeAsync().Completed += OnAddressablesInitialized;
    }

    private void OnAddressablesInitialized(AsyncOperationHandle<IResourceLocator> locator)
    {
        StartCoroutine(RoutineLoadItems());
    }

    private IEnumerator RoutineLoadItems()
    {
        List<object> keys = new List<object>(references.Count);
        references.ForEach(r => keys.Add(r));

        // You can add a typeof() at the end to filter on type as well. Take not of the merge mode here
        AsyncOperationHandle<IList<IResourceLocation>> locationsHandle = Addressables.LoadResourceLocationsAsync(keys, Addressables.MergeMode.Union);
        yield return locationsHandle;

        Debug.LogFormat("Loaded {0} locations.", locationsHandle.Result.Count);

        // Using UnityEngine.Object here because I don't know what you'll be loading
        AsyncOperationHandle<IList<UnityEngine.Object>> objectsHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(locationsHandle.Result, null);
        yield return objectsHandle;

        Debug.LogFormat("Loaded {0} items.", objectsHandle.Result.Count);
    }
}
1 Like

Thanks for the help.
Figured out the issue with Union merge and loading assets in bulk with runtime key. Issue was that without specifying the type of asset, addressables returns the main asset + sub assets. So when trying to load a sprite and mesh, instead of getting back 2 objects, you get 4: Sprite, texture, fbx and mesh.

I’m assuming this is because I’m calling Addressables.LoadAssetsAsync instead of actual types.

But since my list contains lots of different references, I can’t pass that type information in the load.

Maybe your solution of loading the locations might work though…

Basically I’m trying to create a loader utility that I can add a bunch of different asset references of varying types. Load them in bulk and get a single completed event when everything loads. Then be able to reference the loaded assets by the asset reference they were loaded from.

Doesn’t seem possible though if the result list has different size than the input list