How to preserve sprite size with Aseprite importer

Hi, i am currently trying to import sprites from Aseprite with a lot of layers each for an individual part of a character. My layer structure looks like this:


The sprite is 64x64px and I need to preserve that size because of the position of each body part or clothing. Currently I cannot find an option to preserve the size and all slices are trimmed. Is there an option to set the slicing mode to per cell size instead of trimmed?

1 Like

There is currently no way to remove the trimming for each cell. Aseprite does a trim pass when saving the pixel data down to the .aseprite file, so when we load the data up in Unity, it no longer has the size you see in Aseprite.
However, I am curious why you need to preserve the size. Could you expand on how it fails?

Hi Ted, thanks for the answer.
I use sprite libraries and sprite swap to construct a character. My Aseprite files contains a layer for each part which can be modified in my game, for example there are different pants, hair, jackets, shirts etc… After the import every sprite is by its own size, e.g. 10x12 px. My character is constructed in a 64x64px sprite. Now I am missing every position of these parts. Everything would be at the center.
But if Aseprite saves a trimmed sprite how do they know where the sprite goes if I load a saved file?
This is how I currently export the sprites to png and then to unity (this is a hairstyle):
9129595--1267393--radical_curve.png

In Unity i have something like this with the Aseprite importer:

Looking at the image, I think the following import settings are suitable for your use case:
Import Mode: Individual - So that each cell is imported as its own Sprite, so you can swap it out easily
Pivot Space: Canvas - So that the pivot for each Sprite is calculated according to its position in the original canvas, rather than the final Sprite.

Have you tried these settings out?

Every cell has position data stored with it. This is also the data we use to calculate the “Pivot Space: Canvas”-pivot. With this data, you can easily position the trimmed sprites back in place. That is what Aseprite does.

1 Like

Maybe I am missing something. I can only choose between “Animated” and “Sprite Sheet” as import mode. Only when choosing animated I can set the pivot space. But it works now with that combination, thanks :slight_smile:

Thats good to know, maybe the wording of “Sprite Sheet” could be improved. The idea behind the “Sprite Sheet” option is that you are in control of slicing the Sprites up yourself, rather than letting the importer do it for you. This was requested by some of the users.
I’ll make a note to see if the name can be improved.

Happy that you got it all working in the end!

1 Like

I’m sorry to necro this thread, but I’m actually running into the same issue.

When we import our aseprite files, the textures have the correct size (the same as the original canvas), but the position of the content of the canvas is moved to the bottom left-hand corner of the texture.

Here’s an example:

Originally, the rectangles were centered, but you can see they’ve all moved to the bottom left of the texture.

That’s with the Sprite Sheet setting, no sprite is created.

With the “Animated Sprite” setting, sprites are created, but the canvas size is lost and the position information is also lost.

I can provide a project with an example of the animated sprite issue.

tl;dr, the canvas size is lost on sprites, the position information is lost on the textures. @Ted_Wikman is there any way to preserve the original canvas and the position of the content therein?

Would you like to see the SpriteSheet option essentially generating a texture which contains all the layers merged, with the size of the canvas?
Or would you like to see an option where each generated Sprite has the size of the canvas? (Essentially exporting out each Aseprite cell as a Sprite, and keeping the Sprite size to the Canvas size)

1 Like

I think what I’m missing is the latter option you suggested @Ted_Wikman
. Ultimately, we use aseprite for animations and for individual sprites.

Unless I’m misunderstanding, the packing process puts all the sprites into one texture throwing away the alpha surrounding the images.

For an animation, it’s somewhat possible to compensator for this by adding position information into the animation clip so the sprite renderers are positioned relative to their parent on an invisible “canvas”.

The same technique is not possible for single sprites because there is no parent object representing an invisible canvas.

To my knowledge, it’s not possible to create a sprite that’s larger than its texture so by packing the images into one texture, we lose the ability to reconstitute the canvas.

