Unity 4.5 Sprite Packer does not pack images inside Resources folder (539002)

Hi!

I’m trying to use the new Sprite Packer tool, but it doesn’t work if I put the imagens inside Resouces folder, but inside any other folder it works.

is it a bug?

It’s pretty sensible. The main reason to use Sprite Packer is to save space in your build. If your textures are in the Resources folder, they will always be included in the build no matter what. So, why waste space in the texture atlas storing them twice?

1 Like

It’s not a bug, it’s intentional.

–Eric

Thanks Man!

So, where does Unity put the texture atlas? is it inside Resources folder?

Can I get this textures in run time?

if you can answer that, I thank you.

I don’t know where it stores the atlas texture (probably in the Library somewhere?), but it’s intended to be abstracted away so that you never actually need the atlas texture. e.g., dragging a sprite into the game area will use the packed atlas texture seamlessly.

Do you have a reason to need the atlas specifically?

1 Like

I have sprite animations. So my sprite must have the same size for each frame, but I have different animations with different frame sizes in the scene. I created one multiple sprite for every animation. So I have 3 or more multiple sprites. it creates more drawcalls.
I want to make one atlas with all sprites, so I tried to use Sprite Packer to make it.
I really need it to be in Resources folder because I can’t set the sprites in the Animation clip. I’m using AssetBundle to manage resources.

But I think what I want is not possible, so I’ll leave it as it is.

But now I don’t know why i’ll use Sprite Packer if I can’t load it inside resources. And I think that sprites in other folders are also included in the build.

It seems overly restrictive though. I want to dynamically load and unload sprites for use in a specific scene which is image heavy and should not have them all loaded at once. The sprites need to be packed onto atlases for common reasons:

  • Draw Call reduction (packing sprites reduces the number of textures and hence draw calls used in a scene)
  • Memory (If you have several NPOT textures packing them into a power of two atlas allows texture compression)
  • Abstract link to atlas (code only references sprites which can change which atlas they are on)

Obviously we don’t want the sprite texture it’s self stored in the build though, just the resulting atlas and ‘sprite definition’.

I had hoped that by adding the sprites to the resources folder the relevant atlas textures would be created and when a sprite was loaded from the resources folder it would ensure the relevant atlas texture was loaded and return the sprite. Release all sprites on an atlas and the atlas texture would be unloaded.

So it seems that I will have to use an external sprite packer and import the atlas it’s self into the resources directory. This is not ideal as the code then has to know which atlas to load and the best feature of Unity’s sprites is that it abstracts away which atlas texture is used by a sprite allowing you to move sprites between atlases and the game to continue to run unchanged.

Hopefully at some point Unity will add support for packing textures in the resources directory or a work around will be discovered.

6 Likes

Packing sprites that are in the resource folder makes no sense, because they would end up being two times in the final build. Everything from the resource folder is part of the final build and most likely you use the texture atlas as well.

Edit: Dumb post, please don’t read…

Here’s my understanding of the way the sprite packer works: when it packs the sprites into atlases, it creates a specialized 2-D mesh whose UVs reference the atlas. When you drag a Sprite into a SpriteRenderer component, in the editor it contains references to both the original image (since the images are still present even when the packer has not yet been run) and to the atlas; when you build the player, it strips out the references to the original image, leaving only the atlas references and saving space.

I don’t see how being in Resources changes this. When you have an object of type Sprite, it contains a special mesh and a reference to an image, and whether that image is an atlas or a standalone image has little to no impact on a SpriteRenderer. The Resources folder would simply contain the mesh part of the sprite data; it just now refers to the atlas, and the raw image is stripped from the build, just like when there’s a direct reference to it. When I call Resources.Load(“foo”), it should give me a sprite that has a mesh and references the atlas.

At least that’s how it should work…

1 Like

You can get the texture at runtime:
http://docs.unity3d.com/ScriptReference/Sprite-texture.html

To display the frame correctly, you also need to know where on the atlas the sprite is:
http://docs.unity3d.com/ScriptReference/Sprite-textureRect.html

Could you explain what exactly you are doing? How do you use asset bundles? Are all the sprites in the asset bundle or are they in the resources folder?

1 Like

