Skip to content

Godot: How to create sprite sheets the easy way

Andreas Löw, Joachim Grill
Last updated:
Godot: How to create sprite sheets the easy way

 

You'd rather watch a video than read this blog post? Here's our Video Tutorial! Note that it was recorded with Godot 3 — the workflow is the same, but the editor looks different and the plugin is installed from the AssetLib.

Create sprite sheets

TexturePacker makes it easy to create optimized sprite sheets for Godot.

Download TexturePacker, which is available for macOS, Windows, and Linux. You can test it with a 7-day free trial before purchasing a license:

Start TexturePacker and drop the sprites you want to pack into a sprite sheet onto TexturePacker's main window. You can also drop entire folders, TexturePacker will automatically scan them for image files and add them to the sheet.

TexturePacker: Add sprites for packing
TexturePacker: Sprites added for packing

Click the Framework button at the top of the right sidebar and select Godot SpriteSheet as the data format. The sprite sheet data file contains each sprite's coordinates and size on the sheet, which is used later to automatically extract individual sprites from the sheet.

TexturePacker: Select Godot SpriteSheet framework

Use the Sprite sheet file field (below the framework button) to select the location and file name for the data file. The .tpsheet file extension is added automatically. The Texture file name can be left empty, TexturePacker will save the PNG sprite sheet image next to the data file.

When you save both the data and texture files in your Godot project directory, Godot will automatically reimport the sprite sheet whenever you update it with TexturePacker. No manual copying is required.

Press the Publish sprite sheet button in the toolbar (or the export button in the bottom right corner). This will save both the sprite sheet image and a .tpsheet file containing the sprite coordinates.

Install TexturePacker importer

Now switch to your Godot project. To import a sprite sheet not just as one large atlas image, but to also create a set of AtlasTextures for all individual sprites, you need to install the TexturePacker Importer plugin:

  • Open the Asset Store view
  • Search for "texturepacker"

The Asset Store replaces the older AssetLib in Godot 4.7. On older Godot versions, open the AssetLib view instead — the installation steps are the same. We provide the plugin for Godot 3.5 LTS and for Godot 4.3 - 4.6 there.

In this tutorial we use Godot 4.7.2.

Search for "texturepacker" in the Godot Asset Store
  • Click on the plugin
  • Download it
  • Install it

After installation, the plugin is still inactive. Press the Plugins... button to open the project settings. There you can enable the TexturePacker Importer:

Install TexturePacker Importer plugin

Import sprite sheets in Godot

As soon as you enable the TexturePacker Importer plugin, *.tpsheet files are automatically imported and the corresponding sprite sheet images are split. For each sprite, an AtlasTexture resource is generated. These can be found in a new folder with the .sprites suffix:

Imported sprite sheet

Drag and drop an AtlasTexture from the FileSystem view into your scene to create a Sprite2D node.

(If you started with an empty project, create a Node2D as the root node for the scene first.)

Create an animation

To add an animated sprite to the scene, use the + button on top of the Scene tree view to add an AnimatedSprite2D node.

  • Select the AnimatedSprite2D node
  • In the Inspector, click on the Sprite Frames property
  • Choose New SpriteFrames
Create SpriteFrames

Now click again on the Sprite Frames property. At the bottom of the editor, a new "Animation Frames" panel opens. You can drag and drop sprites from the FileSystem tab to the frame list:

Add sprites to SpriteFrames

With the Autoplay on Load button checked, the animation starts playing when your game is launched. Use the FPS field to configure the animation speed. For a preview of the animation in the scene viewport press the Play button:

Start the animation

If the animation should only play when a key is pressed, you can attach a script to the AnimatedSprite2D node:

extends AnimatedSprite2D

func _process(delta):
	# Play animation while right cursor key is pressed
	if Input.is_action_pressed("ui_right"):
		play()
	else:
		stop()

Let TexturePacker create the animations

Instead of collecting the frames by hand, you can let TexturePacker detect the animations and have the importer build them for you. This requires TexturePacker 8.2.0 or newer and version 4.8.0 of the TexturePacker Importer plugin.

Name your sprites so that each animation ends with a frame number — RunRight_0001.png, RunRight_0002.png, ... — and enable Auto-detect animations in TexturePacker's data settings. The frames are then grouped into sequences and written to the .tpsheet file.

