Search Unity

Addressables is not grasp SpriteAtlas dependencies

Discussion in 'Addressables' started by rabbitbooster, Jul 18, 2019.

  1. rabbitbooster

    rabbitbooster

    Joined:
    Sep 23, 2017
    Posts:
    3
    Hello!
    Now I have problem When I include a Sprite and an Atlas in Addressables and build,
    In my think, only to include atlased texture in AssetBundle, But the real behavior also include unatlased texture.
    Is it supposed to work?
    Contents.png Size.png
     
  2. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    I'm not sure I see what you're saying. It looks like you've made Unity.png as addressable. Which adds the actual texture, and the sprite object to the bundle. You've also made "new sprite atlas" addressable, which adds the generated texture, and the atlas object data to the bundle.

    What is in the atlas? Unity.png or something else? If it's Unity.png you can't mark a sprite addressable and expect to load it out of an atlas. You have to just have the atlas as addressable. If Unity.png is not in the atlas, then I'm not exactly sure what you're asking.
     
  3. rabbitbooster

    rabbitbooster

    Joined:
    Sep 23, 2017
    Posts:
    3
    Sorry to my lack of Information.
    Atlas in only to include Unity.png and actual usage is resolve dependencies SpriteAssetReference.
    In my think that pattern only to include SpriteData(All Sprite data without Texture)but constract data is include Sprite TextureData.

    I'm not good at English so I put it together in the diagram
    usecase.png
    This is what I wanted to convey.
    If you don't know what I'm saying ,I will tell you in addition.
    Thank you for your support.
     
  4. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    If you have a sprite in the editor, and you mark it as addressable, and load it at runtime, it is it's own thing. It has no idea if you happened to also include it in a SpriteAtlas. Similarly, if you load a SpriteAtlas, and then get the sprite out of it (GetSprite or GetSprites, see https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlas.html) you'll get the sprite that's contained inside the SpriteAtlas, and it has no idea if you happened to have included the original source in the build.

    I've altered your drawing to match what actually happens. You have two things you can reference from code. They are independent. At runtime, a SpriteAtlas is not dependent on the source sprite. It sucked in all the info it needed during the build.

    usecase.png
     
  5. stefankohl

    stefankohl

    Joined:
    May 30, 2014
    Posts:
    53
    Supposed I have my entire GUI in an addressable scene and this scene refers sprites through the "Image" component. Furthermore, all sprites are included in an atlas that is addressable. At runtime, after loading the atlas, the GUI uses the atlas texture as expected. However, due to the scene refering a sprite that is a sub-asset of the sprite texture, the sprite texture has to be included in an asset group as well in order to satisfy the dependency.

    What is the best way to handle this situation when it comes to UGUI using sprites?
     
  6. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    517
    While this makes sense from an asset management level, this does not make sense from a Unity 2D workflow level. The sprites in the 2D workflow (whether for UGUI or 2D) use the sprite references when dragging references into the SpriteRenderer or UI.Image components. They never use the atlas that the sprite is built into. Expecting artists and designers to change up their workflow for addressables should not be an acceptable solution.

    This is a pretty big miss by the addressable team for not knowing this. Please consider adding an asset reference that will respect the sprite's atlased state so it knows how to load it and can accept Sprite references correctly.
     
    XiangAloha, won-gyu, oxysofts and 3 others like this.
  7. stefankohl

    stefankohl

    Joined:
    May 30, 2014
    Posts:
    53
    I wonder if there is anything on the roadmap to tackle this design flaw. If I understand it correctly, this is more related to Unity itself than AAS. As a solution, for example, a SpriteAtlas could generate sprites as sub-assets similar to single or multi sprite textures. When referring SpriteAtlas sub-assets only, the original sprite textures could be excluded from the asset bundle completely.

    I'm thinking of writing some kind of post-processing script that automatically resolves sprite references in all scenes by deleting them and attaching a component that loads the addressable sprites on scene start and then puts the reference back. I don't like this solution, but if nothing else is out there that retains both the 2D design workflow and sprite atlas generation, I will go with it.
     
  8. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Ok, I've done some additional digging just to make sure I can explain it as best I can.

    Assets contain objects.
    Unity's built in direct reference system is looking at the object level
    Addressable Assets is looking at the asset level.

    For example, the sprite asset on disk in your project actually has a texture asset and a sprite asset inside it. If your game has some prefab/ui/whatever that references a sprite, it's just referencing the sprite object. As such, that reference can be whatever to sprite to atlas.

    In Addressables, however, if you mark the asset as addressable, we don't know which object you want. We include all in the build. The sprite object, and the texture object. Because you might do Addressables.LoadAssetAsync<Texture2D>("whatever"); We have no way of knowing you don't want to be able to do that.


    So if your UI references a sprite that's in an atlas, as long as the sprite itself is not addressable, you should be fine. If you want a way in addressables to get to a sprite that's in an atlas, you need to mark the atlas as addressable, and use the atlas interface to pull the sprites from it.
     
    chrismarch likes this.
  9. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    517
    I understand what you're saying @unity_bill, but I don't think duplicating the texture data is an acceptable solution for mobile in particular. Mobile users constantly delete apps that are the largest on their devices when they need to clear up space. Doubling the size of these types of assets is not helping.

    If I'm understanding you're saying to do the following:

    Instead of doing the typical addressable way of marking the asset addressable and using a reference
    public AssetReferenceSprite mySprite;

    You're asking us to unmark the sprite assets as addressable and do something like this?
    public AssetReference<SpriteAtlas> mySpriteAtlas;
    public string mySpriteName;

    If this is correct, this is not an good workflow for 2D sprite assets. Not only do artists and designers not work with atlases in the typical 2D workflow, we're back to super fragile string references to assets. Addressables was supposed to be a solution here and use the asset database GUID to keep file moves/renames so that it doesn't fail finding the sprite at runtime.

    I'm surprised that this hasn't been brought up as a problem before now. I really feel that this is should work with the 2D team to see if there is anything that can be done to get around this flaw. Maybe we can mark the sprite sub asset as addressable instead of the parent texture asset in situations where we only want to link the sprite and not the texture information? The other thought is that you don't include texture information on textures imported as sprites if they are atlased. I'm sure that loading texture data for an atlas sprite should be rarer, and thus a better alternative than duplicating texture data. If there is still a need for having texture data, the user can duplicate the asset and load the non-atlased version. While not perfect, you're targeting the higher use case scenario rather than the all or virtually nothing approach you currently have with sprite sub-assets.
     
    Sylmerria likes this.
  10. kvfreedom

    kvfreedom

    Joined:
    Mar 30, 2015
    Posts:
    37
    So at present the best way is not to use Sprite Atlas. Use this ASTC compression format.
     
  11. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Agree with @Ferazel, this workflow is very weak.
    It's like if 2D team asks us to reference atlas and load sprite manually, it's not acceptable because mistakes and team work :confused:.
     
  12. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    I agree.
    also agree.


    We are working on a solution. Historically SpriteAtlas and AssetBundle systems have not played great together (and addressables is built on asset bundles). Our goal is to create something to mask that from you, but we haven't completed it yet. It's high on our to-do list.
     
    firstuser, AlejUb and Sylmerria like this.
  13. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    517
    If you wanted no batching or to make the atlas yourself at runtime sure you could skip the Unity atlas asset. I don't think either of these options are great, since the 2D atlas system has some nice built-in features. UI in particular can really benefit from batching with atlases.

    I appreciate you acknowledging the problem and putting it high on the to do list. You are correct that SpriteAlases and AssetBundles have always been problematic. Thus I was disappointed to hear that they are still problematic with Addressables. I understand that the first release is primarily to create the abstraction of assets built on top of AssetBundles, but I was hoping it would be better. Please keep a solution to this high on the todo list, which is all I can ask. Thanks!
     
  14. rabbitbooster

    rabbitbooster

    Joined:
    Sep 23, 2017
    Posts:
    3
    Thank you for recognize this issue and make solution!
    I hopinng it would better.
    Thank you!
     
  15. MikePage_Artrix

    MikePage_Artrix

    Joined:
    Mar 18, 2016
    Posts:
    15
    Just wondering if there's been movement on this issue or a rough ETA on when we might see something? I'm currently banging my head up against some similar assetbundle / sprite atlas issues.
     
  16. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    We'll release version 1.2.something this week (or early next week if some bugs pop up).

    That will include two main features (quoting the upcoming change log):

    - Added sub-object support to AssetReference. For example, you can now have an AssetReference to a specific sprite within a sprite atlas.
    - Added sub-object support to addresses via [] notation. For example, sprirte atlas "myAtlas", would support loading that atlas via that address, or a sprite via "myAtlas[mySprite]"
     
  17. sssssspirit

    sssssspirit

    Joined:
    Dec 2, 2019
    Posts:
    7
    Hi, @unity_bill
    Nice work.
    But in our project, we use the workflow like what @Ferazel said, we directly use sprite and sprite name when build UI and fill data.
    This struct is what we are using:
    upload_2019-12-6_11-14-49.png

    But the solution about "myAtlas[mySprite]" makes we must know the atlas name when the Designer fill data.
    so my question is:
    1. Is it possible to load sprite by sprite name when use addressables?
    2. we test some workthrought, but all of them need load all atlas and find the right sprite by GetSprite, we thougt this maybe make a memory issue on mobile, is it right?
     
  18. sssssspirit

    sssssspirit

    Joined:
    Dec 2, 2019
    Posts:
    7
    Hi, @unity_bill
    i have a new workthrought by modify the addressables code.
    In ResourceLocationMap.cs, modify the function 'Add'
    Code (CSharp):
    1.         /// <summary>
    2.         /// Add a list of locations.
    3.         /// </summary>
    4.         /// <param name="key">The key to reference the locations with.</param>
    5.         /// <param name="locations">The list of locations to store at the given key.</param>
    6.         public void Add(object key, IList<IResourceLocation> locations)
    7.         {
    8.             Locations.Add(key, locations);
    9.             Debug.Log("Locations add:" + key);
    10.             if (typeof(string) == key.GetType())
    11.             {
    12.                 string newKey = key.ToString();
    13.                 if (newKey.Contains("[") && newKey.Contains("]"))
    14.                 {
    15.                     newKey = newKey.Substring(newKey.IndexOf("[") + 1,newKey.Length - newKey.IndexOf("[") - 2);
    16.                     if(!Locations.ContainsKey(newKey))
    17.                         Locations.Add(newKey, locations);
    18.                 }
    19.             }
    20.         }
    for "myAtlas[mySprite]", this will add "mySprite" as the key.
    and
    The important is : All sprite name must be difference in this way.
    now, my question is :
    is this a good way to do this ?
     
    funbites likes this.
  19. ttermeer-reboundcg

    ttermeer-reboundcg

    Joined:
    Jul 12, 2017
    Posts:
    62
    So right now to provide a good workflow for artist, we must create our own Image class that support AssetReference from Addressables - to include preview within the editor and change the pick window to preview images ?
    It seems counter intuitive. Shouldn't it be part of Addressables ?
    Also there needs to be a way to upgrade project to such a workflow.

    Are upgrade to Sprite Atlas and Asset Bundles within Addressables still on the priority list ?
     
    XiangAloha and SDmitry like this.
  20. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    168
    I wasted a few hours on this ... but I have figured out through trial and error that best workaround currently is to just exclude the png files from the addressable bundles. Include only the atlas files. I usually put whole folders into addressable groups to make everything inside addressable, so in my case I just move the pngs that are in atlases to another folder.

    Then you can assign the sprites to UI.Images as usual and it will include only the atlas textures in the asset bundle and at runtime it will use and load only the sprite atlas textures.

    If you don't do this then
    • Your asset bundle will include both all the source textures and the atlas textures.
    • I am not completely sure, but at runtime both the source textures and the atlas textures are loaded, wasting memory. (I have seen this from inspecting with the profiler and memory profiler.)
    So actually this is pretty important if you use texture atlases.
     
    AlienMe and Joshdbb like this.
  21. Patrick_PS

    Patrick_PS

    Joined:
    Sep 9, 2019
    Posts:
    154
    Has this been fixed yet?
     
  22. MagicDesignEmerick

    MagicDesignEmerick

    Joined:
    Oct 4, 2017
    Posts:
    26
    We have an issue related to spriteAtlas as well, I wonder how much it's linked to this issue.
    When we make a reference to a sprite that is in a spritesheet pulled into a spriteAtlas, we get every raw sprite of the spriteAtlas pulled into the bundle as well.
     
  23. Zitga

    Zitga

    Joined:
    Mar 21, 2016
    Posts:
    3
    who care about this topic? Until got this issue in unity 2018.4.18f1 and addressables 1.6.2. Too sad, more than 9 months from this topic was opened, and unity can't fix
     
  24. Hoang_Le_Field_Engineer_VN

    Hoang_Le_Field_Engineer_VN

    Unity Technologies

    Joined:
    Feb 14, 2019
    Posts:
    2
    May be you referred to this public issue https://issuetracker.unity3d.com/is...s-used-which-increases-the-size-of-the-bundle .....the key point is to only mark the SpriteAtlas as Addressable... don't mark the Sprites or the folder that contains the Sprites as Addressable.... that is redundant and cause the raw textures of those sprites to be included into bundles one more time....it's actually not a bug.... just how we carefully identify what should be included into bundles..... hope it clarifies the situation.
     
    Last edited: Mar 21, 2020
  25. androshchuk-vladyslav

    androshchuk-vladyslav

    Joined:
    Dec 13, 2015
    Posts:
    127
    But that is quite uncomfortable. I want to set address for sprite, but if sprite is included in Atlas it should remove them from bundle and associate address with it inside atlass
     
    XiangAloha and oxysofts like this.
  26. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    I have similar problem with this.

    My issue is I have gameobject that has animator component which is just basic frame animation of sprites. But then when I include this gameobject in addressable and instantiate it, animations plays but sprites does not render. I have the sprites in the atlas and tried to include atlas object into the addressable. But it does not help. If I remove the sprites from the atlas, it shows. I didn't mark individual sprites as addressable. Just atlas.

    So dependency from animation does not seem to go as far to fetch sprites from the atlas asset...
     
  27. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Any idea with this?

    How can I load sprite frame animation with sprites being in the atlas?
    Even if I mark the atlas as addressable, my animation does not show after loading the animation. The animation system does not resolve the sprite dependency from sprite atlas.
     
    felipe-shida-playkids likes this.
  28. Hoang_Le_Field_Engineer_VN

    Hoang_Le_Field_Engineer_VN

    Unity Technologies

    Joined:
    Feb 14, 2019
    Posts:
    2
    You would need to implement SpriteAtlasManager callback for binding the SpriteAtlas at runtime: https://docs.unity3d.com/ScriptRefe...3.1224349435.1586515423-1774357591.1586515423

    Instead of loading the SpriteAtlas from Resources, you would need to load it from Addressable Assets and pass it into the callback.
     
  29. funbites

    funbites

    Joined:
    Oct 9, 2015
    Posts:
    17
  30. funbites

    funbites

    Joined:
    Oct 9, 2015
    Posts:
    17
    Did Addressables have any improvement in that matter? I was thinking, maybe a easier solution would be that the Sprite Atlas generated a baked Image with the sprites, so we can reference those images in the UI, so we don't have to use two workflows: one for sprite and other for Sprite Atlas.
     
    ToroSheep likes this.
  31. funbites

    funbites

    Joined:
    Oct 9, 2015
    Posts:
    17
    I'm looking on a build from Addressables 1.8.3 and it seems to load the sprite from the Sprite Atlas and it's not duplicating the data in the bundle. Am I right?
     
  32. xLeo

    xLeo

    Joined:
    Sep 21, 2010
    Posts:
    194
    Following up on the topic "Asset Bundles/Addressables vs Sprite Atlas", does the Addressable System support Sprite Atlas variants?
    If not, is there an indication of how to proceed to make it work?

    We would like to create quality variants for our addressables.

    Would it work if we had 2 bundle build passes, one with only the Master Sprite Atlases enabled and another with only the variants enabled? That way we could host them in 2 different endpoints and pick which scenes/assets to load depending on the device resolution (for example).
     
    GilbertoBitt likes this.
  33. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    i think it work with late binding of atlas https://gametorrahod.com/demystifying-sprite-atlas-variants/ << using the same process here to set the correct sprite atlas but.. the only issue is that you need to load it using AssetReferenceSpriteAtlased instead of using the resourceLoad
     
  34. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    i'm still trying to make this work.. since i have a character that use multiple sprites atlas and i want each of them have a 2 sprite variant for quality and i want to make it work on runtime and still not working.
     
  35. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    giving some updates to you guys.. i was able to hook and correctly sprite atlas from addressable using sprite atlas and sprite atlas variant. i just wish that the addressable system could have some better way to handle the loading using sprite atlas to not show anything while is downloading the dependencies for the sprite/character.. since the request for the sprite atlas will be only occur when something ask for that sprite itself so the main way that i was using was hooking to sprite atlas to avoid the necessary step of loading all character related items in the selected quality and now i need to change the way i build it. i'm still working to improve things about that but i hope with what i said someone from unity can help me better control this for sprite atlas.
     
  36. cadxplore

    cadxplore

    Joined:
    Sep 4, 2019
    Posts:
    17
    I have a SpriteAtlas which marked as Addressable, and untick "Include in Build".
    I try to load a Prefab (which contains a SpriteRenderer using one of the Sprites from SpriteAtlas) from Resources folder and Unity loaded the SpriteAtlas by itself.

    If I manually load SpriteAtlas via Addressable will end up creating 2 sets of SpriteAtlas in the memory.

    How can I make sure Unity don't "overly smart" to load it by itself even I've unselected "Include in Build"?

    Why is it still such a pain to work with Addressable system in Year 2021?! Did anyone manage to integrate it seamlessly into your project? Please share some tips.
     
  37. Patrick_PS

    Patrick_PS

    Joined:
    Sep 9, 2019
    Posts:
    154
    Don't use Resources folder? They are 2 parallel system that will each load their own instance of the sprite atlas.
     
    XiangAloha likes this.
  38. cadxplore

    cadxplore

    Joined:
    Sep 4, 2019
    Posts:
    17
    FYI, I have another prefab that also in Resources folder but the SpriteRenderer doesn't load its SpriteAtlas after unticking "Include in Build"
     
  39. cadxplore

    cadxplore

    Joined:
    Sep 4, 2019
    Posts:
    17
    UPDATE:
    Somehow after restarting my computer/Unity fixed the issue. So I assume that could be a bug caused by the cache?
     
  40. felipe-shida-playkids

    felipe-shida-playkids

    Joined:
    Sep 16, 2020
    Posts:
    13
    I have the exact same problem, the addressable asset is a simple prefab just containing a UIImage component using a sprite that is inside an atlas, the texture/sprite asset is not addressable, but the atlas is. It loads correctly at first, but as soon as I call a Resources.UnloadUnusedAssets() the sprite gets messy, as if it had lost the atlas data, it shows the entire atlas as the sprite.
     
  41. felipe-shida-playkids

    felipe-shida-playkids

    Joined:
    Sep 16, 2020
    Posts:
    13
    @Hoang_Le_Field_Engineer_VN Using the SpriteAtlasManager to intercept the atlas request and load it from the addressable system seems to work. But in this case is there a good way to know when this atlas is not used anymore so it can be unloaded from memory? Because this request is holding a reference count forever, right?

    EDIT: I noticed that the solution of loading from addressables was missing the Addressable. Release call, so I added a release just after the load was completed, in order to not hold an everlasting reference count.

    I noticed another symptom where just before the correct sprite is loaded during some frames the entire sprite atlas is shown. Any ideas of what could cause this behavior?
     
    Last edited: Aug 5, 2021
  42. diesoftgames

    diesoftgames

    Joined:
    Nov 27, 2018
    Posts:
    122
    Also looking for solutions here. Loading from Resources is kind of a non-starter in some scenarios, and the solution posted by @Hoang_Le_Field_Engineer_VN above doesn't take reference counts into account as far as I can tell.

    So just for clarity, here's what I'm looking to solve for (which I think is similar to most others' needs in this thread):
    * I want to use sprite atlases for reduced draw calls (and resizing of variants)
    * I want to use addressable sprite atlases for on-demand loading / unloading of sprite data, and to avoid loading from Resources which seem to be exceptionally slow in some scenarios.
    * I want to make sure that unused sprite atlases are unloaded when not in use.

    Is there a way to do all this without making my own sprite atlas replacement?
     
  43. joe_nk

    joe_nk

    Joined:
    Jan 6, 2017
    Posts:
    67
    The answer is: No, there isn't. And apparently that is by design. I've been through the mill with Unity Premium Support on this issue, and I can post the full transcript of a full, multiple-month long exchange here if you'd be interested.
     
  44. diesoftgames

    diesoftgames

    Joined:
    Nov 27, 2018
    Posts:
    122
    :(
    It seems like something that's so close to being doable. That is, if the existing SpriteAtlas could just be used as an authoring tool that output a MultipleSprite texture, then that sprite would be able to meet all my needs (at least I think?)
     
  45. joe_nk

    joe_nk

    Joined:
    Jan 6, 2017
    Posts:
    67
    You could certainly use the SpriteAtlas to generate an atlas texture and store a sprite manifest alongside that generated texture, to use at runtime. The problem is that you couldn't author UI etc using that atlas
     
    diesoftgames likes this.