Search Unity

Feedback Weird behaviours, bugs, and unclear information in the Addressables system

Discussion in 'Addressables' started by CanisLupus, Mar 27, 2020.

  1. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    [GIANT WALL(s) OF TEXT] Many Addressable things are not working correctly for us. The system downloads everything requested just fine from any location, which is great, but almost everything else doesn't seem right. Some look like bugs, others are strange (to me) design choices, and others are just hard to understand.

    We are using version 1.7.5 in Unity 2019.2.15f1.

    1. [Solved in v1.7.4] Opening the Addressables Groups takes a VERY LONG TIME if you have big assets like a 70MB audio file. So does sorting the list of groups by anything (name, path, label, etc) in that case. The window seems to load all addressable assets for a name/path/label sort, which seems weird. What about people with 2GB DLCs?

    2. GetDownloadSizeAsync always returns 0 for any addressable UNLESS it's an actual remote location. i.e. File paths on a storage (even if it's a network storage like a NAS) always return 0. Is this intended? Are there some requirements for using the method? We already use the actual packed bundles. The docs mention that cached assets will (understandably) return 0, but this happens even for the first download. I was hoping to use the size to understand if an addressable is already downloaded or not, but right now it's impossible locally (even if on a network storage like a NAS).

    3. Related to the above, are Addressables not ever cached if they are read from a file path (i.e. not http or https)? I'm asking just to be sure. When reading from a local network storage (NAS) the Addressables seem to always need to download (although the download size is 0, as seen in point 2), nevermind if the location is "Remote" or not ("Remote" is just a name, so I presume you actually internally check if it is an internet location or not to decide to cache). "Use Asset Bundle Cache" is enabled in the Group settings (we just have one Group).

    4. If you are using a certain Profile, for example "Development", and switch to another profile like "Production", the build/load paths will update correctly in the inspector, but running in the editor or in a build will still try to load them from the previous location if they were not rebuilt. A message that tells you to rebuild if the Play Mode Script is set to read the existing bundles would help. More importantly, if you've already built the addressables using BOTH profiles, Development and Production, why do neither play mode nor builds can see the profile change until the addressables are (uselessly) built again?

    5. The handle returned by DownloadDependenciesAsync has very big jumps in PercentComplete, and so do all other AsyncOperationHandles we've seen. Reading the 70MB file from our local NAS takes about 800ms in total, but the percent will be 0 until the very end, suddenly becoming 1. If reading from our internet server it takes about 17s and increases progressively from 0 all the way to about 0.45 and then jumps to 1 suddenly. In both cases we log the PercentComplete to a StringBuilder at an interval given by await Task.Delay(10). Why does this happen? Any solutions?

    Example, in this case reading from an Editor Hosting Service:
    6. In the beginning I didn't understand why a remote location was downloading instantly even when the folder was not there at all, then I understood the cache existed, but I couldn't find in the docs anything about its location (at least in the editor), and it was hard to find! After a few searches I know it's at "C:\Users\<username>\AppData\LocalLow\Unity\<company>_<app name>. Maybe this could be made clearer.

    7. Searching Google for Addressables-related docs (actually, all Unity docs) frequently returns links for old versions of the docs, leading to wasted time and, when unnoticed, wrong implementations or usage of obsolete methods. You may be able to request changes for the indexing of older pages by Google, or some SEO hocus pocus (I know very little about this!), but a giant red warning at the top of the old pages would be useful. ;)

    8. [Solved] I don't know how we would use a remote URL in the format https://domain.com/storage/[BuildTarget]?param=something because the bundle name goes at the end of the URL, but the parameters must come last for this to work. I posted about this here. Any ideas?

    9. While attempting to solve point 2 by trying to use a Hosting service I also found another problem. Addressable paths that contain accents like ã or ú fail to load on a Hosting service. For example:
    Code (CSharp):
    1. Exception encountered in operation Resource<IAssetBundleResource>(info.json_835c8fcc227d35ba7764540d21d9eb03.bundle): RemoteAssetBundleProvider unable to load from url http://192.168.1.70:54662/songs_assets/m%C3%BAsicas/info.json_835c8fcc227d35ba7764540d21d9eb03.bundle, result='HTTP/1.1 404 Not Found'.
    10. In this part of the docs there's a "please note" paragraph that seems related to the previous section "Initialization objects" and not "Customizing URL Evaluation". (I reported this in the docs page.)

    11. The "Addressables Event Viewer" window does nothing until you press Clear. The Record button also seems to make zero difference, turned on or off. "Send Profiler Events" is enabled (by the way, the name and tooltip for that option refer to the event viewer as the "Addressables Profiler").

    12. Why are catalogs so big and uncompressed? I have 33 addressables, packed separately, so 33 bundles, but the catalog is 154KB because it contains info about every single asset in the Resources folder (??), which is something that can't be updated (can it?). Why does a remote catalog need info about the Resources of the app? And compressed to deflated zip it could be 35KB. The catalog is something that users typically download each time they open the app. This behaviour can be changed but the catalog should still be checked frequently. It wastes mobile data and wastes our storage server traffic, which devs pay for every month.

    13. "Update a Previous Build" regenerates ALL addressables (new names) in the group if you add a new addressable to it and don't modify the older ones at all. This goes against the docs saying "Asset bundles that do not contain updated content are written using the same file names as those in the build selected for the update.". Are updates not applicable for new files? How would a game like Rocksmith, with weekly content, deal with this? After opening the bundles in a hex viewer, this seems to be caused by two IDs changing inside the bundle file, which causes the hash to change. What are these IDs? Why do they change if nothing changed?

    14. From what I've read, Addressables are built on top of Asset Bundles. Asset bundles created in a certain Unity version cannot be opened by an app built with an older version. Does this still apply to Addressables? In the case of Asset Bundles we worked around the problem by upgrading our game as normal but keeping a different project for Asset Bundles (think downloadable songs), forever stuck in time with the same Unity version, otherwise whenever we'd build asset bundles every user would have to be on the most recent game version to open them, and we want very old builds to work. If the versioning issue still happens with Addressables, is it possible to keep and build the remote Addressables on a different project, or does it have to be the same?

    Apologies for the loooong post. I'd appreciate ANY pointers you can give me!

    Cheers!
    Daniel

    UPDATE 1: I've since updated several points of my text, especially 2 and 4. I also added 9.
    UPDATE 2: Marked 8 as solved.
    UPDATE 3: Added 10.
    UPDATE 4: Added 11.
    UPDATE 5: Changed text on 1.
    UPDATE 6: Added 12.
    UPDATE 7: Marked 1 as solved (v1.7.4 solved it and 1.7.5 is now usable).
    UPDATE 8: Added 13. I understand Addressables less and less.
    UPDATE 9: Added 14.
     
    Last edited: Apr 3, 2020
    _creatio_ and KwahuNashoba like this.
  2. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    I think that something that is problematic is the way the system acts differently for filesystem paths and web URLs. Maybe this is configurable somehow, but this default seems strange and error-prone.

    Unless I got this wrong, it never seems to cache Addressables that are in the filesystem (point 3). While this would make sense in a way, it will cause reads from a NAS (which take time and use the network) to not be cached. Similarly, GetDownloadSizeAsync always reports that bundles in the filesystem need 0 bytes to download (point 2), which is frustrating since we can't test our code with local files as it always says they are fully downloaded even if we never called DownloadDependenciesAsync.

    If, to go around this, we use a Hosting Service, it then fails for special characters in the names of the bundles/folders (point 9).
     
    Last edited: Mar 30, 2020
  3. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Point 9 seems solvable if we edit line 209 in HttpHostingService.cs. Change
    Code (CSharp):
    1. var relativePath = c.Request.RawUrl.Substring(1);
    to
    Code (CSharp):
    1. var relativePath = c.Request.Url.LocalPath.Substring(1);
    The normal URL (not raw) seems to not escape the accents and so works. Of course, I don't know if there are consequences to changing this, if we think about other possible file names. It's working well for us, though.
     
  4. Lsh2019

    Lsh2019

    Joined:
    Feb 26, 2020
    Posts:
    2
    I got the same issue like point 9
    I found the same problem when using the UnityWebRequestAssetBundle.GetAssetBundle test,When change the suffix to ".txt" it work.
     
  5. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Hey, not sure if I understood. What was the suffix before? Did it have accented characters? If not it might be something else. :)
     
  6. Lsh2019

    Lsh2019

    Joined:
    Feb 26, 2020
    Posts:
    2
    Sorry,I got a mistake,it maybe my ISS suffix limit
     
  7. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    That's okay. :)

    In other news, added what I think is another bug. I'd really appreciate a reply from Unity people about all this, when they can.
     
  8. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
  9. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,822
    Thank you for compiling this detailed list, @CanisLupus! I'll forward this over to the team.
     
  10. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Hey @TreyK-47, thanks for the reply and forwarding this to the team.

    Discarding the bugs and strange behaviours, there's currently only 3 of these points that are really blocking us from using Addressables (we worked around the others, and some are just documentation issues): 12, 13, and 14.

    Is there any chance that someone from the team can talk about these? They are more like questions, and I want to understand how these things work, if they will be improved in some way, if they are like that by design, etc.
     
  11. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Thanks for the detailed feedback. I'll go through them one by one.

    1. fixed! huzzah
    2 & 3 - Do you actually ship a game with content on a network storage? Or is this a dev-only feature? It seems like a reasonable setup while dev'ing your game, but I've not heard of anyone doing this. Do you know if UnityWebRequest supports loading files from a network drive? If not, then there isn't a good way to support caching this because we don't have our own caching (yet). We just call UnityWebRequestAssetBundle and rely on the caching it provides. If UWR does support network drives, then I'd recommend you make a custom AssetBundleProvider. It should be straightforward to override that class, and set it as the provider on your groups. See "Advanced/Sync Addressables" sample in https://github.com/Unity-Technologies/Addressables-Sample for a reference. As to us doing this ourselves, it feels like a fairly uncommon usecase, and it makes me a little nervous adding string parsing that can identify a network share from the path. Not totally opposed to us supporting it, but if we did it'd be a ways down the road.
    4. To the warning part, yeah, we could likely detect that and warn you. I'll put in a ticket for that. As to why, well, all data is built into the catalog. and the catalog is created when addressbles are built. So really this is a problem for more than just the profile. You could change settings on your groups, rearrange content, mark or unmark items as addressble. Basically, you could change anything. Active profile is just one of the many things in the list of data that's relevant to the build output.
    5.
    a) we've had a few bugs in our % complete code, at least one that I know of us fixing post 1.7. So keep an eye out for fixes there.
    b) Could be there's an engine bug in AssetBundle.LoadFromFileAsync.progress that doesn't handle NAS properly. Might be worth adding some logging or breakpoints in AssetBundleProvider to see if the engine is properly reporting that progress.
    c) % complete is not a reflection of "progress through total time to load" (because how would we guess that) or "progress through total data downloaded" (because the ops do more than just download). For example, your first call into addressables will trigger our init, and chain itself to that op. So 50% of the completeness would be tied to our Init, and 50% to what you actually asked for (because the parent op has two children, init, and whatever you asked for). Of the 50% you cared about, that would also be broken up evenly among dependent ops. If you are downloading something, and want a more accurate reflection of the download, I'd recommend DownloadDependenciesAsync. Well, I'd recommend that to most users. Since you are hosting via a network path, this may not work without you modifying some things
    6. as already mentioned, we're just relying on the engine's built in caching, which is somewhat feature limited and not so greatly doc'd (not that our packages is either). You can learn more here https://docs.unity3d.com/ScriptReference/Caching.html, though I don't think it docs where to find the cache on-device for all the different platforms we support. I'll make a note that we should link to that from our docs.
    7. yes, that is a pain. We've given that feedback to the docs team as well. They did eventually add a big blue button that says "view latest version". Not exactly what we'd hope for, but it gets the job done I suppose. As I understand it that team is working on more improvements to the package doc setup.
    8. solved! victory!
    9. I'll make a ticket to explore your suggestion.
    10. thanks for letting us know.
    11. bugs! noted. thanks
    12. well. they have a lot of data. two fixes coming.
    a) we can't actually zip (the engine doesn't provide an unzip), but we can put the catalog in a compressed asset bundle of it's own. This is being added to 1.8.x as an optional feature.
    b) we currently add some data to catalogs that we could generate at runtime (like sub-asset addresses). Not sure if the improvements here will make the first 1.8 or not.
    13. not sure I totally understand the situation you are describing. Is it this: a group has N assets in it. Group is set to "pack separately" and "can update post release". As such, you end up with N bundles. You then add one asset to that group, and do "update a previous build". At which point you should have N unchanged bundles, and 1 new one. But you are saying you end up with N+1 new bundles? Please clarify.
    14. old players cannot open content built in a newer editor. But a new player can load content that's been built with an older editor. As to building content in one project while loading it in a player built elsewhere, yes, you can do that too. So if I understand your workaround, you'd start your dev, say on 2019.2, and build content and player from that version. Then you want a way to update your player to 19.3, but keep building content in 19.2 so that old players could load it. That right? If so, sounds like it'd work. use LoadContentCatalogAsync to load additional catalogs.

    hope this helps.
     
  12. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    @unity_bill I can't tell you how happy I am to get an answer to all of this. :D A big "thank you"!


    2 & 3. No, no. We will be shipping using internet-based remote storage, like everyone else. ;) Sorry that I wasn't clear on this. The NAS was highly convenient for development, since the whole team could access the same built addressables and it was quick enough to download while also taking a bit of time, allowing us to test downloads (or so I thought) without a remote storage or an always-on hosting computer.

    We are using your in-editor hosting solution now, though. By the way, thanks for implementing such a thing natively. After fixing the accents problem it works very well! We also use a separate program to forcefully slow down upload speeds from the Editor, so that we can test downloads slower. Not sure if you could do this natively in the hosting service as an option, but it's useful!

    Unfortunately I don't know about using UnityWebRequest for network drives, since we've only used it for http requests.

    I see, I thought you did something ESPECIALLY to detect file paths and disabled caching on them (since they are supposed to be fast), didn't think that the caching was a UWR thing. I completely understand if this doesn't make sense outside of a "NAS use case" (hence why I was "asking just to be sure").

    That said, GetDownloadSizeAsync gets confusing if it always returns 0 bytes for local files. I guess it won't make sense for you to change this, but a few improvements in the docs would be appreciated, like a note that explains the differences in caching/download size for local addressables.

    While I'm at it, is there a way to know the size of a non-remote or already cached addressable? Akin to GetDownloadSizeAsync? For example, if we want to tell the user how much space the downloaded songs are taking up.

    4. I see, thanks for explaining. In that case a warning in this case would help a great deal, especially for those starting to use addressables.

    5.
    a)
    Will do! ;)
    c) I expected the AsyncOperationHandle for a download to give a progress based on the size in bytes of the bundle(s). But maybe you can't know the size of the file(s) you are downloading...? Is that it? Or is this a UWR thing? Would a general solution to this be possible at all?

    I thought that the ~50% completion was strange, and guessed that the process was divided (maybe between bundle and dependencies), but from your explanation it seems a bit more complicated than that. Sadly this won't help showing download progress to our users, although it's not a critical problem in any way.

    You mentioned recommending us to use DownloadDependenciesAsync, but we are already using that (I mentioned it at the beginning of point 5). Not sure if you didn't notice or meant to say something else!

    6. Hmm the caching link seems interesting, thanks. I had no idea about that. A link and a small section about caching in the addressables docs would be helpful (like for 2 & 3). I realize you can't be repeating yourselves a lot throughout the docs but, from the standpoint of someone that is using Addressables precisely to AVOID having to deal with downloads manually, these hidden behaviours (from UWR or not) are unexpected. :)

    7. Great to hear! Yes, the blue button helps a bit, but it goes kind of unnoticed.

    9. Thanks!

    12.
    a)
    Awesome, that helps.
    b) I think most (or all) possible reductions of the catalog would be appreciated, or at least we would appreciate them! But why are all assets in the Resources folder in the Addressables catalog? That I could not understand. It uses up the large majority of the catalog's size, and will never be updated (I think?). Isn't this something that the app build already knows? We can convert Resources to Addressables already, if we wish. Maybe this is for something else, but...why?

    13. I think that's exactly it. I add a new asset to the group, leave everything else untouched, and update the previous build (using the bin file generated inside the project, which in any case I think is the same as the one deep in the Library). It regenerates all assets with different hashes. If I look inside the bundles with a hex viewer to see what caused the hash to change, I see that 2 IDs changed (random sequences of characters). I suppose this is not intended!

    I could change the naming behaviour to use the name only (instead of name + hash), but I fear that the internal change of the IDs is the source of the problem.

    I can *try* creating a small reproduction project at some point this week if you can't reproduce it. In our project it seemed to happen every time.

    14. Yes, that's it. Alright, thanks for confirming this. I'll take a look at LoadContentCatalogAsync when I can.


    Thank you very much for taking the time to respond to this behemoth post. :eek: This time it's mostly me replying to what you said, but I left a few questions marked in bold that are still not clear. If you have some time.

    Cheers!
    Daniel

    UPDATE: added a paragraph about editor hosting in 2 & 3.
     
    Last edited: Apr 6, 2020
  13. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    5.c. oh yeah, i forgot. The best case numbers you'll get will be if you are actually downloading (no network drive thing) and your op is not chained to the init (init is already done). assuming you are in that situation, we still end up with an average of all the ops. From your snippet it looks like we've put an extra op in, that represents 50% of the completion, but is just an op-holder (so finishes as soon as children finish). We'll look into that.
    as to your actual bold question... the key problem is that we average the ops. Say you had 10 bundles you were downloading. In that case, each would represent 10% of the total progress (well, maybe 5% if there's some other thing blocking half, but let's ignore that). If nine of those bundles were tiny, and one was huge, we'd have no way of knowing. We just know the progress of each op. We do not have a mechanism to give each op a weight.
    As I mentioned, we use UWR and the built in caching. Both of which somewhat restrict what we can do. Long term we'd like to write our own downloader and caching system. That would make solving this sort of thing much more straightforward.

    12. this is an option. In the group settings select the Player Data group and uncheck both "include..." options. That's just there to ease peoples conversion from Resources to Addressables. We've gone back and forth many times about if this should be checked by default. For now it is, but you can uncheck it to clear out the catalog info.

    13. if you can make a repro project, that'd help, but I'll go ahead and make a ticket in our backlog to look into it.

    -Bill
     
  14. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    5.c. Okay, I understand. Hard to improve this without your own system for downloads.

    12. You mean "Built In Data", right? It never occured to me to check in there. From videos I saw I was under the impression that you'd have to mark assets in the Resources folder as Addressable before you could use them, so this isn't what I expected from the default. But yeah, thank you very much. This takes the catalog down to to 55KB, which is great since it's a third of what it was. Zipped it could be 13KB. ;)

    13. Please let me know if this is reproducible on your end when you can.

    Just a last thing, from my last message: is there a way to know the size of a non-remote or already cached addressable? Akin to GetDownloadSizeAsync?
     
  15. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    @unity_bill Found another problem while creating a repro project.
    Thankfully, my first guess was the actual problem: the path is way too long for Windows. In my case it was:
    Renaming the project just to "Addressables bug" fixes it, but you might want to add a check for this in your code, so that the error explains the problem. I believe the Windows limit is 259 characters or so (plus a null terminating character).

    PS: Of course this happens because of long addressable names, but using the full relative path as the name is the default in the Addressables system, after all!
     
    Last edited: May 4, 2020
  16. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    @unity_bill About point 13, I submitted a bug report. It's case 1234854 (I'm actually jealous of whoever got case 1234567 :p). Please take a look when you guys can.
     
    Last edited: Apr 7, 2020
  17. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Sorry to reply again @unity_bill, I wanted to make sure that you saw the previous messages. A question (from before), a path length issue, and the report for point 13.
     
  18. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
  19. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Nooooo! This issue was marked "By Design"!

    @unity_bill You haven't returned to this thread again, but there has to be something wrong. The resolution note talks a lot about static content and "cannot change post release", but this is not the case for us. This happens for "Can Change Post Release" as well. My issue (1234854) was marked as a duplicate but in that case it isn't.

    This is a very important bug! We literally can't publish our game while this bug exists, otherwise the smallest update with a new file will cause ALL USERS to redownload ALL ADDRESSABLES they had previously.
     
    Prodigga likes this.
  20. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    And another thing... The previous 6 posts were all made by myself, despite tagging @unity_bill on almost all of them. The last time someone other than me replied was almost 2 months ago... How can I reach you people?

    I realize you and the team have a lot to do, and I understand that and thank you very much for the answers to all my previous questions, but then I just tried to get an answer to a question that was ignored in the last reply, and then I tried to help you (and me) by creating a reproduction project for a bug in your system, so I guess I was expecting some more interaction... (by the way, I also found the file path length problem above).

    By this time I don't know what to do. I'm replying to my bug report again, to see if it can stop being a "duplicate", and I'm also writing here. Do you want me to create a new thread for this? It risks getting flooded by the other threads...
     
    Last edited: May 25, 2020
    better_walk_away and Prodigga like this.
  21. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427