Search Unity

Issues with Addressable system

Discussion in 'Addressables' started by Rotary-Heart, Oct 20, 2018.

  1. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    This was tested with 0.4.6 and 2018.2.13f1

    1. Private serialized AssetReferences are not showing up on the inspector. It can be fixed by going to
    Code (CSharp):
    1. AssetReferenceDrawer.DescendHierarchy
    Modify the reflection check, is only checking for public fields (since that is the default parameter), therefore private fields will not be retrieved by reflection.

    2. What’s the proper way to use InstantiateAll and LoadAssets?? I can't find any way to make them work correctly.

    LoadAssets doesn’t seem to be working to load an array of objects.
    While this works, it only returns the first element of the array
    Code (CSharp):
    1. Addressables.LoadAssets<GameObject>(myarray, callback);
    If changed to use an array, it returns a status of failed
    Code (CSharp):
    1. Addressables.LoadAssets<GameObject[]>(myarray, callback);
    Now the InstantiateAll doesn't seem to work at all. While this compiles without issues, it throws the following error when called:
    Code (CSharp):
    1. Addressables.InstantiateAll<GameObject>(checkBoxFolder, callback);
    Then when replaced to GameObject[] it doesn’t compile, throwing the following error:
    Code (CSharp):
    1. Addressables.InstantiateAll<GameObject[]>(checkBoxFolder, callback);
    3. If a folder is marked as addressable the inspector won’t allow you to select anything that is inside that folder for an AssetReference field.
     
  2. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    After many more tests I cannot find any way to load or instantiate an array of addresses. Anyone have any workaround beside looping the array and loading individuallly?
     
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Loading multiple objects separately you need the final optional argument, `MergeMode mode`.

    The default is `MergeMode.UseFirst` which is what you get. To get each one separately use Union. There is also Intersection.

    The intention behind UseFirst seems to be to be able to use LoadAssets to load a main object and all of its other addressables dependencies at once. But I do think the intuitive default enum should be Union.
     
  4. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    Alright so I must be missing something here... Here's what I have right now:
    Code (CSharp):
    1. private void Start()
    2. {
    3.     Debug.Log(assets.Length);
    4.     Addressables.LoadAssets<AssetReferenceGameObject>(assets, callback, Addressables.MergeMode.Union).Completed += Loader_Completed;
    5. }
    6.  
    7. private void Loader_Completed(IAsyncOperation<IList<AssetReferenceGameObject>> obj)
    8. {
    9.     Debug.Log(obj.Status + ", " + obj.Result.Count);
    10. }
    11.  
    12. private void callback(IAsyncOperation<AssetReferenceGameObject> obj)
    13. {
    14.     Debug.Log(obj.Status + ", " + obj.Result);
    15. }
    Now this is throwing the following error:
    Code (CSharp):
    1. UnknownResourceProviderException: Exception of type 'UnityEngine.ResourceManagement.UnknownResourceProviderException' was thrown., Location=Assets/ManuallyAdded/IndividualTest/PrefabTest.prefab
    2. UnityEngine.AddressableAssets.Addressables:LoadAssets(IList`1, Action`1, MergeMode)
    3. Loader:Start() (at Assets/Loader.cs:12)
    This is the output I get from the callback:
    Code (CSharp):
    1. Failed,
    2. UnityEngine.Debug:Log(Object)
    3. Loader:callback(IAsyncOperation`1) (at Assets/Loader.cs:22)
    4. UnityEngine.ResourceManagement.DelayedActionManager:LateUpdate()
    And this is the output I get from the Loader_Completed
    Code (CSharp):
    1. Failed, 6
    2. UnityEngine.Debug:Log(Object)
    3. Loader:Loader_Completed(IAsyncOperation`1) (at Assets/Loader.cs:17)
    4. UnityEngine.ResourceManagement.DelayedActionManager:LateUpdate()
    I'm getting this same errors for all my 6 assets that I'm trying to load with this test script.
    Capture.PNG
     
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Without knowing your Addressable setting and what's inside your `assets` array I don't know what went wrong. But `AssetReferenceGameObject` (Or AssetReference, AssetReference____) is not something that can be loaded from bundle. Because they cannot be put in the Addressables panel in the first place.

    AssetReference is a variable type that stores GUID, which you can call the instance method .LoadAsset to use that GUID with the Addressables system. (Equivalent to Addressables.LoadAsset(aref.RuntimeKey)) It is used to load, not a load result.

    Look in the Addressables panel, what is the type of object that those addresses in your `assets` array point to? If it is a game object then the correct generic type is <GameObject>. (In which case you should use Addressables.Instantiate)

    On a technical side, each entry in your Addressables panel get assigned one "provider". Most of the them will get BundledAssetProvider which its job is to wait for one dependency ".bundle" file, which is assigned with AssetBundleProvider. Then get the thing inside it.

    The error suggests that your address key point to an asset with location requiring some provider that is no matching with any of your providers. I don't know what kind of address can cause this behaviour. (And the search for provider routine does not even use the generic yet) You could also find out what kind of provider that address need by using Addressables.LoadAsset<IResourceLocation>(yourKey) then check on the returned location.ProviderID (a string of provider's class name needed)
     
    Rotary-Heart likes this.
  6. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    Alright, that definitely makes sense. (I shouldn't be playing with 2 new systems at the same time) I completely miss typed the type that is going to load. Changing it to GameObject fixed the issue and of course it makes sense, since what I'm trying to load is a GameObject.... Brain fart there.

    For future reference: The assets array is just an array of AssetReferenceGameObject. They all are prefabs, a simple sphere prefab (used just for testing)
     
  7. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    Now the only one remaining is the Addressables.InstantiateAll. Which I cannot find how to execute without throwing errors.
     
  8. peterahou

    peterahou

    Joined:
    May 19, 2015
    Posts:
    53
    I've been struggling with the same issue and only managed to get Addressables.InstantiateAll to work by using a list of IResourceLocations. To get that list, I use Addressables.LoadAssets<IResourceLocation>(string array) like 5argon suggested. Also, don't forget the InstantiationParameters.
    Code (CSharp):
    1. private string[] _addresses = new string[2]{"sphere.prefab", "cube.prefab"};
    2.  
    3. public void Initialize()
    4. {
    5.      Addressables.LoadAssets<IResourceLocation>(_addresses, LocationCallback, Addressables.MergeMode.Union).Completed += LocationsReady;
    6. }
    7.  
    8. void LocationsReady (IAsyncOperation<IList<IResourceLocation>> obj)
    9. {
    10.      Addressables.InstantiateAll<GameObject>(obj.Result, InstantiateCallback, new InstantiationParameters(null, true));
    11. }
     
  9. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    Yes this seems to work fine, but in some cases I would prefer not to call LoadAssets if I'm going to instantiate them instantly since instantiate takes care of the loading too (if needed). It seems like the Assembly is missing one implementation for the InstantiateAll, which would be
    InstantiateAll<TObject>(IList<object> keys)
    the only version that has an IList is of type
    IList<IResourceLocation>
    which explains why this current approach works.

    Capture.PNG

    Also,
    Addressables.InstantiateAll<GameObject>("MyLabel", InstantiateCallback);
    works fine too.
     
  10. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    The "All"'s intention seems to be for use with one key that point to multiple locations, not "all" as in from multiple keys each pointing to one location. I think the main use case is probably for label since it is exactly one key to multiple locations. (Instantiate/LoadAsset also can found multiple locations from the key you give, but only use the first location for that key.)