Skip to content

Aseprite to Unity 6 — Sprites and Animation Clips

Drop the .aseprite file and export a Unity bundle: the atlas, a JSON description and a small editor script that slices the sprites (Point, uncompressed) and creates one AnimationClip per tag with its frame timing.

Unity cannot play an .aseprite file by itself: it needs sprites on a texture and an AnimationClip per animation. Drop the file into Nerulio, check its tags, and export for Unity 6: you get the packed PNG, a JSON and an editor script that, from Tools › Nerulio › Import Studio JSON, slices the texture (Point, uncompressed, pivots from your pivot slice) and writes one .anim per tag with every frame's own duration. Reverse and ping-pong tags are written out frame by frame. Checked in Unity 6000.5.3f1; Unity's own 2D Aseprite Importer package is the alternative.

Drop a sprite sheet, numbered frames, a GIF / APNG or an .aseprite file
Runs in your browser. Files are not uploaded.
Studio Sprite workspace: one frame with its pivot, a hit box and a hurt box, and the timeline with animation tags
The real Studio with a CC0 asset (OpenGameArt).
Exports to
  • Unity 6Verified· Unity 6000.5.3f1
  • .asepriteVerified· Aseprite 1.3.18
  • Godot 4Verified· Godot 4.7.2
  • Phaser 3 / 4Verified· Phaser 3.90 + 4.2
  • PixiJS 8Verified· PixiJS 8.21
  • Aseprite JSONVerified· Phaser load.aseprite · PixiJS 8.21
  • Spine / libGDXVerified· spine-canvas 4.2
  • Starling / Sparrow XMLVerified· Phaser 4.2
  • LÖVEVerified· LÖVE 11.5
  • DefoldBuilt· Defold bob.jar 1.13.1
  • GameMakerUNVERIFIED
  • CSS spritesVerified· Chromium
  • GIF / APNGDecoded· Pillow

From Aseprite tags to Unity clips

An .aseprite file stores frames with a duration in milliseconds each, tags that name a frame range with a direction (forward, reverse, ping-pong) and a repeat count, layers, and slices that can carry a pivot. Unity's equivalent is a texture in Sprite Mode Multiple, one sprite per frame with a normalised pivot, and an AnimationClip whose keys swap the SpriteRenderer's sprite at given times.

Nerulio composites the visible layers of every frame, packs the frames and writes their rects in Unity's bottom-left coordinates. Each tag becomes a clip whose keys sit at the running sum of the frame durations, plus a closing key so the last frame lasts its full time. A tag that repeats forever gets Loop Time on; a tag with a repeat count gets Loop Time off, because a clip has no repeat count.

Unity's own 2D Aseprite Importer (version 4.x needs Unity 6.4 or later) imports the file directly and reimports it on save. According to its documentation it supports individual frame timings and turns ∞ into a looping clip, but only the Forward direction is supported and slices are not imported.

Tag
A named frame range in Aseprite with a direction and a repeat count.
Pivot slice
An Aseprite slice with a pivot point; Nerulio uses it as each frame's pivot.
Loop Time
The AnimationClip setting that makes a clip repeat.
Closing key
A final key that repeats the last sprite so it keeps its own duration.

Example: a 32 × 32 hero with three tags

Aseprite                                 Unity 6 AnimationClip (key times, s)
idle    4 frames × 125 ms, ∞             idle.anim    0, 0.125, 0.25, 0.375 | end 0.5    loop on
attack  100, 100, 150, 250 ms, ×1         attack.anim  0, 0.1, 0.2, 0.35 | end 0.6        loop off
jump    3 frames × 80 ms, ping-pong       jump.anim    frames 0-1-2-1: 0, 0.08, 0.16, 0.24 | end 0.32

pivot slice at (16, 31) on the 32 × 32 canvas, frame not trimmed
  Unity pivot = (16 / 32, (32 − 31) / 32) = (0.5, 0.03125)   (y counts up)

The ping-pong tag is written as the order 0-1-2-1, so it plays the same in Unity without relying on a direction setting.

What survives the conversion

