Search Unity

How to load addressable group? (load several assets at once)

Discussion in 'Addressables' started by oxysofts, Nov 15, 2019.

  1. oxysofts

    oxysofts

    Joined:
    Dec 17, 2015
    Posts:
    124
    For example, if I would like to load all the fonts in my game on startup, how do I do this without individually loading each of them? The documentation states that we can load an asset group at once, and it seems there's a LoadAssets function (which I assume is what the docs refer to). However the function is templated so it looks like it can only load one type of asset......... Do I need to call LoadAssets twice with different generic typing? (e.g. Material, TextMeshProAsset, and some other type for TTF assets?) This seems like an absolutely critical feature which should be touched on in the docs.

    edit 1:
    It seems like the documentation is implying that I would instead use an AssetReference to asynchronously load my font when needed. I assume this will not incur a performance hit since it is loading in the background.

    However, doesn't that mean my text wouldn't appear until it's actually loaded while the rest of the game continues forth? If this is the case, the same will probably be true for all sorts of other assets in the game. It sounds like the game would become increasingly janky and amateurish looking as more and more of these assets appear to load in a delayed manner.

    And how on earth would I do this anyway considering that TextMeshPro doesn't use addressables anyway? Create a script solely for the purpose of loading the font and feeding it into TMP at runtime? That would ruin my ability to quickly iterate on the text's appearance in the editor in prefab mode, since the TMP component would have no font until runtime.

    edit 2:
    It seems the correct way to achieve this would be to create a label and provide
    [B]UnityEngine.Object[/B]
    as the type.

    However I still have all the questions raised in edit 1. In other words, what is the point of loading dynamically as the game is running instead of loading everything required in a loading screen prior?

    Even the demos seem confused on this: check out this demo component I stumbled upon. It's loading its own assets, but there's no mention of what would happen if the user managed to trigger
    SpawnAThing()
    before everything could load. Scenarios:

    • If the user is spending in-game cash to spawn that thing, this is pretty hilariously bad.
    • If this is simply a decorative such as a prefab with particles, then it will appear glitchy and amateurish when the particles don't spawn for the corresponding action in the game.
    So then, what is the point of loading assets on demand like that? Unless I'm misunderstanding, it seems like the Addressable API is going all in on this concept of 'on demand loading', when in reality this is actually not at all a desired behavior 99% of the time. I say this because the docs are making it seem as though migrating is simple, simply use AssetReference in place of direct references and load/react as needed, when in fact it can actually change how the game plays. NOT at all what I would expect most developers to want.
     
    Last edited: Nov 15, 2019
    tgrotte likes this.
  2. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Sorry for necroing, i don't want to open separate thread, and i see this isn't really answered.

    @oxysofts

    Did you figure it out in the end? If you have to load asset by asset it is quite a nonsense.

    This is all i found:

    Label - provides an additional addressable Asset identifier for run-time loading of similar items.
     
  3. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    for anyone looking to do this, i suggest using
    Code (CSharp):
    1. public AssetLabelReference assetLabel;
    2. private void Load()
    3.     {
    4.         Addressables.LoadAssetsAsync<GameObject>(assetLabel, LoadCallback).Completed += LoadingManager_Completed;
    5.     }
    and label the adderassables in the addressable groups window
     
    Last edited: Apr 15, 2020
  4. cihad_unity

    cihad_unity

    Joined:
    Dec 27, 2019
    Posts:
    35
    Loading with assets still doesn't make much sense.
    I want to have a list of addressables and load them one by one imperatively. That way I will have a full control over assets.

    I can create a for loop and load all of them one by one but I'm not sure if there is a performance cost of this. In every loop I request an asset from same group so there might be performance issue when it unpacks bundle and checks if it's in the cache.

    Code (CSharp):
    1.  
    2. foreach (AssetReference reference in references)
    3.         {
    4.             var handle = reference.LoadAssetAsync<Font>();
    5.  
    6.             while (!handle.IsDone)
    7.             {
    8.                 var status = handle.PercentComplete;
    9.                 Debug.Log(status);
    10.                 yield return null;
    11.             }
    12.  
    13.             yield return handle;
    14.        
    15.             if (handle.Status == AsyncOperationStatus.Succeeded) {
    16.                 Debug.Log("Font");
    17.                 Debug.Log(handle);
    18.                 text.font = handle.Result;
    19.             }
    20.             else
    21.             {
    22.                 Debug.Log(handle.Status);  
    23.             }
    24.         }
    25.  
     
    gooby429 likes this.
  5. SneakyFoxDev

    SneakyFoxDev

    Joined:
    Aug 3, 2017
    Posts:
    10
    Same here. I want to load an all files that I specified in a single group. How to arcieve this without using label/labels?

    For example, what if I have a ~50-100 groups and in each there is some amount of files 5~10 or maybe even 100. The count of files not so important, but an amount of groups are significantly important. So, for each group I must create a single label and load with it? This is an overkill, compared to the solution with one reference/link to a group.
    What about the way, where my app become larger, and I continiously add some new groups, as a content for players?

    So, Is there a ways to achieve this?
     
    Avalin likes this.
  6. novaVision

    novaVision

    Joined:
    Nov 9, 2014
    Posts:
    518
    Looking for the same answer. Wish to pre-download all the asset to keep it locally to avoid downloading when they will be requested. Can't find a way to solve it.
     
    Christian_Vertigo likes this.
  7. SneakyFoxDev

    SneakyFoxDev

    Joined:
    Aug 3, 2017
    Posts:
    10
    You can predownload assets locally from remote:
    1. At First asset download it will cache all files to device, and will not redownload when you try to load it again ( another run of your app), asset will be loaded directly from cache. (until second situation happens)
    2. If you updated your assets (Updated a previous build), it is another situation. Addressables will check all differences of local version and remote, and only download/redownload files that changed or added.

    Another case, that I stuck into it is an issue, where without remote connection where you can't get hash/data file (as I understand), you can't get any local cached files, and it is look very weird at this scenario.

    I would like to get a sufficient answer of this issue from Unity Technologies, and also about case for which this thread was created.

    Will be hope someone answer soon, and shed light on these questions
     
  8. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,821
    I'll raise this with the team - be in touch (or they will :))
     
    SneakyFoxDev likes this.
  9. oliviergc

    oliviergc

    Unity Technologies

    Joined:
    Dec 19, 2019
    Posts:
    26
    Hey everyone.

    There were talks in the past about implicitly creating a label with the group name in order to be able to load all assets from a group at once, but it seems these talks never materialized.

    The reason why is because you can kind of acheive the same results by using an Addressable folder. You can mark a folder as Addressables, in which you can put an arbitrary number of assets in it. A RuntimeKey will be created implicitly in the catalog for each asset in that folder.

    You can then put this addressable folder inside a group and you only have to set a single label : it will then be applied to every underlying assets within this folder.
     
  10. oliviergc

    oliviergc

    Unity Technologies

    Joined:
    Dec 19, 2019
    Posts:
    26
    @SneakyFoxDev You can't load arbitrary files from the cache, only bundles and only through UnityWebRequest. You can however check if a bundle is in the cache by using the Caching.IsVersionCached() API.

    If you have cached bundles, it means you have a local copy of the catalog (which may not be up-to-date but still) and you can get the bundle name/hash by using Addressables.LoadResourceLocationsAsync() and looking into the Dependencies property. Addressables should be able to load assets from a cached bundle even without a remote connection.

    Hopefully this answers your follow-up question.
     
  11. PixelLifetime

    PixelLifetime

    Joined:
    Mar 30, 2017
    Posts:
    90
    Feels more a like a workaround, so we have to destroy our project folder structure and move assets to folders to create a single load point? What are the technical complications of loading all assets in a group? (including `Type` of asset would also be beneficial).

    Something like:
    Addressables.LoadGroup(string groupName/int hash)

    AddressablesGroup group; group.GetLocations();


    Then with this we could have locations of assets in a group. This is super useful for many things.

    End goal: Get all locations/addressable names of a certain group. [Loading by label is not an option, assets in a group can have different labels.]
    How to achieve this right now?

    Related - https://gamedev.stackexchange.com/questions/194314/how-to-convert-resources-loadall-to-addressables .
     
  12. PixelLifetime

    PixelLifetime

    Joined:
    Mar 30, 2017
    Posts:
    90
    A somewhat manageable approach would be to write an automatic label set for specific groups. https://docs.unity3d.com/Packages/c....AddressableAssets.AddressableAssetGroup.html

    If you follow some convention that each of your groups have unique label for it.

    I can only understand this if you don't actually have internal grouping of assets when they are in bundles at runtime. Then it makes sense that groups stuff are `Editor Only` and only are a tool to build bundles. If that is the case then my assumption that this approach with labels is the closest thing we can get right now.

    And of course as usual you can't access labels to add your own through code - https://stackoverflow.com/a/61404101/6603717

    Useful - https://titanwolf.org/Network/Articles/Article?AID=c9ccdf5f-19c9-412f-8f56-1267335dfe16#gsc.tab=0
     
    Last edited: Jul 13, 2021
  13. shivaprasad_unity

    shivaprasad_unity

    Joined:
    Mar 30, 2021
    Posts:
    19
    @oliviergc
    Ahh.. never had thought about adding whole folder as addressable.
    Good to know.
    But this require module based strict folder hierarchy that people usually don't follow. Most of the community is used to classifying assets based on type rather than what module(That can be loaded at once) they belong to.
     
  14. userq

    userq

    Joined:
    Jun 4, 2017
    Posts:
    40
    So in the end, what would be a solution for loading a group? I am talking here a group of addressables from different folders.
     
  15. LuGus-Jan

    LuGus-Jan

    Joined:
    Oct 3, 2016
    Posts:
    179
    No, this is currently still not possible. An Addressable Assets group is not a concept that exists outside of the editor. Assets are packed together based on the group settings, and depending on that, an asset bundle may accidently coincide with a group as it exists in editor, but there's also no straightforward way to get which assets belong to which asset bundle.

    If you require the loading of all assets from a specific Addressable Assets group, it would still be easiest to assign a specific label to each asset inside that group, and load it through the use of the label.
     
  16. userq

    userq

    Joined:
    Jun 4, 2017
    Posts:
    40
    @LuGus-Jan , thank you for the answer. I was in the impression that the group actually would produce an asset bundle in the end and that requesting to load an asset from that group would load the whole bundle (talking on-demand assets here). Or am I mistaken?
     
  17. LuGus-Jan

    LuGus-Jan

    Joined:
    Oct 3, 2016
    Posts:
    179
    Depends on the group's settings. The 'Bundle Mode' setting (in the Advanced Settings section of the group) defines whether assets in the group are actually packed together in a single asset bundle, but you can also define to have a separate bundle per asset entry in the group, or group them per label.

    Regarding the loading of the whole bundle when requesting an asset from the group also depends on several settings as far as I understand. The type of compression, for example, as an effect on that. LZ4 and uncompressed allow the system to just read the file headers and extract the necessary assets from it. Having it set to LZMA will require it to be placed fully in memory and decompress it before it can access content.
    It is probably influenced by other parameters as well, and whether or not your asset has implicit references that are found in other Addressable Asset groups or not.
     
  18. SavedByZero

    SavedByZero

    Joined:
    May 23, 2013
    Posts:
    124
    So what's being said here is that if I have a web comic engine and put my assets and script file into an Addressable Group, there's no way to load and unload all of them by group beyond a couple of awkward workarounds? I thought the entire point of groups was for this kind of thing?
     
  19. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    is there a way to reference a folder via an AssetReference and then load all of its assets at runtime?
    I mean, it shouldn't be that hard to implement.
    Case and point:
    - I have a directory with N txt files for localization
    - I want to load all of them at once for some processing, at runtime.
    - I'd like to reference the directory only, and then magically load them at runtime, or at least get their addresses and load them myself.

    Currently, I have to serialize an AssetReference[] directly, which is a pain.
    Please spare me from the "label" solution. That's an ugly hack for such a simple problem.


    Edit: ha, I cannot even drag them all on the inspector as you usually can with a list of assets. What a misfortune. I literally have to use Resources just to be able to ship faster.
     
    Last edited: Mar 21, 2023
    ABCptt and v_whitepot like this.
  20. v_whitepot

    v_whitepot

    Joined:
    Sep 2, 2020
    Posts:
    2
    Addressable Asset Groups have the option of being 'packed together', compressed, having their own build/load paths set - but they're not really groups? If this is the case then how it is communicated to the end user requires an overhaul.

    I have a number of remote 'levels' to download (the assets for which - prefab gameobjects, videos, sounds, materials, etc. - I've grouped into different 'Addressables Groups' in editor).

    For each of these levels (Addressable Groups), I'd like to pull out and instantiate an 'Unpacker' MonoBehaviour from the Addressable Bundle once I've cached/downloaded the bundle contents. Levle001 will have an 'Unpacker', Level002 will have an 'Unpacker', etc.

    My ideal workflow: Explicitly download the contents of the 'Level001' parent addressable group and instantiate its 'Unpacker' asset. Is this simply not possible without explicitly naming it Level001_Unpacker, since there's no way for me *just* to load in the Level001 Addressables Group on its own?
     
    Last edited: Apr 20, 2023
    sinedsem likes this.