← Blog
·26 min read·SpriteForge Team·Godot

Building 2D Character Animations for Godot with Sprite Sheets

Godot-specific workflow: AnimatedSprite, AtlasTexture, FPS, and importing sprite sheet metadata into Godot 4.

Godot 4 sprite sheet pipeline PNG + JSON AtlasTexture AnimatedSprite2D Play Steps 1. Export in Godot format (regions: name, x, y, w, h). 2. Import PNG as Texture2D; create AtlasTexture per region from JSON (script). 3. AnimatedSprite2D + AnimationLibrary keyframe frame or texture swap; match FPS to export. 4. One texture + many AtlasTextures = fewer draw calls than many separate textures. Tip: Script region creation for many frames; keep FPS consistent between export and playback.

Godot 4's 2D pipeline uses textures and either individual Texture2D resources or atlases via AtlasTexture. For character or object animation, the typical flow is: one PNG sprite sheet, one metadata file that describes each frame's region, then an AnimatedSprite2D (or manual Sprite2D + script) that switches textures or atlas regions over time. This guide walks through export format, setting up the atlas, animation playback, and performance so you can get sprite sheets from an external tool into Godot and playing correctly.

Export Format for Godot

When you export from a sprite sheet or atlas tool, choose the Godot format if available. The format usually describes the main texture and then a list of named regions (name, x, y, width, height) and optionally margins. Godot doesn't parse every possible JSON shape natively; it expects a specific structure (see AtlasTexture). Check your tool's docs: it may export a format that Godot's importer understands, or you may need to write a small script that reads your JSON and creates AtlasTexture resources that reference the main texture and the correct region.

Common fields in Godot-style metadata include the path to the image file and an array of regions, each with a name and a rect (position and size). If your tool exports generic JSON with frame names and rects, you can map that to AtlasTexture in an import script or an editor plugin. Keeping frame names consistent (e.g. run_0, run_1) makes it easier to build animations by name in the Godot editor.

What the JSON should contain

At minimum you need, per frame: a unique name (or index), and x, y, width, height in pixels. Some formats also include margin, source size, or duration. Your import script or tool maps these to AtlasTexture region rects. If the tool exports "Godot" format, the structure may already match what an existing Godot plugin or script expects; otherwise treat it as generic and write a small adapter.

Setting Up the Atlas in Godot

Import the PNG as a texture (Texture2D). Create an AtlasTexture for each frame: set the Atlas to your main texture and set the Region rect to the frame's x, y, width, height from your metadata. You can do this by hand for a few frames, but for dozens of frames it's better to script it: load the JSON, iterate regions, create an AtlasTexture per region, and save them as resources or reference them from an Array.

An import script can run when the PNG is imported: read the companion JSON (e.g. same base name with .json extension), create an AtlasTexture for each region, and either attach them to a resource that the game loads or write them as separate .tres files. That way every time you re-export the sheet and reimport in Godot, the atlas setup is regenerated automatically. Alternatively, use a standalone editor tool that runs on demand and generates the AtlasTexture resources.

Manual vs scripted setup

For a single sheet with a handful of frames, creating AtlasTextures by hand in the editor is feasible. For character sheets with 50+ frames or multiple characters, scripting saves time and avoids errors. The script can live in your project as an editor plugin or a one-off tool; the output is either a scene that references the AtlasTextures or a resource file that your game code loads and uses to drive the animation.

AnimatedSprite2D and FPS

In Godot 4, AnimatedSprite2D is driven by an AnimationLibrary and Animation that keyframe the frame property or swap the sprite's texture. Alternatively you can use a Sprite2D and a script that changes texture (or the atlas region) every frame based on elapsed time and FPS. Match the FPS in your script to the FPS you used when exporting the sprite sheet so that animation timing matches the original.

If your export tool provides frame duration in the metadata, you can use that to set keyframe spacing in the Animation: for example, 24 FPS means roughly 0.0417 seconds per frame. AnimatedSprite2D can also use an AnimationLibrary with an animation that lists sprite frames in order; the playback speed is then controlled by the animation's FPS or by the frame duration you assign. Keeping export FPS and in-engine FPS in sync avoids sped-up or slowed-down playback.

Building the animation in the editor

Create an AnimationLibrary and add an Animation. Add keyframes for the sprite's frame property (or texture), one keyframe per frame of the sheet, spaced by 1/fps seconds. Assign the AtlasTextures (or frame indices) in order. Set the animation to loop if needed. Attach the AnimatedSprite2D to your node, assign the library and animation name, and call play(). The same library can hold multiple animations (idle, walk, jump) if they're all on the same sheet; use different frame ranges for each.

AtlasTexture vs Multiple Textures

Using one texture and many AtlasTextures is more efficient than many separate texture files: one draw call per unique atlas, and batching works better. So the recommended pipeline is: one PNG, one set of region metadata, many AtlasTexture resources pointing at that PNG. Then your animation references those AtlasTexture resources (or their indices) when playing back.

If you have multiple characters or multiple sheets, each sheet becomes one Texture2D and one set of AtlasTextures. Avoid splitting a single logical sheet into many small textures just to match an old workflow; consolidating into one atlas per character or per scene usually improves performance. Godot's 2D renderer batches draw calls for sprites that share the same texture and material, so fewer textures mean fewer batches and better frame rate, especially on lower-end devices.

Troubleshooting

If animations play too fast or too slow, double-check that the keyframe interval matches your export FPS. If frames are misaligned or show the wrong part of the texture, verify the region rects in each AtlasTexture against the JSON. If you see tearing or flicker, ensure you're not swapping textures every frame from different atlases; keep one atlas per character or effect where possible.