Exactly how I see it too. I can see however why it may be misleading and people may expect the sprite texture to also be in the build but I would only expect that if the texture type was not set to sprite or the sprite was not packed. As far as the actual texture data goes it would effectively in the build but in the packed atlas texture, there is no reason I can think of why it would appear twice. As StarManta puts it above loading the sprite from resources would return the sprite referencing the atlas texture.

In hindsight, that makes sense, but it’s not super obvious. I was going nuts trying to figure this out before I found this thread. It really ought to say something about this at http://docs.unity3d.com/Manual/SpritePacker.html

2 Likes

Cool post. Just one thing wanna get my head around. So I’m creating a system that would load either SD sprites or HD sprites, depending on the tag they have. All the sprites are stored directly in Resourced. The reason I’m doing this is that depending if its an iPhone5, iPad Retina or iPhone6 I want specific sprites tags to be loaded. If I created folders for each Scene in the game that have different sprites directly in Resourced, I would using be able to use:

Resources.Load(“scene1/foo@HD”)

This will only load the sprite named “foo@HD” which is in Folder named “scene1”. Don’t see nothing wrong why this can’t work. So Sprite Packer (PRO Only) still can’t be used in Resources folder?? Honestly that’s one of the main reasons I wanted to buy the PRO version but not gonna be useful in this case. Any suggestions I’m up for

Yep the following would be nice

Resources.Load(“scene1/foo@HD”)

It would load the atlas texture with the sprite on it along with the actual Sprite object. Any further loads of other sprites would use already loaded atlases or load them as needed.

It should all just work but supposedly the current implementation is ‘intentional’. I really hope someone at Unity thinks about this and comes up with a solution that allows sprites in the resources folder, I can’t see a technical reason why it couldn’t be supported. I certainly can’t see the reasoning that a sprite in the resources folder should not be atlased, why not? As long as it has an atlas tag then it can be put into the relevant atlas texture(s), the rest of the APIs should just work.

Yeah apparently the new sprite packer in Unity 5 is suppose to solve a lot of problems.

Also wanted to add that if you have later scenes in the game that no longer use the previous sprites loaded in the Resource folder, the following line can be used to unload stuff accordingly:

Resource.UnloadUnusedAssets()

I agree this is an issue. My main problem right now is I can’t figure out how to enumerate all sprites in a Texture atlas at runtime, is it possible? I tried to use the Resources folder as you can enumerate assets at a path (so if these assets were all packed then I also get all sprites in a texture atlas for free) however as sprites in a Resources path don’t pack this isn’t possible.

This is all Unity5 as well.

1 Like

+10 to have that feature

I’ve just discovered that you can still put sprites in the Resources folder into an atlas if you do the following steps:

  1. Temporarily move the folder that contains your sprites outside of the Assets/Resources folder
  2. Change the packing tag on all of the sprites
  3. Select Pack from the Sprite Packer
  4. Finally, move the folder back into Resources
  • it is necessary to do all of these steps every time a sprite is changed, including step 2, or else the Unity editor will not consider all sprites for packing

The reason why I need to do this in my project is because I need a way to load individual UI sprites at runtime by name (for example, context-sensitive user actions may require different sprites on the same logical button, and the exact nature of the action might only be determined at runtime) and at the same time I want to apply rendering optimizations by batching similar sprites in a single SetPass call. Individual sprites loaded via Resources.Load() creates individual SetPass calls for EACH sprite, unless they were all in the same atlas. Making prefabs for each individual sprite just to replace that simple Resources.Load() call is overkill.

Unity, please remove this skip-Resources-folder restriction for the sprite packer. As other posters have already said above, the implementation need not store the atlas-ed textures twice.

2 Likes

Hi again!

Has someone figure out how this unity’s sprite packer thing works?

I haven’t been able to figure it out…I really don’t know how I can call the sprites from this “logical atlas” in my code. How to load it. there’s no tutorial to how load sprite by code using this unity’s sprite packer.

Please someone from unity team teach us how to use this thing please!!!

Gives sprites a packing tag, and all sprites with that tag are packed into an atlas. You don’t have to do anything else; it’s all automatic and you refer to sprites the same way as always. As far as your code goes, it’s all the same whether sprites are part of an atlas or not.

–Eric