Search Unity

Sprite Atlas About "Include in Build" behaviour

Discussion in '2D Experimental Preview' started by beinteractive, Jul 4, 2017.

  1. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    I'm trying to use a Sprite Atlas feature in Unity2017.1.0f1.
    I need to download Sprite Atlas assets via Asset Bundle at runtime and not to be included in a built app binary (In other word, I don't use Resources).

    So I have some questions:

    1. "Include in Build" means "A built app binary contains a packed sprite atlas"?
    2. If I need to use Asset Bundle, should I uncheck the "Include in Build" option?
    3. In such case, should I always do "late binding" written in the following document?
    (I have a prefab that has a uGUI Image that refers a packed sprite in an Asset Bundle. The packed sprite atlas is also in the Asset Bundle. In this situation, even If I instantiate the prefab, the sprite doesn't be shown on screen)
    https://docs.unity3d.com/2017.1/Documentation/Manual/SpriteAtlas.html
    4. When will a SpriteAtlasManager.atlasRequested callback be triggered? Can I control a timing of it?
    5. Where is a packing tag (the 1st parameter of a SpriteAtlasManager.atlasRequested callback) from? It's a filename of a .spriteatlas asset?
     
  2. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Hello!

    Lets go straight to answers...

    1. "Include in Build" means "A built app binary contains a packed sprite atlas"?
    Yes. Exactly what you meant.
    2. If I need to use Asset Bundle, should I uncheck the "Include in Build" option?
    You don't need to, but it's recommended to do so, else it will be a waste of space.
    3. In such case, should I always do "late binding" written in the following document?
    Using the .atlasRequested callback, a.k.a late binding, you can pass the loaded Sprite Atlas into Unity via the System.Action. Unity runtime will do the rest e.g. refreshing sprite & sprite renderers.
    On the other hand, by using the GetSprites() API on the Sprite Atlas loaded from the asset bundle, you will get the sprites from the atlas which is referencing to the packed texture.
    (I have a prefab that has a uGUI Image that refers a packed sprite in an Asset Bundle. The packed sprite atlas is also in the Asset Bundle. In this situation, even If I instantiate the prefab, the sprite doesn't be shown on screen) https://docs.unity3d.com/2017.1/Documentation/Manual/SpriteAtlas.html
    Regret to tell you that, late binding via the callback is currently not supported on our uGUI front. We will look into the possibility of making this happen, can't promise though. Try to work around the situation with the GetSprites() API I mentioned above, it's trickier, but hopefully it does the trick for you.
    4. When will a SpriteAtlasManager.atlasRequested callback be triggered? Can I control a timing of it?
    It will be triggered whenever the sprite referencing to the atlas gets awaken. There is no way to control it's timing. We strongly recommend user to register the callback during OnEnable().
    5. Where is a packing tag (the 1st parameter of a SpriteAtlasManager.atlasRequested callback) from? It's a filename of a .spriteatlas asset?
    Really appreciate your feedback and question on the usage of the feature. Please keep us posted of your progress.
     
    HZ51 and Andrey-Postelzhuk like this.
  3. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    Thank you for a quick response. It's so helpful for me.

    Things what do I want to do:

    - Make an Asset Bundle that contains a prefab that has a uGUI Image that refers a sprite.
    - Download the Asset Bundle at runtime.
    - Instantiate the prefab in the Asset Bundle and display the sprite on screen.
    - Don't contain both the prefab and the sprite in a build app binary (to reduce app size)

    According to your answers, I should do:

    - Uncheck the "Include in Build" option (to reduce app size)
    - Load a Sprite Atlas from the Asset Bundle
    - Get a Sprite via SpriteAtlas.GetSprites() and set it into Image.sprite

    because there are no way to resolve sprite atlas reference from uGUI Image.
    My understand is correct?

    If so, there are feature requests to make Sprite Atlas better:

    - Late binding supports uGUI Image.
    - Split "Include in Build" option into "Include in Build" and "Use Late Binding" options.
    There is possible situation that "I don't want to include an atlas in a binary but I don't need late binding feature".
    If both a sprite atlas and components that refers the sprite was included in a same Asset Bundle, It would be better that a loaded component references the sprite without late binding. Because the component knows where the sprite is. (Of course, it's in the same Asset Bundle)
     
  4. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Aye aye. Gonna look into the uGUI support of late binding.

    For the wording and explanation of the option, I will discuss with the UX & Doc people to find a better solution.

    As for the situation you described, e.g. sprite atlas, sprite and component are in the same asset bundle. I thought it should work. Do you mind share a simpler version of your project which can reproduce this?
     
  5. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    I attached a simple tiny project for reproducing my situation.
    This project has been made in Unity2017.1.0f1 / macOS / iOS Platform.

    The project has a Scenes/Game.unity scene.
    An attached component Scripts/InstantiateFromAssetBundle.cs on Canvas will load an uGUI Image from an Asset Bundle and instantiate it. I've expected a sprite was shown on screen but it wasn't.

    Assets in the Asset Bundles are placed on "Asset Bundle Assets" folder and the Asset Bundle was built by Asset Bundle Manager.

    I faced this problem when I play this project on Editor and Local Asset Bundle Server mode.
    I didn't check that this problem will happen on device / other platforms.
     

    Attached Files:

  6. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Thank you very much, will get to work immediately.
     
  7. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    So I took a look. TBH, took some time to figured out the asset bundle manager and gets it working :p.

    I found out, creating the prefab out of the UI Image component and load it as is under the canvas, will fail even with a sprite without atlas. Not sure is this a bug originally or I mess up the state.

    However. I changed it to create a prefab from the whole canvas hierarchy (Canvas + UI Image children), and loading it with or without sprite atlas packing is fine. Can you verify that?
     
    HZ51 likes this.
  8. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    Like you say, I created a prefab with Canvas. But the problem still occur.
    Please review an attached project.
     

    Attached Files:

  9. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Sorry, I was testing in Editor and have my asset still sit in the project, thus not seeing the issue.

    This might be a bug, but we need more time to find out the real cause. If you don't mind, you can create a bug report with the sample project. Doing so, you will have a direct channel to the issue and get notify when it's fix. Else, I can have our QA to log the bug and I post it back here once we find a fix.

    So sorry for causing this much trouble, had you re-create another project, we will get this fix asap.
     
    Last edited: Jul 5, 2017
    HZ51 likes this.
  10. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    I reported a bug via Unity Bug Reporter in Editor.
    Thank you for reviewing.
     
  11. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Hi @beinteractive,

    I saw the issue has been converted to a bug and it's in the system. After digging into the issue last week, I have some findings that can share with you now.

    1. The "Include in build" has created some confusion. For this particular situation, this check box need to be checked. Doing so will make sure the sprite will reference to the atlas's texture in the asset bundle, in this sense, the asset bundle is a "build". This is confusing, we are finding a solution to the wording / work flow around this option now.

    2. These are all editor only issue. Standalone builds are fine as they has different logic when starting up the sprites and atlas.

    3. Even though checking the option will remedy the situation. After all these, I found other underlying asset bundle + editor related issue in sprite atlas, thus, there are still bugs to fix following this up.

    For now, you can check the option "Include in build" to ensure the sprite in the asset bundle will reference to the atlas in the asset bundle. This will work 100% in standalone builds (e.g. ios). But there are ways to break it in editor, e.g. deleting the assets from the project before enter play mode. These are the outstanding issue we will need to fix.

    Finally, really appreciate your discoveries of the issue and we able to smoke out underlying issues earlier.
     
  12. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    21
    Thank you for update.
    Hope soon the issue will be fixed.
     
  13. drHogan

    drHogan

    Joined:
    Sep 26, 2012
    Posts:
    158
    As this one seems to be the only current alive thread on the Sprite Packer, I have a couple of doubts here. A premise, we worked till now with TexturePacker for atlases management.

    The first one is almost the same as @beinteractive had involving a bundle and a prefab (in my case it's sprites, but same problem). It's also a bit unclear to me if i need to provide with the asset bundle tag only the sprite atlas or also the single sprites (and in that case will there be a duplication?).
    I also add that as a vital feature one should be able to use the sprites from inspector, otherwise the workflow becomes hellish if i need to assign each sprite from the code.

    The second one is related to size. The size of the atlas seems to be bound to the largest of the packed sprites. In TexturePacker, after producing a sheet, we had a chance to change the whole sheet, resizing each single sprite in the process. Here it does seem to work only if you first reduce the size of each involved sprite. Beside, having tried with a sheet with lots of small elements (a waving flag), it happened the following : The flags were still in a very large format because i forgot to reduce them (so approx 30 frames each was 512x512). I give the packing command into a 1024 atlas, and without any worning, a lot of them were left outside the atlas.

    Is it possible to give the atlas some control over the final size ( i saw variant but in my case using the variant seems a bit overkill) and/or at least a warning that all the elements couldn't fit in as required? I think it's pretty easy to lose a sprite along the way without noticing because of that.

    Cheers,
    H
     
  14. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    754
    @Kuan I've been trying to get UGUI SpriteAtlas and Asset Bundles to play nicely together and have a question about Include In Build intended behaviour.

    I would think that checking include in build would make it so that the atlas does NOT get duplicated in every bundle that references a sprite from it but that is not what's happening. Is it expected that checking include in build will duplicate the atlas in every asset bundle that is dependent on it or is this a bug?
     
  15. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Hi @TheValar,

    The SpriteAtlas is not duplicated, but referenced as dependency in the bundle.

    How'd you find out that the asset is actually duplicated into each bundle? If the asset is copied and sit into each bundle, this is a bug. In that case, I would need your help to provide information like Unity version and a repro project or steps.
     
  16. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    754
    @Kuan thanks for the speedy response!

    I can tell it is being duplicated in each bundle because of the size. And to re-iterate this is only if I have the "include in build" boolean set to true. I'll work on getting a simple repro project to send in with the bug.

    So is that confirmation that late binding is not supported for UGUI? And will it be supported in the future?
     
  17. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    A repro project will be really helpful. It is a great way for us to discover how user setup their project for certain situation too.

    Late binding for uGUI is something we aware of but hasn't make it into a real task to work on yet. I will escalate this to the product management team, so that they aware that user still need this feature.
     
  18. chmodseven

    chmodseven

    Joined:
    Jul 20, 2012
    Posts:
    38
    Following on from drHogan's question about size - I am packing a sprite atlas and seeing that the Max Size settings for the individual sprites being packed do not appear to be respected by the atlas packer. For instance I've set a 256x256 icon down to 128x128 to save space on the icon itself, but when I do the atlas pack, it has taken the file size of 256x256 and packed it at that full size instead. Is this something I'm not doing correctly? An intended functionality? I would have thought that we'd be able to fine tune individual sprite sizes and other settings as per normal for any unpacked sprite, and then have those changes applied as such into the packed atlas.
     
  19. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    I do not observe this behaviour currently, the atlas do pack with the reduced size (both legacy and new). Which version of Unity are you using that has this issue? Or you mind share your project or a small repro project?
     
  20. esg_evan

    esg_evan

    Joined:
    Sep 29, 2016
    Posts:
    1
    Did some experimenting and late binding can work on Images in bundled prefabs that reference bundled SpriteAtlases if you instantiate the prefab, deactivate the object so you can't see the broken Images, handle the atlas request which comes in on frame end*, and then reactivate the object next frame (presumably because now it has all the info to actually build the canvas correctly). Tested in Editor and on Android.

    Not really acceptable for us but if anyone else is stuck in a real bind, this good 'ole "turn it off and on again" trick may help.

    It's a shame because it seems like a nice system but I don't think reworking our pipeline to use GetSprites is worth it so we're likely sticking with the Legacy Packer for a while.

    * Sadly even yield return WaitForEndOfFrame doesn't wait long enough. Atlas request still comes in later.
     
    learner_CL likes this.
  21. TheJimz

    TheJimz

    Joined:
    Jun 26, 2015
    Posts:
    48
    I'd like to confirm that I'm having an issue with 'include-in-build' sprite atlases also being duplicated into other asset bundles. This can be confirmed by both the asset bundle size and the log output of what's included in the bundle.

    I also tried bundling my sprite atlases into their own asset bundle (still with include-in-build) and other asset bundles will still duplicate them. This has been a trick I use with regular texture to prevent duplication by using a 'common' asset bundle with them already included, and therefore other asset bundles should know not to duplicate.

    The legacy sprite atlas system does not have this issue, and my project is going to have to continue using the legacy system.

    Any update on the status of this?
     
    Last edited: Jan 18, 2018
  22. WitLau1990

    WitLau1990

    Joined:
    Nov 30, 2017
    Posts:
    2
    i found a violence way ,
    BroadcastMessage("SetAllDirty", SendMessageOptions.DontRequireReceiver);
    in next frame........
     
  23. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    754
    @Kuan any word on when UGUI will support late binding?
     
  24. ColossalPaul

    ColossalPaul

    Unity Technologies

    Joined:
    May 1, 2013
    Posts:
    169
    Apologies for the late replies. Our SpriteAtlas guy @Kuan left us :( now we are shorthanded. Anyways let me try to reply.

    Here is a simple rule to keep in mind. The "Include in Build" checkbox governs if the `Sprite` has a direct reference to the `SpriteAtlas`. Check then yes, uncheck then no.

    When checked, we make it so that you don't really have to care about taking the `SpriteAtlas` anywhere explicitly. It will be there as long as you bring the `Sprite`. This is like any asset dependency that we check during our conventional build. Which also applies to AB builds.

    when unchecked, The `Sprite` releases its reference to the `SpriteAtlas` therefore, the `SpriteAtlas` won't come automatically. You'd have to use latebinding to load it from somewhere (resources, streaming assets, AB via www)

    If you bundle the SpriteAtlas explicitly and separately, you should uncheck "Include In Build". So that the bundle that has the sprites don't get the atlas. also make sure the spriteatlas are not reference explicitly by anyone.

    18.3, maybe 18.2 trying to see what fits.

    I'm watching this thread so i'll be able to reply sooner. feel free to ask more.
     
    ranye likes this.
  25. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    754
    thanks for answering my questions :)
     
  26. cybergaston007

    cybergaston007

    Joined:
    Jun 21, 2017
    Posts:
    7
    I don't want to seem rude, but I just spend an entire day, trying to figure out why my code was not working on late binding and UI image. Until I came across this post.

    So basically it's been a year since the release of this new feature, and this bug has still not been fixed ? Not even 1 mention about Late binding and GUI not working in the docs.

    Honestly, as a paying user, sometimes how Unity handles thing seems less then professional. I don't even get how such a simple bug was not spotted during Unity QA....
     
    Last edited: Jul 24, 2018
  27. ColossalPaul

    ColossalPaul

    Unity Technologies

    Joined:
    May 1, 2013
    Posts:
    169
    The fix was back-ported to 2018.2 8-days ago. It should be coming out in a patch anytime soon.

    We are also rewriting the entire SpriteAtlas docs. In fact we hired a 2D tech doc writer to rewrite almost everything.

    I truly appreciate when users come up to me and tell me anything. The good and the bad. I also appreciate it when users call me out on things I missed. It's a free bit of info to build my roadmap. And this is how we could work collaboratively to make unity and your experience better. I can't claim that we have 100% test coverage or figured everything out, it is just humanly impossible to cross check every feature with every other feature in unity. So it is anything but easy, but thanks to you we will get them all eventually.

    Thank You!!!
     
    pankaj8958 and kruzoe like this.
  28. tachen

    tachen

    Joined:
    Jul 2, 2013
    Posts:
    9
    So what's the resoult?
     
  29. magehernan

    magehernan

    Joined:
    Jul 6, 2012
    Posts:
    5
    Hi, i am working with SpriteAtlas and AssetBundles, i have a lots of sprites that don't use all at the same time, i see unity load all in memory and is consuming 800mb of ram... so i decide to split on assetbundles and load the sprites i need and unload when i don't need them.
    I'm using the sprite atlas manager, and it works great, but if i unload the assetbundle and later load it again it never relink with the sprites.
    there is a way to load and unload spriteAtlas without losing the references to the atlas?
    Best Regards
     
  30. abiasi

    abiasi

    Joined:
    Nov 12, 2015
    Posts:
    3
    We are also experiencing some issues with sprite atlases. When using the memory profiler we can see that all sprite atlases referenced in a scene get loaded but when switching scenes they don't get unloaded even after calling Resources.UnloadUnusedAssets().

    Scenes are switched using SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single) and we are waiting for the end of frame after the async operation is done to call Resources.UnloadUnusedAssets().

    When the sprites are not part of the atlas we can see in the memory profiler that they are properly loaded/unloaded.

    All sprites are drag and drop references in the inspector, no asset bundles or sprite atlas API used. No sprite is assigned to more than 1 sprite atlas. Most sprites are assigned to UGUI Image components. Happens in the Editor and also on iOS devices.

    We are currently testing using Unity version 2018.2.11f1 for Mac.
     
    learner_CL likes this.
  31. Ryukidmm

    Ryukidmm

    Joined:
    Aug 14, 2018
    Posts:
    5


    "SpriteAtlasManager.atlasRequested" will not be called if the Sprite included in the SpriteAtlas is attached to the SpriteRenderer and its Prefab is loaded from the AssetBundle and Instatiate is done.
    .spriteatlas, .prefab, .png All are included in one AssetBundle.
    I have a component that performs late binding in Prefab and I set reference of spriteatlas in inspector.

    When placing it from the beginning in the Scene and playing it, I confirm that it binds correctly.

    In this case, can you tell me how "SpriteAtlasManager.atlasRequested" will be called?

    I am using Unity 2018.2.6.
    I am sorry for my poor English.
     
  32. bug-fiend

    bug-fiend

    Joined:
    May 25, 2017
    Posts:
    1
    Is this problem fixed now?
     
  33. vietlab

    vietlab

    Joined:
    Sep 29, 2016
    Posts:
    6
    It's never been fixed as least for me, all sprites included in the build together with the big texture generated by the SpriteAtlas ... Never works, 2018.2.x, 2019.x or I'm I missing something? @ColossalPaul
     
  34. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    4,129
    Could you please submit a bug-report as described in this document:
    https://unity3d.com/unity/qa/bug-reporting

    It's important that you report these issues together with a reproduction project if you want them to get fixed. If you don't do it, it might be a long time until someone else reports them or until Unity Technologies find them.

    After you submitted the bug-report, you receive a confirmation email with a bug-report Case number. You can post this Case number here (in this forum thread) for Unity staff to pick up, in case they see it.
     
  35. ColossalPaul

    ColossalPaul

    Unity Technologies

    Joined:
    May 1, 2013
    Posts:
    169
    Please submit a bug and I'll take a look at it thanks.
     
  36. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    Late binding for UI seems to work in the latest unity, but before a requested atlas is loaded image shows some garbage from other atlases like atlas for text or other atlases included in build.

    While atlas is being loaded:
    upload_2019-4-2_13-42-1.png
    After:
    upload_2019-4-2_13-42-36.png

    Is it intended for some weird reason or a bug?
     
    Last edited: Apr 2, 2019
  37. TheJimz

    TheJimz

    Joined:
    Jun 26, 2015
    Posts:
    48
    Yes regarding this, if you are async loading the atlas unity will show an empty image in place of the sprite. When the atlas request is called you really want to return it immediately. Setup your code to immediately have it available. (Download it before the game starts, or load the bundle containing it immediately at startup)