In AsepriteIn NerulioIn Unity 6
Frame pixels (visible layers)Composited frame, packed into the PNGOne sprite rect of that texture
Frame duration (ms)Kept per frameKey time: each frame starts at the sum of the previous durations
TagOne animation of the same nameOne .anim clip of the same name
Direction reverse / ping-pongPlayback order written outKeys in that order
Repeat ∞LoopLoop Time on
Repeat 1, 2, 3…Plays that many times in the previewLoop Time off: the clip plays once
Pivot slice (or a pivot set with P)Frame pivot (default bottom centre)Sprite pivot, Custom alignment, y up
Hit / hurt slicesBoxes per frameNot written for Unity (they are in the generic JSON)
LayersCompositedOne sprite per frame, no per-layer sprites

What it does

  • Tags become AnimationClips with each frame's duration; pivots come from Aseprite slices or the Studio's pivot tool.
  • Sprite Mode Multiple, Point filter, no compression — the settings pixel art needs.
  • Rects, pivots, pixels, clip keys and durations were checked in Unity 6000.5.3f1 batch mode.
  • No Unity package or Aseprite importer needed on your side.

How to do it

  1. Drop the .aseprite file and check the tags.
  2. Open Pack & Export and choose Unity 6.
  3. Copy the bundle into Assets/ (the Editor folder with it).
  4. Run Tools › Nerulio › Import Studio JSON: it slices the sheet and builds the clips.

Files you get

FileWhat it is for
hero.pngThe packed frames (Point-friendly: trimmed, 2 px apart, never rotated).
hero.unity.jsonSprite rects in Unity coordinates, normalised pivots, and one clip per tag with each frame's milliseconds and loop flag.
Editor/NerulioSpriteImporter.csThe editor script: texture settings, sprite rects, .anim clips.
README-UNITY.mdThe import steps for this bundle.

Import it into Unity 6

  1. Copy the bundle folder into Assets/, PNG next to the JSON, with its Editor subfolder. Unity compiles the script; the 2D Sprite package must be installed (it is in every 2D template).
  2. Run Tools › Nerulio › Import Studio JSON and pick hero.unity.json.
  3. Check the texture: Sprite (2D and UI), Multiple, Point (no filter), Compression None, PPU 100; the Sprite Editor shows one rect per frame with its pivot.
  4. Find idle.anim, attack.anim and jump.anim next to the JSON; open one in the Animation window to see its keys.
  5. Add the clips to an Animator Controller on a GameObject with a SpriteRenderer; for a play-once tag such as attack, add a transition back to idle when it ends.
  6. Keep the .aseprite file itself out of Assets/ if Unity's Aseprite Importer package is installed, or Unity imports it a second time its own way.

Check the result

  • attack.anim has keys at 0, 0.1, 0.2 and 0.35 s and ends at 0.6 s, the total of the tag in Aseprite.
  • Loop Time is on for idle and off for attack.
  • Play jump next to Aseprite's preview: the order 0-1-2-1 and the 80 ms steps match.
  • Switch clips: the feet stay on the pivot point.

Troubleshooting

SymptomLikely causeHow to checkFix
A clip plays once instead of loopingThe tag has a repeat count in Aseprite (anything but ∞)Loop Time in the clip's InspectorSet the tag to ∞ and export again, or tick Loop Time in Unity
Console: "clip … names a missing sprite"The PNG was renamed or moved away from the JSON before importingIs the PNG next to the JSON with its exported name?Keep the files together and run the import again
The sprite is blurryFilter Mode or compression was changed after the importTexture InspectorPoint (no filter) and Compression None; see blurry pixel art in Unity
The character jumps between framesNo pivot slice, so each frame uses the default bottom centre, or pivots differ per frameSprite Editor: pivot markers across framesAdd one pivot slice in Aseprite or set pivots with P in Nerulio; see the pivot editor
Two copies of every sprite appearUnity's Aseprite Importer also imported the .aseprite file placed in Assets/Project window shows the .aseprite asset expandedUse one route: remove the .aseprite from Assets/, or skip this bundle
A ping-pong tag plays only forwardsThat is Unity's own importer (forward only), not this bundleWhich asset does the Animator use?Use the .anim from this bundle, which has the order written out

Other ways to do it

