Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Non async version

Discussion in 'Addressables' started by pointcache, Feb 11, 2019.

  1. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    508
    Is there a non async version?
    This code from samples :

    Code (CSharp):
    1.     public List<AssetReference> shapes;
    2.  
    3.     bool m_IsReady = false;
    4.     int m_ToLoadCount;
    5.  
    6.     int currentIndex = 0;
    7.     // Use this for initialization
    8.     void Start ()
    9.     {
    10.         m_ToLoadCount = shapes.Count;
    11.         foreach (var shape in shapes)
    12.         {
    13.             shape.LoadAsset<GameObject>().Completed += OnShapeLoaded;
    14.         }
    15.     }
    16.  
    17.     void OnShapeLoaded(IAsyncOperation<GameObject> obj)
    18.     {
    19.         m_ToLoadCount--;
    20.         if (m_ToLoadCount <= 0)
    21.             m_IsReady = true;
    22.     }
    23.  
    What if i don't plan to use cdn, is there a way to load the resources synchronously?


    Ok from what i gathered , sync was not implemented, but its planned, meaning it's at least half year away. Also system lacks commonly used methods of query.
    So what i'd do for now is mock adressable system myself with labels and such to use resources, and then swap when it's ready.
     
    Last edited: Feb 11, 2019
  2. tomekswk

    tomekswk

    Joined:
    Jun 11, 2015
    Posts:
    5
    Shouldn't really matter whether the asset is local or remote - why would you want to freeze your game while loading assets?
     
    RecursiveFrog likes this.
  3. Overing

    Overing

    Joined:
    Mar 1, 2015
    Posts:
    1
    Maybe you can try...

    Code (CSharp):
    1. public List<AssetReference> shapes;
    2. bool m_IsReady = false;
    3.  
    4. IEnumerator Start ()
    5. {
    6.     foreach (var shape in shapes)
    7.     {
    8.         yield return shape.LoadAsset<GameObject>();
    9.     }
    10.     m_IsReady = true;
    11. }
     
  4. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    508
    I need all dependencies to be preloaded. Im not doing coroutine mumbo jumbo for something so simple.
     
  5. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    453
    If you need everything preloaded, why do you want to use addressables?
     
    RecursiveFrog likes this.
  6. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    508
    It speeds up editor play times, it acts as a database, etc etc there are many benefits to it apart from downloading assets. The system solves many problems with bundles and management, but it seems the main selling point is aimed at mobile/browser developers so im met with confusion when i want to do things the standalone/desktop way.
     
  7. BinaryEclipse

    BinaryEclipse

    Joined:
    Sep 1, 2016
    Posts:
    20
    I just integrated it into my pooling system. So the pooling system creates the instances to be made readily available for getting instances non-async. And because addressables give it to you async, you can create more instances of a certain asset when you are running low, and you can do so without affecting performance. So the rest of you application can just get instances as though they were being instantiated.
     
    RecursiveFrog likes this.
  8. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    508
    So asset loading and instantiation are async? I was under impression that instantiation would behave in the same way it did before, with async part being initial asset load into memory.
     
  9. jonagill_ag

    jonagill_ag

    Joined:
    Jun 21, 2017
    Posts:
    24
    If you plan on everything to be loaded at once, then you can load all of your assets from addressables during a loading scene using LoadAsset, then instantiate them at runtime by using the standard, synchronous instantiation code to clone the loaded assets.
     
  10. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    508
    Ill just wait til sync is officially supported.
     
  11. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    Oh boy, have I got news for you...! :-/
     
  12. BinaryEclipse

    BinaryEclipse

    Joined:
    Sep 1, 2016
    Posts:
    20
    I'm talking about "Addressables.Instantiate"
     
  13. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    If the asset is loaded already, this will instantiate and call its callback synchronously.
     
  14. BinaryEclipse

    BinaryEclipse

    Joined:
    Sep 1, 2016
    Posts:
    20
    but the function returns an IAsyncOperation
     
  15. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    A completed one, if I remember rightly. Do check.
     
  16. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,535
    Why would I want to waste cpu and gpu running my game, when what I want to happen is load the thing I asked as fast as possible?
     
    Last edited: Mar 5, 2019
  17. taylank

    taylank

    Joined:
    Nov 3, 2012
    Posts:
    69
    I personally find "why would you want X anyways" kind of comments very unhelpful and annoying, to say the least. We are all developers here and we have our reasons. Not everybody has to build in your preferred style, not every project gives us a choice. Async operations add an extra layer of complexity that in some cases is completely unnecessary.

    Do you stand to benefit from async operations? Fantastic, you're already covered. Now please stop trying to invalidate people asking to get their needs covered too.
     
    jchoi-ludia, zhuxianzhi and AcidArrow like this.
  18. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    Agreed, this sort of thing is what makes StackOverflow rather an unpleasant place to be. In this particular case you need to understand why the decision was made to make the API what it is. The idea is that making a game load off a remote location should not require different code by default, hence why loading is async.

    Anyhow, in the mean time, there are ways around it if you absolutely need instantiation to be synchronous, you can LoadAsset in advance and then instantiate manually using the regular instantiation APIs, although that'll lose you the reference counting.

    I'm under the impression that if a resource is already available the load operation returns synchronously but I'm not currently on a machine with our Unity project to verify that.
     
  19. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,535
    If I should load it in advance (meaning before I know If I need it), I might as well have it in the scene, or as an inspector reference.
     
  20. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    No. As soon as your data dictates that an item is required, load it asynchronously and then have it available for synchronous instantiation.

    If you do not know at all whether you need it or not or whether it’s loaded or whether it’s available, how could you have it available to you synchronously? With or without addressables it will need the asset bundle to be loaded and even if that is available offline it can potentially take time to decompress etc. In other words, if you need something available synchronously without a stutter, you have to preload it at some point, with or without addressables.
     
    BinaryEclipse likes this.
  21. taylank

    taylank

    Joined:
    Nov 3, 2012
    Posts:
    69
    That beats the point of Addressables having any memory management benefit at all. Say I have fifty abilities the player can use at any time, defined as ScriptableObjects, each of them with a reference to a prefab that would be instantiated when the player chooses to use that ability. You're saying because my data references 50 different prefabs, I should load them all async and have them ready for instantiation? Why, I might as well just LoadAll when the scene loads and be done with it, no Addressable system necessary!

    To me the main benefit of Addressables is being able to load references to resources without actually loading up the object itself into memory, thus having a handle to my data to use when and only when I actually need it. Having this system async only for local resources complicates issues in cases where there is a certain initialization order that you have to maintain. If you're using a dependency injection framework with inter-dependency resolution at start-up, introducing async loading to that increases code complexity an order of magnitude, for absolutely zero functional gain.
     
    Kirsche likes this.
  22. taylank

    taylank

    Joined:
    Nov 3, 2012
    Posts:
    69
    Yeah I disagree with that idea. A game loading resources from a remote location is very obviously doing something more complicated than a game using local resources only. Why should my local project workflow bear that complexity cost for other people's remote loading projects? It's like saying scuba diving should not require different gear than swimming, and then mandating all swimmers wear scuba gear whether they plan to dive or not.
     
    Kirsche and AcidArrow like this.
  23. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    440
    There's a whole lot in this thread, apologies if I'm missing something when I comment...

    agreed.

    Not sure where you got that, as that is not planned.

    However, I will point out that the AssetReference class does keep up with it's loaded asset. So once the loading is done, you can call the sync Instantiate(shape.Asset); You do still need to make sure you wait for the loading to happen, but at least once it's done, you can be sync.

    As to how you wait, honestly the snippet you showed to start is probably best. I would definitely not do
    Code (CSharp):
    1. foreach(){ yield return...}
    . The problem with that is that it'll only load one thing per frame. Which goes against the main idea of async being capable of starting a bunch of things at once.
     
    hippocoder, MNNoxMortem and Overing like this.
  24. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    I am not really disagreeing with you, you are right. However, based on the very description of the addressables system, it does note seem to be a good match for your use case.

    The premise of it is to unify local and remote loading and "asynchronous" is literally on the description of the package.

    OTOH, even if it is not a direct match, I wonder if you could write a version of AssetBundleProvider that loads synchronously and then wrap the public API in a synchronous set of methods.
     
  25. taylank

    taylank

    Joined:
    Nov 3, 2012
    Posts:
    69
    It is baffling to me that remote loading is accommodated to such extent, as I can't imagine there being more Unity users dealing with remote servers than local. Then again I don't work at Unity, so maybe I'm wrong.

    In the meantime I already have my home-brew addressable system, with the limitation that it only works for assets in Resources folder. I was excited about Addressables when it was first announced as an out of the box, comprehensive system, and have been a bit disappointed so far to see I won't be switching anytime soon.
     
  26. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,535
    @unity_bill thanks for the reply.

    So here is my perspective. After being told to move away from the Resources folder, we’ve been looking for ways to do so. (Even though, to date, I haven’t seen any actual compelling evidence of why the Resources folder is bad)

    Asset Bundles seem like something that is intended for remote loading, that incidentally happens to also work locally, and also adds a lot more complication to our workflow. So we’ve given up on them.

    So I took an interest in Addressables, and I’m sad to hear that simplicity is compromised once more because of things having to work remotely.

    If this is a system that is supposed to make people move away from the Resources folder, it seems like it missed the mark. I don’t think we’ll ever move to it unless we have no other choice.

    But maybe replacing the Resources folder was never the intent, which of course is more than fine, I’m sure there are plenty of people that are ecstatic about the whole local/remote thing.

    I’m just offering my perspective.
     
    SugoiDev likes this.
  27. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    117
    Sufficiently small games developed and distributed in open platforms, on powerful machines, probably can get away with using Resources folders. However, you become boxed in quickly when you rely on them exclusively, and if you start a project relying on them then decide later to migrate away, you are in a world of pain. Having been there before, a system that scales from day one and involves minimal hassle, is a blessing.

    The reasons to not use Resources honestly may not apply to you right now. But they may some day, if your ambitions grow.

    • Are you going to release a game on a console, and need to have small patch sizes?
    • Are you working with massive quantities of assets that you don't want to re-build into the application every time you need to test the game?
    • Do you have to keep your game's file size small enough that you can avoid the abomination known as "Multiple APKs" for an Android game?
    • Do you want to avoid long startup times? Large numbers of files in Resources mean that the game takes extra time indexing every file on startup, meaning that many small files actually slow down startup longer than a few large ones. That's in addition to the size of the first scene to load on startup.
    • Do you need your base game to have a small memory footprint so that you can load and unload expensive assets at will? Or worse, must your game's base engine be so small that there's no room in memory for a bloated binary that you'll get with large numbers of resources?
    Some of these might be doable with a synchronous API across all platforms. Some of them can only be synchronous in some platforms but not others. Any unified API will have to be able to work with every supported platform, and there are some popular platforms out there that require Async for a game of even moderate scale. You can take that up with the platform owners, but there's really nothing Unity can do about that other than play by their rules.
     
  28. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,535
    I develop for mobile.

    Startup times seem unaffected by the Resources folder. (Although admittedly maybe our Resources folder usage is sensible?)

    And the difference in memory usage was negligible.

    Also IMO, having an Android game instantly start downloading stuff after I have already downloaded it is the worst thing ever. As a user it means I immediately close and uninstall, so I can’t imagine why I would do it as a developer.
     
  29. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    That's interesting. I have had rather the opposite experience, where resources folder use increased our launch times quite a bit. It does very much depend how much data is in there though.

    Using asset bundles doesn't necessarily mean that the game needs to not have any of its assets bundled with it. For example, we bundle everything needed to get at least through the tutorial with the app in local bundles. Those local bundles can still be updated/replaced with remote bundles if needed. Huge monolithic downloads post-install is a massive turn-off for me too.

    Also, while this is not currently supported by the addressables system and I have never actually done it, asset bundles are also used for app thinning on iOS, where the App Store only bundles the resources appropriate to the device the app is being installed on.
     
    unity_bill, MNNoxMortem and AcidArrow like this.
  30. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    117
    Yes, I also would rather simply download the game and just have it. I miss the days where you just buy a game and play it.

    What I mean about Android is the concept of APK splitting which is required by Google Play for apps over 50MB.

    While Google tries to hide what’s happening from the user, you still have to implement a content downloader of your own in case Google Play fails to deliver all the APKs. And of course the hassle involved in testing an app like this, where you have to upload your secondary APKs to Google Play seems needless.
     
  31. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,081
    I have tried this and there are a lot of problems than I thought. You could read if you want to challenge it. (Hint : not as simple as replacing with AssetBundle.LoadFromFile and return completed IAsync and pretend that you could .Result right away)

    https://forum.unity.com/threads/why-are-there-no-synchronously-loadasset-apis.539946/#post-4273024

    Along the way I understand more why UT choose async only. It's more than asset, and it is not just dependency chaining. It is async all the way from the catalog system. Async is a superset of sync and that's good that the API was made to cover. What Unity really need is something like UniRx.Async (or better) where you avoid callback hell with a bunch of yield points in a custom player loop. You just wait then continue from the same point thanks to async context capture. If that's possible then there is no problem with async only. You only feel the friction because you need that invisible hand iterating the coroutine and that is not given by default. (Or default if you do it from IEnumerator Start, but still not fluent enough) And when you need one, you need some game object to "host" it.

    It seems to have opposite effect than you described to my multiple friends who plays gacha-game/troop management game. I observe that they are very willing to wait for the 500MB-1GB voice acting and graphic resource to load while seeing the game's title graphic and maybe some music. (Some game let you play tutorials first, so you don't want to quit)

    But when I said to try this good game with download size 1.5GB they say maybe later and not coming back to it again. They must have tested that this onboarding is psychologically better, at least the game's icon is already on the home screen. If the space is insufficient (happen a lot more than I thought) for stores it is gated by OS's popup and is difficult to come back this deep in the store after you do bother to clear up the phone. For game icon on your home screen, retrying is easier and more inviting.
     
    AcidArrow and Overing like this.
  32. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    462
    Yeah, what I am suggesting would only work properly if you could guarantee that everything is available synchronously already, that the catalogues have already been loaded etc. which is why I was arguing that I cannot think of a nice API to expose both sync and async loading for this system that would be properly orthogonal and not confusing.

    I might take you up on the challenge and try it myself too if I get the time, just to familiarise myself with the internals better, I don't doubt for a second that you are right.
     
  33. PNordlund

    PNordlund

    Joined:
    Nov 20, 2013
    Posts:
    46
    The fact that you can't instantiate a local (or already loaded) asset synchronously is a blocker for using the addressable assets system. I can't imagine why that isn't supported.

    So, what are the best alternatives to the addressable assets system?
     
  34. jonagill_ag

    jonagill_ag

    Joined:
    Jun 21, 2017
    Posts:
    24
    Let Addressables handle the hard part of preloading all of the assets you want synchronously available, and then instantiate them them manually using traditional Instantiate() calls when you're ready to use them. A very simple wrapper class with an async function to pre-load an asset and a synchronous function to instantiate an already pre-loaded asset is all you would need to make this happen.
     
    5argon and RecursiveFrog like this.