Search Unity

  1. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  2. Unity 2017.2 beta is now available for download.
    Dismiss Notice
  3. Unity 2017.1 is now released.
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  6. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice

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:
    6
    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:
    81
    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.
     
  3. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    6
    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:
    81
    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:
    6
    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:
    81
    Thank you very much, will get to work immediately.
     
  7. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    81
    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?
     
  8. beinteractive

    beinteractive

    Joined:
    Apr 10, 2014
    Posts:
    6
    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:
    81
    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
  10. beinteractive

    beinteractive

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

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    81
    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:
    6
    Thank you for update.
    Hope soon the issue will be fixed.
     
  13. drHogan

    drHogan

    Joined:
    Sep 26, 2012
    Posts:
    127
    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