Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feedback Instant(synchronous) Load methods. In addition to Asynchronous ones.

Discussion in 'Addressables' started by TextusGames, Aug 9, 2019.

?

Do you need Addressables to have instant(synchronous) Load method?

  1. Yes

    82.2%
  2. No

    11.1%
  3. Wow, i thought it is already there.

    6.7%
  1. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    This asynchronous addressable asset system is not a straightforward replacement to the previous system it requires to make significant changes to previously synchronical code, there you can use things like Resource.Load("MyObject").DoSomethingImmediatly().

    Why do not you allow users to call load synchronously in some cases in order to support the old system without "Changing a line of" old "code"?

    Case 1: I know that the resource that is needed is included in the build.
    Case 2: I know that I will download that resource and it will be presented on a device.

    In the above cases, I just want to use a field of type "AssetReference" in order to access any resource at runtime,
    without the need a resource to be in the resource folder,
    without dependency on the resource name,
    with the ability to restrict type AssetReference<GameObject> Go,
    with the ability to serialize that field into JSON utility by asset GUID which is persistent in-between editor sessions and game sessions (in oppose to instance ID serialization of UnityEngine.Object which is not persistent and can not be used in save system),
    but still with the ability to access it synchronously.
    That AssetReference type gives so many benefits, but without the ability to synchronously call load I can not use it in old systems and new synchronous ones(.

    I just wanted to use AssetReference as a reference to an asset as the name implies but in synchronous context as I know what that asset is on my device!

    You should consider adding this functionality at least for supporting old systems (like resources load).

    Is this planned or already obsoleted?
     
    Gera1997, xucian, tarahugger and 2 others like this.
  2. kaimelis

    kaimelis

    Joined:
    Apr 28, 2016
    Posts:
    18
    It would be a really nice improvement. As I am now trying to shift the whole made project to addressable objects. Sometimes it takes so long to rewrite the whole code as it is assuming thing work instantly. But either way. Addressables are a nice thing just I think it needs documentation update.
     
  3. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Three comments.

    One, Addressables is intended to provide edit-side flexibility without requiring changes to code. If your code is synchronous, it restricts what you can do edit side.

    Two, we have provided a mostly-functional example project here https://github.com/Unity-Technologies/Addressables-Sample/tree/master/Advanced/Sync Addressables that you can use to create your own sync version of Addressables on top of our framework. The sample isn't perfect, or fully tested, but it should work well as something you could copy into your project, and adjust as needed.

    Three, we are looking into adding sync directly to the package. Of note, one of the purposes of the Sync Addressables demo linked above is to show how much error checking and potential exception throwing is needed to make this sync. What if you ask for something that requires a download? Exception. Sync addressables is something that would need to be used very carefully by someone that understood the constraints.
     
  4. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    Assets presented in build could be marked somehow as persistent. That will allow safely and synchronously call LoadPersistantAssetSynchronously that asset at runtime or even at editor time without many checkings. I hope you will add synchronous Loads at least for the case then assets are always in build, and this functionality may replace old ResourcesLoad approach.

    Anyway, Thank you for your fast and useful reply.
     
    unity_bill likes this.
  5. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    464
    It's majorly a design decision that as they advertise the system - a way to separate asset referencing and packaging. So your code always work if you starts with local assets and switch to remote assets later, vice versa. Introducing a sync load may block the main thread, hence break the design principle.

    And the API is encouraging the on-demand pattern, you invoke LoadXXXAsync on demand, it handle everything behind, downloading, loading, reference counting. Good for web game scenario, everything is loaded in a progressive way, like a web page.

    However like you point out the case 1 or 2, what if the major usage is the preload pattern? That everything should be downloaded before start a feature. I assume the pattern is more common for mobile, steam, console. In such case, download async + load sync API can be programmitc.

    My workaround is an AssetPreloader class that loads every assets required by feature x, and cache in memory. Then I just query the AssetPreloader for the assets needed. This works like sync load API and good for a few scenarios. You only deal with async API once in the AssetPreloader. This also avoid loading remote asset in sync load API by accident, it just impossible to happen.

    For other scenarios do need async API, I found await-async is way more easy to maintain.
     
  6. KB73

    KB73

    Joined:
    Feb 7, 2013
    Posts:
    234
    Hi Bill, any eta on this re: Sync functionality? The gitbhub sync examples don't appear to work for us , we tried them but always got the failed to sync load error no matter what we passed in. The item we had was local not remote etc

    * Nevermind, we bit the bullet and ported everything to async
    thnx
     
    Last edited: Oct 7, 2019
  7. ouyanglinxin

    ouyanglinxin

    Joined:
    Sep 25, 2019
    Posts:
    5
    Hi Bill, SyncBundleProvider can no longer be loaded asynchronously if SyncBundleProvider is selected in the official example project.This is too inflexible, later official will change the source code to support asynchronous and synchronous hybrid loading of an Asset
     
  8. StrongCube

    StrongCube

    Joined:
    Nov 22, 2016
    Posts:
    50
    Added sync loading to the dead Addressables asset? Or is it just as useless?
     
  9. tarahugger

    tarahugger

    Joined:
    Jul 18, 2014
    Posts:
    129
    This is what i had to do as well, download everything up front and index/cache it.

    The 75% of people casting votes for a sync version shows that there is a real and common need for the feature.

    There are many valuable improvements with addressables compared to using legacy bundles other than async. So a sync version would let people use those other features without heavily refactoring code.

    I hope Unity takes note that we feel this is important, and if they feel it shouldn't be important, to provide us with their reasons and some examples of how to work around the issues we're facing.
     
    Last edited: Apr 27, 2020
  10. MartinCoatsink

    MartinCoatsink

    Joined:
    Nov 13, 2019
    Posts:
    7
    At least in Addressables 1.8.3 there is an Addressables.Instantiate method, which I assume does things synchronously.

    However it's marked as [Obsolete]. Will it get removed at some point in the future?
     
  11. phobos2077

    phobos2077

    Joined:
    Feb 10, 2018
    Posts:
    350
    No, all those Obsolete methods are the same async methods just named badly (thus they've renamed them).

    On the subject I think there are different approaches to handle this:

    1. AssetPreloader or something similar as suggested above. Be aware that such solution won't scale (unless you manage different Preloaders and handle load/unload, but then you'd better of going with option #2). This is only useful for stuff that you really need to be loaded in the memory during the entire run time and it's not heavy (like configs).

    2. Implementing Sync interfaces yourself by writing custom providers and Sync versions of Load methods like suggested by Unity's examples. This is more scalable as It will use ResourceManager features like ref counting to track what's need to be unloaded etc. But you need to separate stuff that will be loaded synchronously (like local bundles) from other assets. If you really think about it, you will understand why Unity's still haven't implemented this in the base package. There are many edge cases and more than one way to deal with stuff.

    For example, you might request to download dependencies for an address asyncronously, and then use Sync API to load assets.

    Another reason to want sync API is performance. I've just stumbled upon a case where I needed to preload 1000 small assets from one bundle and it took quite some time. By replacing BundledAssetProvider with my own version (that uses sync API of AssetBundle class) I improved loading time of those 1000 assets 2x-5x times. This is a specific use case, but I think it demonstrates how sync API is useful if properly implemented, apart from giving easier migration path for existing projects and inexperienced coders.
     
  12. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97

    That assett DOES NOT work...

    https://gamedev.stackexchange.com/q...-achieve-synchronous-addressable-asset-loadin

    Could you just provide an API with a synchronus method that waits for the object to be loaded? It's a PAIN to work with coroutine that cannot return a value object...
     
  13. Awarisu

    Awarisu

    Joined:
    May 6, 2019
    Posts:
    215
    I'd like to add one thought (and brace for the incoming hatred, rebuttals, and whatnot): There are quite a lot of "traditional Unity bugs" that stem from developers doing something the seemingly easy but bad way. Doing too much work on the main thread is one of these. Providing a sync API would basically guarantee that most devs would just immediately jump on that and perpetuate these issues instead of being guided towards taking the time to do these correctly.
     
    ProtoTerminator likes this.
  14. inkletom

    inkletom

    Joined:
    Oct 13, 2016
    Posts:
    63
    Sync addressables seems like a glaring oversight for me. While it's true that not having it typically steers users towards the better approach, I'm not sure that async is always the best approach!
    When loading tiny assets, assets that can often be relied upon to be already loaded (especially in the case of spritesheets!), or simply hiding behind a loading screen (fine, not a great practice, but acceptable in a pinch) I often finding myself wishing for a simple one line "give me this asset", rather than having to write event handlers for each asset.
    The Sync example project doesn't work for me either.
     
    LeleUnity likes this.
  15. Awarisu

    Awarisu

    Joined:
    May 6, 2019
    Posts:
    215
    You don't have to write the event handlers yourself though, that's what
    await
    is for. Your code remains as simple as always, other than it now spanning more frames than one (that you can easily make work with your loading screen for instance, I hope that it waits for things to actually load) and the few associated ifs that you now need to add to, e.g. prevent starting a new loading process if one is already running. It's not even multithreaded so you don't have to worry about that part.

    Now that is of course, if Unity and Addressables actually worked. Case 1246117
     
  16. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97

    I can't Use Async Addressables.

    I have a structure where:
    Character1Holder---->LevelManager---->DataBaseManager
    Character2Holder----->LevelManager--->DataBase Manager

    The 2 charcter holders calls a method "give me character named X/Y and send a callback to me When loaded" respectively. So it will pass both the name of the desired charcter to be loaded and the reference of themselves to be called when the load is completed.

    The levelManager just passes the request to the DatabaseManager that base on the wanted prefab it will load it asynchronsly. Then, thanks to the reference to the Character1Holder it will register a call back method.
    This is the code of the method inside the DataBaseManager.

    Code (CSharp):
    1. AsyncOperationHandle<GameObject> CharacterHandle= Addressables.LoadAssetAsync<GameObject>("CharacterX");
    2.  
    3. CharacterHandle.Completed += CharacterXObjectReference.CharacterHasBeenLoadedCallBack;
    The problem is:
    What will happen IF this Charcter1 calls this method, and Charcter2 calls this method too before the
    Code (CSharp):
    1. Character1ObjectReference.CharacterHasBeenLoadedCallBack
    is triggered ?

    The variable CharacterHandle will be overriden with the data of Charcter2.
    This will delete the previous subscribtion to the event? or both triggers will be registered to the event of the loaded charcter1 ?
    What happens if I override the variable CharacterHandlebefore it is triggered?**
    The previous delegate is deleted and not notified anymore, or It will trigger twice?
    are they considered two different events?