HomeUse cases › Import a sprite sheet into Godot
Godot 4 tutorial · AnimatedSprite2D

How to import a sprite sheet into Godot.

A complete, accurate Godot 4 walkthrough: import a 4×4 walk sheet with crisp pixels, slice it in AnimatedSprite2D + SpriteFrames, build four directional walk animations, and play them from CharacterBody2D input.

Make a sprite — $5
No account · ZIP in minutes · money-back if it fails QA (handled manually during beta)

What you need before you start

This tutorial assumes Godot 4 and a 4×4 walk-cycle sprite sheet — 16 frames in four rows: down, left, right, up, four frames each. That is exactly the layout PixelForge produces, but any evenly-gridded sheet works the same way. The whole job is four moves: import the PNG without blurring it, slice the grid, name four animations, and play them from input.

Godot 3 vs 4 note: in Godot 3 the node was AnimatedSprite and bodies used KinematicBody2D. In Godot 4 they are AnimatedSprite2D and CharacterBody2D, and move_and_slide() reads and writes the node's velocity property instead of taking it as an argument.

Import the sprite sheet into Godot 4

Drag your sprite_sheet.png into the project's res:// folder in the FileSystem dock. By default Godot applies linear filtering, which smears pixel art into a blur the moment it is scaled. Fix it before you do anything else:

01

Open the Import tab

Click the PNG in FileSystem, then the Import tab (top-left, next to Scene).

02

Filter → Nearest

Set Texture > Filter to Nearest, then click Reimport.

03

Or set it project-wide

Project Settings → Rendering → Textures → Default Texture Filter → Nearest.

Setting the Default Texture Filter to Nearest once in Project Settings makes every new sprite crisp by default, so you do not have to touch the Import tab for each file.

Slice the sheet in AnimatedSprite2D

Now turn the single image into 16 named frames using AnimatedSprite2D and a SpriteFrames resource — Godot's built-in flipbook for sprite-sheet animation.

NodeAnimatedSprite2D
ResourceSpriteFrames (New)
Slicer buttonAdd frames from a Sprite Sheet
GridHorizontal 4 · Vertical 4
Frames total16 (4 rows × 4)
  1. Add an AnimatedSprite2D node to your scene.
  2. With it selected, open the Inspector, find the Sprite Frames property, click it, and choose New SpriteFrames. A SpriteFrames panel docks at the bottom of the editor.
  3. In that panel, click Add frames from a Sprite Sheet (the grid icon) and open your PNG. The slicer dialog opens.
  4. Set Horizontal to 4 and Vertical to 4. The preview snaps to a 4×4 grid of 16 cells.

Build the four directional animations

One sheet, four loops. In the SpriteFrames panel you create one animation per direction and feed it the right row of the grid.

  1. Rename the existing default animation to walk_down.
  2. In the slicer, click the four cells of the down row (the top row on a PixelForge sheet) and press Add N frames.
  3. Back in the panel, click + to add walk_left, then re-open the slicer and add that direction's row. Repeat for walk_right and walk_up.
  4. For each animation set Speed (FPS) to about 8–10 and switch Loop on so the walk cycle repeats. Optionally set one as Autoplay to preview it in the editor.
Row order matters. PixelForge sheets are ordered down, left, right, up, top to bottom. Match each animation to its row and your sprite will face the direction it walks. (If you skipped left or right, you can flip one horizontally in code with $AnimatedSprite2D.flip_h = true.)

Play the walk cycle from input

Attach a script to a CharacterBody2D (with the AnimatedSprite2D as a child) and drive the right animation from the player's input. This is the standard Godot 4 top-down pattern — read a direction, set velocity, call move_and_slide(), and play() the matching loop.

player.gd · Godot 4 / GDScript
extends CharacterBody2D

const SPEED = 90.0
@onready var anim = $AnimatedSprite2D

func _physics_process(_delta):
    var dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = dir * SPEED
    move_and_slide()

    if dir == Vector2.ZERO:
        anim.stop()
    elif abs(dir.x) > abs(dir.y):
        anim.play("walk_right" if dir.x > 0 else "walk_left")
    else:
        anim.play("walk_down" if dir.y > 0 else "walk_up")

Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") returns a normalized direction from the built-in arrow-key actions (in Godot 4, move_and_slide() uses the node's velocity — you do not pass it in). The if/elif/else picks whichever axis dominates so the sprite shows one clean direction at a time and calls, e.g., $AnimatedSprite2D.play("walk_down"). Press F6 to run the scene and walk around.

That's the whole import

Import crisp → add AnimatedSprite2D → New SpriteFrames → Add frames from a Sprite Sheet at 4×4 → name walk_down / walk_left / walk_right / walk_upplay() from input. Same steps for an attack or idle sheet later — just more rows, more animations.

Don't have a sprite sheet yet? PixelForge turns a photo into this exact 4×4 walk sheet — 16 transparent frames, ordered down / left / right / up, ready to slice in AnimatedSprite2D — for a one-time $5. See photo to game sprite or the Godot character sprites guide.

Frequently asked questions

AnimatedSprite2D vs AnimationPlayer — which should I use?

For a sprite sheet, use AnimatedSprite2D. It is purpose-built to flip through frames stored in a SpriteFrames resource, so slicing a 4×4 walk sheet and calling play("walk_down") is just a couple of clicks. AnimationPlayer is a general timeline that keyframes any property (position, modulate, calling functions); reach for it when you need to coordinate movement, effects, and audio together, not for a simple looping walk cycle.

Why does my sprite look blurry in Godot?

Godot applies linear texture filtering by default, which smooths pixels into a blur when they scale up. Fix it by setting Texture > Filter to Nearest on the PNG's Import tab (then Reimport), or set it everywhere at once via Project Settings → Rendering → Textures → Default Texture Filter → Nearest. Nearest-neighbor keeps every pixel a crisp, hard-edged square.

How do I get 4-direction movement from one sheet?

Slice the sheet at Horizontal 4 / Vertical 4, then build four animations — walk_down, walk_left, walk_right, walk_up — each from its own row (PixelForge order is down, left, right, up). In a CharacterBody2D script, read input with Input.get_vector(...), compare the X and Y magnitudes to pick the dominant direction, and call the matching $AnimatedSprite2D.play("walk_…") before move_and_slide().

What are the Godot 3 vs Godot 4 differences for this?

The workflow is the same, but several names changed. The node AnimatedSprite became AnimatedSprite2D, and KinematicBody2D became CharacterBody2D. The biggest gotcha: in Godot 4 move_and_slide() takes no arguments and instead reads/writes the body's built-in velocity property, whereas in Godot 3 you passed velocity in and reassigned the return value. The SpriteFrames panel and Add frames from a Sprite Sheet slicer work the same in both.

Can I import a sprite sheet without slicing it cell by cell?

Yes — that is exactly what Add frames from a Sprite Sheet does. You set Horizontal and Vertical once and Godot cuts the whole grid into evenly sized frames automatically; you just click the cells you want for each animation. You do not have to import 16 separate PNGs or crop anything by hand, as long as the sheet is on an even grid (a PixelForge 4×4 sheet is).

Put anyone into your game.

$5 · one photo · 4-direction walk pack · no subscription

Make a sprite — $5