I think what we want is, rather than packing everything into one texture, to have a texture per cell and to have that texture be the size of the canvas. We use SpriteAtlas for packing and this way we wouldn’t lose position information.

Or maybe it’d be fine if everything was still packed in a texture, but then the sprites retained their position and canvas size.

So I guess what I’m looking for is either:
A) A way to create a texture-per-cell that is the size of the canvas. That way no information is lost. It also makes packing into Unity’s build-in SpriteAtlases more efficient since it can arrange more granular image sizes.

B) A way to, with the current single-texture-with-packing approach, to create sprites that are the size of the original canvas and have the images within them positioned as they were on the original canvas.

Based on my brief reading of the code, it seems like neither option is possible currently. Do you have any advice for us?

Here’s what I’ve done as a temporary workaround:

This packs everything in the texture with the canvas intact rather than packing as tightly as possible. Unfortunately, that means it’s even less efficient than it was to add this to a SpriteAtlas, but I don’t know a better way of doing this without rewriting the importer to output textures that retain the canvas.

Aseprite already removes the alpha around the cells before writing the content down to the file. In the Aseprite Importer, we got an additional alpha removal step, just in case another DCC outputs Aseprite files with the alpha intact (something we’ve seen with .psd files).

However, I feel like I don’t fully understand your problem. You have Cells/Sprites in your Aseprite file, and you want them to retain their individual position inside of Unity. Is that correct? If so, the Import Mode: Animated Sprite already does that for you. It calculates the pivot of each Sprite based on the canvas it was on, so that if you drag a few Sprites out into the scene and set their position to 0,0,0, they will be in the same positions as they are in Aseprite.

I’m also looking into adding support to preserve the canvas around each Sprite. Where this would be useful is mainly UI animation, where each Sprite should be the same size. However, your use case seems to be different, so I am curious about it and would love to understand your setup and how the current options are failing you.

If we were to add the option to have each Sprite add alpha to be the size of the canvas, we would most likely go for your option B, since we want the Sprites to be on the same texture to save on draw calls without the need of a Sprite Atlas.

Thanks for your input, and looking forward hearing more about your setup.

Thanks so much, @Ted_Wikman, for reading all of that!

Issue 1 - Respecting Original Canvas
I think it would be easiest if I just share a file where the current Animated Sprite mode doesn’t work as we would expect.

Here is a link to a test animation with three frames. If you play it in aesprite, it looks one way, if you play it in Unity, it looks another.

Let me know if this helps illustrate the issue we’re seeing. If you take a look at the GitHub commit I shared, it forces the canvas atlas to be retained during the packing phase to side-step the issue.

Issue 2 - Sprite Atlas Efficiency
This is less important, but because the sprites are being packed in a single texture, they cannot be efficiently packed into Unity’s SpriteAtlases. It seems like the Aseprite importer is duplicating some of the effort put into Unity’s SpriteAtlas system.

This isn’t causing any real problem for us because our animations aren’t that big. But I just wanted to mention it because it seems like relying on the existing SpriteAtlases could help simplify the plugin and allow for greater memory efficiency.

also try the free option libresprite maybe that one works for you. (is the same thing like aseprite but free open source)

I might be missing something, but they look the same to me. (Here I’m using the default settings of the Aseprite Importer).

Re: Issue 2: It is true that the packing is different between Aseprite Importer and Sprite Atlas. However, the packing should be the same between multiple textures vs. single texture when creating a new atlas texture using a Sprite Atlas. The reason for that is that we take the Sprites and copy them over to the Sprite Atlas, so it doesn’t matter if the Sprite is by itself on a texture vs. is on a texture with multiple Sprites. If you are seeing anything different than this, let me know so we can make sure nothing strange is happening in the Sprite Atlas pipeline.

Hi @Ted_Wikman , I apologize I didn’t get notified about this response so I completely missed it!

Thanks so much for testing that out.

RE: Issue 1
It’s very strange because when I imported that, the red rectangles actually don’t move at all, but it seems like they are when you imported them. I don’t know what to say. Maybe there’s been an update to the plugin or maybe I have something configured incorrectly. I’m baffled.

