Search Unity

Handling multiple Addressables with the same key but different paths...

Discussion in 'Addressables' started by wheee09, Jan 15, 2019.

  1. wheee09

    wheee09

    Joined:
    May 21, 2018
    Posts:
    68
    So, it's not clear if we're allowed to have multiple Addressable Assets with the same key but different paths.

    Right now, if I have multiple AssetGroups with different Assets with the same key, it's rather difficult to get the right Asset provided the key. In fact, it looks like it'll get the first one which is a bit arbitrary.

    It seems we should either:
    1. prevent the same key from being used twice in the Editor
    2. make it easier to load an asset by the location string

    For #2, I'm trying to load an AssetGroup and iterate over the AssetEntries within - but I still haven't figured out how to create an IResourceLocation out of a location string given an AssetEntry... which would allow me to LoadAsset<IResourceLocation> the right one.
     
  2. itthereforeim

    itthereforeim

    Joined:
    Apr 28, 2014
    Posts:
    24
    var location = IAsyncOperation.Context.ToString();
    Is this what you need in #2?
     
  3. wheee09

    wheee09

    Joined:
    May 21, 2018
    Posts:
    68
    @itthereforeim I don't think so. That code snippet looks like it'll return me a string location.

    For #2, I already have the location string (ie. Asset Path) but there are no Addressables.Load* methods that take in the location string. The closest thing is one that takes in an IResourceLocation but generating the IResourceLocation seems to be rather convoluted, at least to me.
     
  4. itthereforeim

    itthereforeim

    Joined:
    Apr 28, 2014
    Posts:
    24
    Did you mean that you wanna load the asset by this kind of key value?
    Key1: "Chapter1/MyPrefabName"
    Key2: "Chapter2/MyPrefabName"
    And use Addressables API like this>
    Addressables.LoadAsset<GameObject>("MyPrefabName", "Chapter2");

    If so, it can be done right now.
    Just drag Folder into AAS and rename it.
    It will detetect all files and list them in the AAS.
    For example:
    You may have a folder like this: Assets/Content/Chapter1/
    And you can now, drag it into AAS, and rename it as "Chapter1".
    And add your new Prefab "MyCube" into this folder.
    It will automaticlly appear in the Addressables window.
    And now, you can load it by this Key value:
    "Chapter1/MyCube"

    For now, you can do some magic API by yourself
    MyLoadAsset<GameObject>("MyCube", "Chapter1");
     
  5. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    three notes:
    One, you can load all assets or all locations that match a given key. so you could do LoadAssets<IResourceLocation>("multiKey") and get a List<> of the locations matching that key. How you could look at those locations and work out which one you wanted is another matter. most likely that's impossible.
    Two, you can use more than one key, to fine tune your results. This ties in to why we allow multiple keys to exist. For example, you might have a prefab with the address "HighwayBillboard". You then realize you need a version for your game in Japan. So you give the current one the label "English" and make a new one, with address "HighwayBillboard" and label "Japanese". Now at runtime you can do something like:

    Code (CSharp):
    1.  
    2.         Addressables.LoadAssets<GameObject>(new List<object> { "HighwayBillboard", this.currentLanguageString}, null, Addressables.MergeMode.Intersection);
    Three, there isn't currently a way to iterate over a group. To do it manually, you could give everything in the group a label. More realistic (but sadly difficult with our current architecture) would be to create a GroupSchema that takes a string as a setting, and applies that as a label to all assets during build. The ability to extend the build like this is there now, but is something on our list to make much more straightforward in the future.
     
    MNNoxMortem likes this.
  6. wheee09

    wheee09

    Joined:
    May 21, 2018
    Posts:
    68
    Thanks @unity_bill - that clears up things for myself.

    To summarize, the recommended practice if I understand this correctly is to allow for duplicate keys and use labels to differentiate in conjunction with LoadAssets + Intersection merge mode.

    @itthereforeim that's a cool trick, never realized that I could add the folder as an addressable - it's a bit odd since I have to open up the parent folder and select the individual folders to check the addressable checkbox. I will play around with that and what Bill said to come up with something that works for me. Thanks!
     
  7. itthereforeim

    itthereforeim

    Joined:
    Apr 28, 2014
    Posts:
    24
    The folder trick did not works fine in 053 version, you have to repoen Addressables window for refresh content.
    I am using 048 in my work, it works fine for me, I wroted an auto fix code for Schema problem in 048.:)
     
  8. javierfed

    javierfed

    Joined:
    Apr 10, 2015
    Posts:
    50
    hey, so I am confused when I look at these threads about the addressables, because when I see the addressables window, I don't see a place to define "key" I see the address (set in the asset itself when made addressable), and a label. nothing labeled "key" yet I see it thrown around in these threads all the time. I am attempting to load all assets who are in a folder. the folder has an address and no label. do I have to give it a label to start loading things from it? I thought I only needed the address.
     
  9. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Any news on how to query groups?
     
  10. DumoeDss

    DumoeDss

    Joined:
    Feb 6, 2017
    Posts:
    7
    Can I use scripts to automatically create labels by group name or other rules? I didn't find an API like that.
     
  11. jyves69

    jyves69

    Joined:
    Jan 3, 2014
    Posts:
    9
    I have the same use case as wheee09, I tried your trick using the label like this:

    Code (CSharp):
    1. _loadingHandle = Addressables.LoadAssetsAsync<T>(new List<object> { _assetAddress, "default" }, null, Addressables.MergeMode.Intersection);
    2.  
    My _assetAddress is a runtimeKey (the hash of the addressable) and I tagged the assets I wanted with the "default" tag (or any other tag I tried for that matter) but no success. All I have is a :

    Code (CSharp):
    1. Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation`1[System.Collections.Generic.IList`1[UnityEngine.GameObject]], result='', status='Failed': Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=System.Collections.Generic.List`1[System.Object]
    2. UnityEngine.AddressableAssets.Addressables:LoadAssetsAsync(IList`1, Action`1, MergeMode)
    But when I use the exact same code without the "default" label:

    Code (CSharp):
    1. _loadingHandle = Addressables.LoadAssetsAsync<T>(new List<object> { _assetAddress }, null, Addressables.MergeMode.Intersection);
    My assets are properly loaded.

    Could you provide us with a little bit more info on how to achieve it @unity_bill ?

    See attachment for my addressable setup :)

    Thank you very much!

    EDIT: after testing if I use only the tag like this:
    Code (CSharp):
    1. _loadingHandle = Addressables.LoadAssetsAsync<T>(new List<object> { "default" }, null, Addressables.MergeMode.Intersection);
    2.  
    The asset is found. I don't really understand why the mergedMode intersection with both key doesn't work.
     

    Attached Files:

    Last edited: Jan 23, 2020
  12. JmprDev

    JmprDev

    Joined:
    Apr 26, 2018
    Posts:
    16
    @unity_bill I'm having the same issue as @jyves69. If I to use
    Code (CSharp):
    1. Addressables.LoadAssetsAsync<IResourceLocation>(new List<object>() { "label1", "label2" }, null, mergeMode);
    It always returns an error . This is also true for DownloadDependenciesAsync()
    Code (CSharp):
    1. Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation`1[System.Collections.Generic.IList`1[UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation]], result='', status='Failed': Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=System.Collections.Generic.List`1[System.Object], Type=UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation
     
  13. JHGameDev

    JHGameDev

    Joined:
    Jul 16, 2020
    Posts:
    1

    I try to use this but it is deprecated now, what should I use instead?