About "Include in Build" behaviour

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)
    Unity - Manual: Sprite Atlas
  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?

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) Unity - Manual: Sprite Atlas
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?
Yes it is. Special case for variant though.

Really appreciate your feedback and question on the usage of the feature. Please keep us posted of your progress.

2 Likes

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)

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?

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.

3133225–237419–Sprite Atlas Sandbox.zip (1.29 MB)

Thank you very much, will get to work immediately.

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?

1 Like

Like you say, I created a prefab with Canvas. But the problem still occur.
Please review an attached project.

3133457–237435–Sprite Atlas Sandbox v2.zip (1.23 MB)

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.

1 Like

I reported a bug via Unity Bug Reporter in Editor.
Thank you for reviewing.

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.

Thank you for update.
Hope soon the issue will be fixed.

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

@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?

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.

@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?

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.

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.

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?

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.
1 Like