On import, the plugin writes an AnimationLibrary next to the sprite sheet, named {sheet}.animations.tres. It holds one looping animation per sequence, running at 10 fps and named after the sprites it was built from — RunRight for the frames above. Sprites inside a folder keep the folder in their name, with the slashes replaced by dashes. Each animation animates the atlas, region and margin of a single AtlasTexture, so trimmed sprites play at the correct size and offset, and multipack sheets work as well.

To play such an animation in your scene:

  1. Drag the first frame of the animation from the sheet's .sprites folder into your scene, so that Godot creates a Sprite2D node for it. Select the node and click the chain icon next to its Texture property in the Inspector to make the texture unique: the animation modifies the texture, and without this the changes would be written back to the imported sprite.
  2. Add an AnimationPlayer as a child of the Sprite2D. Its Root Node then already points at the sprite, and no further setup is needed. The animations contain no node names, so the same library can drive any sprite.
  3. Select the AnimationPlayer to open the animation dock at the bottom of the editor. Click the Animation button there, choose Manage Animations..., and press Load Library to select the generated .animations.tres file. Godot names the library after the file, so the animations appear as character.animations/RunRight and have to be played under that name. Double-click the library's name in the dialog and clear it if you'd rather use the animation names on their own.
  4. Start the animation. Attach a script to the AnimationPlayer node and play the animation by its name:
extends AnimationPlayer

func _ready():
	play("character.animations/RunRight")

Sprites without a trailing frame number are imported as static sprites and get no animation.

The importer only rebuilds what each frame shows. The timing stays yours: drag the keys in the animation editor and they survive the next reimport, as long as you don't add or remove frames in TexturePacker. Add the .animations.tres file to your version control — it contains the timing you tuned by hand, not just generated data.

Using sprites with normal maps

The TexturePacker Importer plugin also supports sprites with normal maps, enabling dynamic lighting effects for your 2D sprites in Godot.

Sprite sheet with corresponding normal map sheet

Creating normal maps

If you don't have normal maps for your sprites yet, here are two helpful resources:

Automatic CanvasTexture creation

When your .tpsheet file links to a normal map, the TexturePacker Importer plugin automatically:

  1. Loads the normal map sprite sheet
  2. Creates a CanvasTexture for the sprite sheet that combines the diffuse texture with its corresponding normal map
  3. Saves this CanvasTexture resource in a subdirectory named CanvasTexture
  4. Uses the CanvasTexture instead of the diffuse texture when importing the sprite sheet and creating the sprite resources

Using sprites with normal maps

Using sprites with normal maps is just as simple as using regular sprites:

  • Drag and drop the sprites from the FileSystem view into your scene or animation
  • No additional configuration is needed

To see the effect of the normal maps, add a DirectionalLight2D to your scene:

Lit sprite which too much ambient light

You might notice that the sprite appears quite bright. This is because the global light illuminates the sprite, making it look like a sprite in a scene without additional light sources. The light from the additional light source is added to this global light.

To fix this, add a CanvasModulate node to the scene and set its color to black (or a dark color that you want to use for ambient light). This makes the sprite unlit by default, allowing you to clearly see the effect of the directional light.

Lit sprite with some ambient light

To configure the direction of the light, change the Rotation property in the Transform section of the DirectionalLight2D node.

Using texture compression

Texture compression reduces the amount of GPU memory a texture occupies and can speed up rendering. Unlike PNG or JPEG, which are decompressed into raw pixels before they reach the GPU, compressed textures stay compressed in video memory. This means lower memory usage and faster texture uploads.

Godot supports KTX and KTX2 files with ASTC, ETC1/ETC2, DXT (S3TC) and Basis Universal (KTX2 only) compression, which can be generated with TexturePacker. For a full overview of all formats supported by TexturePacker, see Texture compression.

FormatbppPlatform
ASTC0.89 - 8iOS, modern Android
ETC14All OpenGL ES devices (no alpha)
ETC24 - 8OpenGL ES 3.0+
DXT14Desktop (1-bit transparency)
DXT58Desktop (full alpha)
Basis UniversalvariableAll platforms (KTX2 only)