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?
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.
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
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.
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 Unity - Scripting API: SpriteAtlas) 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.
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?
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.
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.
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(â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.
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 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.
So at present the best way is not to use Sprite Atlas. Use this ASTC compression format.
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 .
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.
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!
Thank you for recognize this issue and make solution!
I hopinng it would better.
Thank you!
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.
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]â
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:
But the solution about âmyAtlas[mySprite]â makes we must know the atlas name when the Designer fill data.
so my question is:
- Is it possible to load sprite by sprite name when use addressables?
- 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?
Hi, @unity_bill
i have a new workthrought by modify the addressables code.
In ResourceLocationMap.cs, modify the function âAddâ
/// <summary>
/// Add a list of locations.
/// </summary>
/// <param name="key">The key to reference the locations with.</param>
/// <param name="locations">The list of locations to store at the given key.</param>
public void Add(object key, IList<IResourceLocation> locations)
{
Locations.Add(key, locations);
Debug.Log("Locations add:" + key);
if (typeof(string) == key.GetType())
{
string newKey = key.ToString();
if (newKey.Contains("[") && newKey.Contains("]"))
{
newKey = newKey.Substring(newKey.IndexOf("[") + 1,newKey.Length - newKey.IndexOf("[") - 2);
if(!Locations.ContainsKey(newKey))
Locations.Add(newKey, locations);
}
}
}
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 ?
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 ?
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.