OptionWhen it is the better choice
Unity's 2D Aseprite Importer packageYou edit in Aseprite all day and want Unity to reimport on save, with per-layer import; accept forward-only tags and no slices.
Export a PNG sheet from Aseprite and slice it in the Sprite EditorOne or two animations at an even frame rate; see slicing a sprite sheet in Unity.
The same file for another engineAseprite to Godot or Aseprite to Phaser.

Engine exports and how each was checked

"Verified" means the exported files were loaded by the real engine or tool on real CC0 assets and the result was compared with the source. Anything that was not loaded is labelled as such.

TargetFilesCheck
Godot 4.tres SpriteFrames · .tscn AnimatedSprite2D · .png.importVerified Godot 4.7.2Loaded by Godot; every animation frame drawn and compared with the source file. The scene uses Nearest filtering; rotation is never used.
Unity 6.unity.json · Editor/NerulioSpriteImporter.cs · AnimationClipVerified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked.
Phaser 3 / 4atlas JSON (multiatlas) · .anims.jsonVerified Phaser 3.90 + 4.2Frames and animations drawn by both versions.
PixiJS 8spritesheet JSON · animations · anchor · meta.scaleVerified PixiJS 8.21Rotated and multi-page atlases included.
Aseprite JSONhash / array · frameTags · slicesVerified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count.
.asepritelayers · tags · durations · slicesVerified Aseprite 1.3.18Opened and rendered by the Aseprite command line.
Spine / libGDX.atlasVerified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run.
Starling / Sparrow XMLXML per pageVerified Phaser 4.2Phaser 3.90 draws trimmed XML frames wrongly (its own bug); the "Sparrow XML (Phaser 3)" preset turns trim off and passes in 3.90 and 4.2.
LÖVELua quads · nerulio_atlas.lua · main.luaVerified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper.
Defold.atlas · .tilesourceBuilt Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back.
GameMakerspr_<name>_stripN.png · gamemaker.jsonUNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them.
CSS sprites.css · preview .htmlVerified ChromiumEvery class drawn from the shipped stylesheet.
GIF / APNGone file per animationDecoded PillowEvery frame and delay decoded again after export; APNG is exact.

Evidence

GIF decoder: 408 of 408 frames identical to Pillow on 29 real GIFs; APNG 132 of 132 on 16 files. .aseprite: 231 corpus files imported, re-written and reopened in Aseprite 1.3.18 with the same tags, durations and pixels (231/231). Exports: 49 runs in the real engines on real CC0 assets, 47 pass — the 2 failures are Phaser 3.90's trimmed-XML bug, which the Phaser 3 preset avoids.

Limits

  • Layers arrive flattened into one sprite per frame.
  • A repeat count above one is not kept: the clip plays once.
  • Hit and hurt boxes are not written for Unity.
  • A grid or island guess is a preview with a confidence; nothing is cut until you press Apply, and every choice has one-click alternatives.
  • .aseprite files whose layers do not compose exactly (e.g. group opacity) are imported flattened, and the Import panel says why.
  • Rotated frames in an imported atlas stay rotated; their export is UNVERIFIED.
  • Images up to 32,768 px per side (268 million pixels), subject to your browser's memory.

Versions and sources

Nerulio's Unity bundle was checked in Unity 6000.5.3f1 batch mode (sprite rects, pivots, pixels, Point / Uncompressed / Multiple, clip keys and times); clips playing through an Animator at runtime were not checked. The .aseprite reader reopened 231 real files in Aseprite 1.3.18 with the same tags, durations and pixels. What is said about Unity's own Aseprite Importer comes from its version 4.0 documentation.

Official documentation used

Questions

Why not Unity's own Aseprite importer?

You can use it. This route gives a packed atlas and clips from the same timing, and it works on machines without the importer package.

Does it keep one pivot per frame?

Yes, each sprite rect gets its frame's pivot (a common anchor when the frames share one).

Is it free, and do I need an account?

Everything on these pages is free and works without an account. There is no watermark and no export that is held back.

Are my sprites uploaded?

No. The Studio decodes, packs and exports in this browser tab. Projects are autosaved in the browser (IndexedDB) and can be saved as a .nerulio file.

Does it need Aseprite or an engine plugin installed?

No. .aseprite files are read and written in the browser, and each engine bundle carries what that engine needs (for Godot, the import settings and scene; for Unity and the Godot TileSet, a small editor script).