Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    989
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    989
    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:
    49
    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:
    391
    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.
     
  7. stefankohl

    stefankohl

    Joined:
    May 30, 2014
    Posts:
    49
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    989
    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.
     
  9. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    391
    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:
    27
    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:
    262
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    989
    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.
     
    AlejUb and Sylmerria like this.
  13. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    391
    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:
    12
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    989
    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]"
     
    diesoftgames, rabbitbooster and M_R like this.
  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 ?
     
  19. ttermeer-reboundcg

    ttermeer-reboundcg

    Joined:
    Jul 12, 2017
    Posts:
    54
    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 ?
     
    SDmitry likes this.
  20. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    147
    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.
     
    Joshdbb likes this.
  21. Patrick_PS

    Patrick_PS

    Joined:
    Sep 9, 2019
    Posts:
    55
    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:
    1
    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. AndersonDev

    AndersonDev

    Joined:
    Dec 13, 2015
    Posts:
    96
    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
     
  26. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,564
    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...
     
unityunity