RE: Issue 2
Maybe I misunderstood how a SpriteAtlas would pack the Aesprite mutli-texture. I thought it would take the texture as a whole rather than the individual sprites. If it’s the latter, then there’s no problem at all because they sprites can be rearranged to best fit the SpriteAtlas. But if it’s the former, then they couldn’t be rearranged and so would take up more space.

I want to throw in my 2 cents as well.

So, I am working on a TCG (think Magic the Gathering) and the cards are pixel art characters using Aseprite for animations. So it looks like the pixel characters are doing an idle animation on the card.

The cards are basically 128x256. Meaning the top 128x128 is the character art. While the bottom 128x128 is all the text for the card. (Its essentially 2 squares stacked on top of each other to form a cards content.)

now MY ISSUE is that the way Aseprite importer works, it trims around the character getting rid of the canvas empty space. (I have it blank behind the character so I can have the texture of the card behind the character.

So now when I place characters into the cards playing their animation, they are all bouncing around and shaking because the way their frames are trimmed. As well as scaled improperly because they are stretched to fit the size of their UI canvas on the card.

For example:
I have a little goblin character who is about 45x45 within the 128x128 canvas.

I have a dinosaur character who is 128x128 within the 128x128 canvas.

But now the Goblin is scaled up to the size of the dinosaur and the pixels massive.

The only “Solution” I could come up with is forecfully adding a background layer in Aseprite covering the entire canvas. So now the Aseprite Importer properly makes the entire 128x128 canvas a frame. (But now I have an ugly square behind my characters. :sob: )

I have 600+ pixel characters and all have their own Idle animation that is 8-12frames long using Aseprite. I dont want to have to manually slice them create new animation clips dragging and dropping thousands of frames. So I hope you can understand my troubles. So would appreciate some tips or a solution built-in.

(Same thing happened for me. Didn’t get any notification from discussions. I’ll poke the team to see if this is a bug)

Which version of Unity & Aseprite Importer are you using?

For example:
I have a little goblin character who is about 45x45 within the 128x128 canvas.
I have a dinosaur character who is 128x128 within the 128x128 canvas.
But now the Goblin is scaled up to the size of the dinosaur and the pixels massive.

I don’t follow, why is the Goblin scaled up to the size of the dinosaur? is it because you are using Image components instead of SpriteRenderer? If that is the case, then it would be interesting to understand a bit more about your setup and how we can make it work better with Aseprite Importer. Feel free to DM me with more information.

1 Like

I’m using Unity 6000.0.28f1 and Asprite 1.1.8.

I think, maybe, the notifications only happen when we @Ted_Wikman each other. I could be wrong though.

Ok, I’ll keep an eye out to see if we get more reports similar to yours. Unfortunately, I can’t do much to help you without getting the issue myself.

Regarding the notifications, I asked the team, and after enabling email notifications (under Settings > Email) I now get an email when people are interacting in the threads I’ve written in. Hope that helps!

This has been an issue for me as well. I dont know if my workflow is just wrong, but for me the intuitive workflow is that if I set a sprite in aseprite to a set size, the size should be preserved even if it contains alpha cells. I have the same issue when using the seprite importer in Godot, so I assume its probably an aseprite issue, but I can try and explain the workflow.

Say I create a simple 16x16 sprite of an arrow

I then animate the position of the arrow to move down over 8 frames

The importer then generates an animation clip and animation controller and on the actual aseprite object, the animation looks correct

However when the animation clip is opnened it shows that all the sprites are the exact same and the offset is not preserved even though the pivot space is set to canvas. The entire animation is now just a stationary sprite.

If you set it to import as a spritesheet instead of an animated sprite, all the frames look to be in the same cell location as well. It almost looks like they have changed their offsets
Unity

Separately generated spritesheet in aseprite

Using Unity Version 6000.0.56f1
Aseprite version 1.3.15.2