Godot Engine 4.0 Documentation - Manual - 2D

This article is the result of Google Translate's English translation, and DrGraph added some corrections on this basis. English original page:

2D — Godot Engine (stable) documentation in English

Canvas Layer¶

Viewport and Canvas Items¶

CanvasItem is the basis of all 2D nodes, whether regular 2D nodes such as Node2D or Control . Both inherit from CanvasItem . You can arrange canvas items in a tree. Each item will inherit its parent's transform: when the parent moves, its children move too.

CanvasItem nodes and nodes that inherit from them are direct or indirect children of the Viewport that displays them .

The viewport's property  Viewport.canvas_transform allows custom Transform2D  transformations to be applied to the CanvasItem hierarchy it contains. Nodes like Camera2D work by changing that transform.

To achieve effects such as scrolling, manipulating the canvas transform properties is more efficient than moving the root canvas item and the entire scene.

But usually, we don't want everything in our game or application to be subject to canvas transforms. For example:

  • Parallax Background : A background that moves slower than the rest of the stage.

  • UI : Imagine a user interface (UI) or heads-up display (HUD) superimposed on our game world view. We want life counters, score displays, and other elements to maintain their on-screen position even as our view of the game world changes.

  • Transitions : We may want visual effects for transitions (fade, blend) to remain at a fixed screen position.

How to solve these problems in a single scene tree?

Canvas Layers¶

The answer is CanvasLayer , a node that adds a separate 2D rendering layer to all its children and grandchildren. By default, viewport children will be drawn at layer "0", while CanvasLayer will be drawn at any number layer. Layers with higher numbers will be drawn on top of layers with lower numbers. CanvasLayers also have their own transformations that do not depend on the transformations of other layers. This allows the UI to stay fixed in screen space while our view of the game world changes.

An example of this is creating parallax backgrounds. This can be done with a CanvasLayer of "-1" layer. Screens with scores, life counters and pause buttons can also be created on the "1" level.

Here's what it looks like:

CanvasLayers are independent of the order of the tree, they only depend on their layer number, so they can be instantiated when needed.

notes

CanvasLayers don't need to control the order in which nodes are drawn. The standard way to ensure that nodes are correctly drawn "in front" or "behind" is to manipulate the order of the nodes in the scene panel. Perhaps counterintuitively, the topmost nodes in the scene pane are drawn behind the lower nodes in the viewport. 2D nodes also have a CanvasItem.z_index property that controls the order in which they are drawn .

Viewport and Canvas Transforms¶

Introduction¶ _

This is an overview of the 2D transformation a node takes from what it draws locally to what it draws to the screen. This overview discusses the very low-level details of the engine.

Canvas Transform¶

As mentioned in the previous tutorial Canvas layers , each CanvasItem node (remember, Node2D and Control based nodes use CanvasItem as their common root) will reside in a Canvas Layer . Each canvas layer has a transform (translation, rotation, scaling, etc.) that can be accessed as a Transform2D .

As also introduced in the previous tutorial, nodes are drawn in layer 0 of the built-in canvas by default. To place nodes in different layers, you can use CanvasLayer nodes.

Global Canvas Transform¶

The viewport also has a Global Canvas transform (also a  Transform2D ). This is the master transform and affects all individual canvas layer transforms. Generally, this transform is not very useful, but it is only used in the CanvasItem Editor in Godot's editor.

Stretch Transform¶

Finally, the viewport has a Stretch Transform that is used when resizing or stretching the screen. This transform is used internally (as described in Multiresolution ), but can also be set manually on a per-viewport basis.

Input events multiply this transition but lack the ones above. In order to convert InputEvent coordinates to local CanvasItem coordinates, the CanvasItem.make_input_local() function is added for convenience .

Transform order¶

To make the coordinates in the CanvasItem local properties be actual screen coordinates, the following chain of transformations must be applied:

Transformation functions¶

Getting each transformation can be achieved with the following function:

type

convert

canvas project

CanvasItem.get_global_transform()

canvas layer

CanvasItem.get_canvas_transform()

CanvasLayer+GlobalCanvas+Stretch

CanvasItem.get_viewport_transform()

Finally, then, to convert a CanvasItem's local coordinates to screen coordinates, simply multiply in the following order:

GD script C#
var screen_coord = get_viewport_transform() * (get_global_transform() * local_pos)

But keep in mind that usually you don't want to use screen coordinates. The recommended approach is to simply work in Canvas coordinates ( ) CanvasItem.get_global_transform()to allow automatic screen resolution adjustments to work properly.

Provide custom input events¶

It is often necessary to feed custom input events to the scene tree. Armed with the above knowledge, to do this correctly, one must proceed as follows:

GD script C#
var local_pos = Vector2(10, 20) # local to Control/Node2D
var ie = InputEventMouseButton.new()
ie.button_index = MOUSE_BUTTON_LEFT
ie.position = get_viewport_transform() * (get_global_transform() * local_pos)
get_tree().input_event(ie)

2D Lights and Shadows¶

Introduction¶ _

By default, 2D scenes in Godot are unshaded, with no visible lights and shadows. While rendering is fast, unshaded scenes can look flat. Godot provides the ability to use real-time 2D lighting and shadows, which can greatly enhance a project's sense of depth.

No 2D lights or shadows, the scene has no shadows¶

Enable 2D lights (no shadows)

Enable 2D lights and shadows¶

node¶ _

A complete 2D lighting setup involves several nodes:

CanvasModulate is used to darken the scene by specifying a color that will act as the base "ambient" color. This is the final lighting color for areas that cannot be reached by any 2D lights. Without the CanvasModulate node, the final scene would look too bright, as the 2D lights would just illuminate the existing unshaded appearance (look fully lit).

Sprite2D is used to display the texture of the flare, background and shadow caster.

PointLight2D is used to light the scene. The way lights usually work is by adding selected textures to the rest of the scene to simulate lighting.

LightOccluder2D is used to tell the shader which parts of the scene cast shadows. These occluders can be placed as standalone nodes, or as part of a TileMap node.

Shadows only appear in the area covered by the PointLight2D , and their orientation is based on  the Light 's center.

notes

The background color does not receive any lighting. If you want the ray to hit the background, you need to add a visual representation of the background, such as a Sprite2D.

Sprite2D's region properties are helpful for quickly creating repeating background textures, but remember to also set  Texture > Repeat to Enabled in the Sprite2D's properties.

Point Light¶

Point lights (also known as position lights) are the most common element in 2D lighting. Point lights can be used to represent light from torches, fire, projectiles, and more.

PointLight2D provides the following properties to adjust in the inspector:

  • Texture: The texture used as the light source. The size of the texture determines the size of the light. Textures may have an alpha channel, which is useful when using Light2D's Mix blending mode, but not required if using Add (default) or Subtract blending modes.

  • Offset: The offset of the light texture. Unlike moving light nodes, changing the offset does not cause shadows to move.

  • Texture Scale: A multiplier for the size of the light. Higher values ​​will extend the light farther. Larger lights have a higher performance cost as they affect more pixels on the screen, so consider this before increasing the size of the lights.

  • Height: The virtual height of the light relative to the normal map. By default, rays are placed very close to the surface receiving the ray. This will make the lighting almost invisible if using a normal map, so consider increasing this value. Adjusting the height of the light will only make a noticeable difference on surfaces using normal maps.

If you don't have a premade texture to use in your lights, you can use this "neutral" point light texture (right click > save image as... ):

Neutral Light Texture¶

If you need a different falloff, you can create the texture procedurally by assigning a New GradientTexture2D on the light's Texture property. After creating the resource, expand its Fill section and set the fill mode to Radial . Then you have to adjust the gradient itself to start from opaque white to transparent white and move it's starting position to the center.

Directional Light¶

New in Godot 4.0 is the ability to do directional lighting in 2D. Directional lighting is used to represent sunlight or moonlight. The rays are projected parallel to each other, as if the sun or moon were infinitely far from the surface receiving the rays.

DirectionalLight2D provides the following properties:

  • Height: The virtual height of the light with respect to the normal map ( 0.0 =parallel to the surface, 1.0=perpendicular to the surface). By default, the ray is exactly parallel to the surface receiving the ray. This will make the lighting almost invisible if using a normal map, so consider increasing this value. Adjusting the height of the light will only make a visual difference on the surface using the normal map. Height does not affect the appearance of the shadow.

  • Max Distance: The maximum distance (in pixels) between the object and the object at the center of the camera before culling shadows. Decreasing this value prevents objects outside the camera from casting shadows (while also improving performance). Max Distance doesn't take into account Camera2D scaling, which means that at higher zoom values ​​shadows seem to fade out faster when zoomed to a given point.

notes

Directional shadows always appear infinitely long, regardless of the value of the Height property. This is a limitation of the shadow rendering method used in Godot for 2D lights.

To get directional shadows that are not infinitely long, you should disable shadows in DirectionalLight2D and use a custom shader that reads from a 2D signed distance field instead. This distance field is automatically generated from the LightOccluder2D nodes present in the scene.

Common Light Properties¶

Both PointLight2D and DirectionalLight2D provide public properties, which are part of the Light2D base class:

  • Enabled: Allows toggling the visibility of the light. Unlike hiding light nodes, disabling this property does not hide the light's child nodes.

  • Editor Only: If enabled, the light is only visible within the editor. It will be automatically disabled in running projects.

  • Color: The color of the light.

  • Energy: An intensity multiplier for light. Higher values ​​produce brighter light.

  • Blend Mode: The blend formula used for light calculations. The default  addition is suitable for most use cases. Subtraction can be used for negative light, not physically accurate but useful for special effects. The Mix blending mode mixes the pixel value corresponding to the light texture with the pixel value below it by linear interpolation .

  • Range > Z Min: The lowest Z index affected by light.

  • Range > Z Max: The highest Z index affected by light.

  • Range > Layer Min: The lowest visual layer affected by light.

  • Range > Layer Max: The highest visual layer affected by light.

  • Range > Item Cull Mask: Controls which nodes receive light from this node, depending on which other nodes have the visibility layer Occluder Light Mask enabled . This can be used to prevent certain objects from receiving light.

Setting shadows¶

After enabling the Shadow > Enabled property on a PointLight2D or DirectionalLight2D node , initially you won't see any visual difference. This is because the nodes in the scene do not yet have any occluders , which are used as the basis for shadow casting.

For shadows to appear in the scene, a LightOccluder2D node must be added to the scene. These nodes must also have occlusion polygons designed to match the outline of the sprite.

Along with their polygon resources (which must be set to have any visual effects), LightOccluder2D nodes have 2 properties:

  • SDF Collision: If enabled, occluders will be part of a signed distance field generated in real time and can be used in custom shaders. When not using custom shaders that read from this SDF, enabling it makes no visual difference and has no performance cost, so it is enabled by default for convenience.

  • Occluder Light Mask: This is used in conjunction with the Shadow > Item Cull Mask property of PointLight2D and DirectionalLight2D to control which objects cast shadows for each light. This can be used to prevent specific objects from casting shadows.

There are two ways to create shaders:

Automatically generate shaders¶

An occluder can be automatically created from a Sprite2D node by selecting the node, clicking the Sprite2D menu at the top of the 2D editor  , and selecting Create LightOccluder2D Sibling .

In the dialog that appears, an outline will surround the edges of your sprite. If the outline closely matches the edge of the sprite, you can click OK . If the outline is too far from (or "eroded" into) the edge of the sprite, adjust Grow (pixels) and Shrink (pixels) , then click Update Preview . Repeat this until you get a satisfactory result.

Draw shaders manually¶

Create a LightOccluder2D node, then select it and click the "+" button at the top of the 2D editor. Answer Yes when asked to create a polygon resource  . You can then start drawing the occlusion polygon by clicking to create a new point. You can delete existing points by right-clicking on them, or create new points from existing lines by clicking on the line and then dragging.

The following properties can be adjusted on a 2D light with shadows enabled:

  • Color: The color of the shaded area. By default, shadow areas are completely black, but this can be changed for artistic purposes. The alpha channel of the color controls how much the shadow is tinted by the specified color.

  • Filter: Filter mode for shadows. The default of None renders fastest and is ideal for games with a pixel art aesthetic (due to their "blocky" visuals). If you want soft shadows, use PCF5 instead  . PCF13 is softer, but the most demanding for rendering. Due to the high rendering cost, PCF13 can only be used for a few lights at a time.

  • Filter Smooth: Controls the degree of softening applied to shadows when Filter is set to PCF5 or PCF13 . Higher values ​​produce softer shadows, but may result in visible banding artifacts (especially when using PCF5).

  • Item Cull Mask: Controls which LightOccluder2D nodes cast shadows, depending on their respective Occluder Light Mask properties.

Hard Shadows¶

Soft Shadows (PCF13, Filter Smooth 1.5)

Soft shadows with streaking artifacts caused by Filter Smooth too high (PCF5, Filter Smooth 4)

Occluder drawing order¶

LightOccluder2Ds follow the usual 2D drawing order. This is important for 2D lighting, as this is how you control whether the occluder should occlude the sprite itself.

If the LightOccluder2D node is a sibling of the sprite , the occluder will occlude the sprite itself when placed below the sprite in the scene tree.

If the LightOccluder2D node is a child of a sprite,  the occluder will obscure the sprite itself if Show Behind Parent is disabled on the LightOccluder2D node (which is the default).

Normal and specular maps¶

Normal and specular maps can greatly enhance the perception of depth in 2D lighting. Similar to how these work in 3D rendering, normal maps can help make lighting look less flat by changing its intensity based on the direction a surface receives light (on a per-pixel basis). Specular maps further help improve visuals by bouncing some of the light back to the viewer.

Both PointLight2D and DirectionalLight2D support normal and specular maps. Starting with Godot 4.0, normal and specular maps can be assigned to any 2D element, including nodes inheriting from Node2D or Control.

The normal map represents the direction each pixel is "pointing". The engine then uses this information to correctly apply lighting to 2D surfaces in a physically plausible way. Normal maps are usually created from hand-painted height maps, but they can also be automatically generated from other textures.

The specular map defines how much light should be reflected (and in which color, if the specular map contains colors) per pixel. Brighter values ​​will produce brighter reflections at a given point on the texture. Specular maps are usually created through manual editing, using a diffuse texture as a base.

hint

If your sprites don't have normal or specular maps, you can use the free open source Laigter  tool to generate them.

To set a normal map and/or specular map on a 2D node, create a new CanvasTexture resource for the properties that paint the node's texture. For example, on Sprite2D:

Create CanvasTexture resource for Sprite2D node¶

Expand the newly created resource. You can find several properties to adjust:

  • Diffuse > Texture: Base color texture. In this property, load the texture you are using for the sprite itself.

  • Normal Map > Texture: Normal map texture. In this property, load the normal map texture you generated from the heightmap (see tip above).

  • Specular > Texture: Specular map texture, controls the specular intensity of each pixel on the diffuse texture. The specular map is usually grayscale, but it can also contain color to increase the reflected color accordingly. In this property, load the specular map texture you created (see tip above).

  • Specular > Color: Color multiplier for specular reflections.

  • Specular > Shininess: The specularity exponent used for reflections. Lower values ​​increase the brightness of reflections and make them more diffuse, while higher values ​​make reflections more localized. High values ​​are better for wet-looking surfaces.

  • Texture > Filter: Can be set to override the texture filtering mode, regardless of what the node's properties are set to (or the  Rendering > Textures > Canvas Textures > Default Texture Filter item setting).

  • Texture > Repeat: Can be set to override the texture filtering mode, regardless of what the node's properties are set to (or the  Rendering > Textures > Canvas Textures > Default Texture Repeat item setting).

After enabling normal maps, you may notice that your lights seem to fade. To fix this, increase the Height property on the PointLight2D and DirectionalLight2D nodes. You may also want to increase  the energy property of the light slightly to get closer to the light's intensity before enabling normal maps.

Use additional sprites as a faster alternative to 2D lights¶

If you're having performance issues with 2D lights, it might be worth replacing some of them with Sprite2D nodes that use additive blending. This is especially useful for short-lived dynamic effects such as bullets or explosions.

Additional sprites render much faster because they don't need to go through a separate render pipeline. Additionally, this method can be used with AnimatedSprite2D (or Sprite2D + AnimationPlayer), allowing the creation of animated 2D "lights".

However, attaching sprites has some disadvantages compared to 2D lights:

  • Blending formulas are inaccurate compared to "real" 2D lighting. This isn't usually a problem in well-lit areas, but it prevents additional sprites from properly lighting completely dark areas.

  • Attached sprites cannot cast shadows because they are not lights.

  • Adding sprites ignores normal and specular maps used on other sprites.

To display a sprite with additional blending, create a Sprite2D node and assign it a texture. In the inspector, scroll down to the CanvasItem > Material section, expand it and click the dropdown next to the Material property. Select New CanvasItemMaterial , click on the newly created material to edit, and set the Blend Mode to Add .

2D Grid¶

Introduction¶ _

In 3D, meshes are used to display the world. In 2D, they are rare because images are used more frequently. Godot's 2D engine is a purely 2D engine, so it can't really display 3D meshes directly (though it can be Viewportdone with and ViewportTexture).

see also

If you're interested in displaying a 3D mesh on a 2D viewport, see the Using the Viewport as a Texture tutorial.

A 2D mesh is one that contains two-dimensional geometry (Z can be omitted or ignored) rather than 3D. You could try SurfaceToolcreating them yourself in code and displaying them in MeshInstance2Da node.

Currently, the only way to generate a 2D mesh in the editor is to import an OBJ file as a mesh, or convert it from Sprite2D.

Optimizing Drawn Pixels¶

In some cases, this workflow is useful for optimizing 2D drawings. When drawing large images with transparency, Godot will draw the entire quad to the screen. Large transparent areas are still drawn.

This can affect performance, especially on mobile devices, when drawing very large images (often the size of the screen), or stacking multiple images together with large transparent areas (for example, when using ParallaxBackground.

Converting to a mesh will ensure that only the opaque parts are drawn and the rest are ignored.

Convert Sprite2D to 2D Mesh¶

Sprite2DYou can take advantage of this optimization by converting a to a MeshInstance2D. Start with an image that contains a lot of transparency around the edges, like this tree:

Put it in a Sprite2Dand choose "Convert to 2D Mesh" from the menu:

A dialog will appear showing a preview of how the 2D mesh will be created:

For many cases, the defaults are sufficient, but you can change the grow and simplify as needed:

Finally, press the button and your Sprite2D will be replaced:Convert 2D Mesh

2D sprite animation¶

Introduction¶ _

In this tutorial, you will learn how to create a 2D animated character using the AnimatedSprite2D class and AnimationPlayer. Typically, when you create or download an animated character, it will appear in one of two ways: as a separate image or as a single sprite sheet containing all the animation frames. Both can be animated in Godot using the AnimatedSprite2D class.

First, we'll use AnimatedSprite2D to animate a collection of individual images. Then we'll use this class to animate the sprite sheet. Finally, we'll learn another way to animate a sprite sheet using the AnimationPlayer and the Sprite2D  's Animation property.

notes

The art for the examples below is from ansimuz | OpenGameArt.org and tgfcoder.

A single image using AnimatedSprite2D¶

In this scene, you have a set of images, each containing a frame of animation for a character. For this example, we'll use the following animations:

You can download the image here:  2d_sprite_animation_assets.zip

Unzip the images and place them in the project folder. Set up the scene tree with the following nodes:

notes

The root node can also be Area2D or  RigidBody2D . Animations will still be done the same way. After the animation is complete, you can assign the shape to a CollisionShape2D. See Introduction to Physics for details  .

Now select AnimatedSprite2Dand select "New SpriteFrames" in its SpriteFrames properties.

Click on the new SpriteFrames asset, and you'll see a new panel appear at the bottom of the editor window:

From the file system dock on the left, drag 8 individual images to the center section of the SpriteFrames panel. On the left, change the name of the animation from "Default" to "Run".

Use the Play button in the upper right corner of the Filter Animations input to preview the animation. You should now see the animation play in the viewport. However, it's a bit slow. To fix this, change the Speed ​​(FPS) setting in the SpriteFrames panel to 10.

You can add additional animations by clicking the "Add Animation" button and adding additional images.

Control animation¶

Once the animation is complete, you can control the animation through code using play()the and stop()methods. Here's a short example that plays an animation while holding down the right arrow key, and stops it when the key is released.

GD script C#
extends CharacterBody2D

@onready var _animated_sprite = $AnimatedSprite2D

func _process(_delta):
    if Input.is_action_pressed("ui_right"):
        _animated_sprite.play("run")
    else:
        _animated_sprite.stop()

Sprite sheet with AnimatedSprite2D¶

You can also easily animate from a sprite sheet using the class AnimatedSprite2D. We'll use this public domain sprite sheet:

Right-click on the image and select "Save Image As" to download it, then copy the image into your project folder.

Set up the scene tree the same way as before with a single image. Select AnimatedSprite2Dand select "New SpriteFrames" in its SpriteFrames properties.

Click on the new SpriteFrames resource. This time, when the bottom panel appears, select Add Frame from Sprite Sheet.

You will be prompted to open a file. Choose your sprite sheet.

A new window will open showing your sprite sheet. The first thing you need to do is change the number of vertical and horizontal images in the sprite sheet. In this sprite sheet we have four horizontal images and two vertical images.

Next, select the frames from the sprite sheet to include in the animation. We'll select the first four and click Add 4 Frames to create the animation.

You will now see your animation under the list of animations in the bottom panel. Double-click on default and change the name of the animation to jump.

Finally, check the play button on the SpriteFrames editor to see your frog jump!

Sprite sheet with AnimationPlayer¶

Another way you can animate when using sprite sheets is to use standard  Sprite2D nodes to display textures, then use an AnimationPlayer to animate the changes between textures.

Consider this sprite sheet with 6 frames of animation:

Right click on the image and select "Save Image As" to download, then copy the image into your project folder.

Our goal is to cycle through these images. Start by setting up the scene tree:

notes

The root node can also be Area2D or  RigidBody2D . Animations will still be done the same way. After the animation is complete, you can assign the shape to a CollisionShape2D. See Introduction to Physics for details  .

Drag the spritesheet into the Sprite's Texture property, and you'll see the entire sheet appear on the screen. To split it into individual frames, expand the Animation section in the inspector and set Hframes to 6Hframes and Vframes are the number of horizontal and vertical frames in the sprite sheet.

Now try to change the value of the Frame property. You'll see it range from 0to 5and the image displayed by the Sprite2D changes accordingly. This is the property we want to animate.

Select AnimationPlayerand click the Animation button, then click New. Name the new animation "Walk". Set the animation length to 0.6and click the Loop button so our animation will repeat.

Now select Sprite2Dthe node and click on the key icon to add a new track.

Continue adding frames at each point in the timeline ( 0.1seconds by default) until you have all frames from 0 to 5. You'll see the frames actually appear in the animation track:

Press "Play" on the animation to see how it looks.

Controlling AnimationPlayer animations¶

play()As with AnimatedSprite2D, you can control the animation through code using the and methods stop(). Again, here's an example that plays an animation when the right arrow key is held down and stops it when the key is released.

GD script C#
extends CharacterBody2D

@onready var _animation_player = $AnimationPlayer

func _process(_delta):
    if Input.is_action_pressed("ui_right"):
        _animation_player.play("walk")
    else:
        _animation_player.stop()

notes

If you update both animations and individual properties at the same time (for example a platformer might update a sprite's h_flip/ v_flip properties when a character turns when starting a "turn" animation), it's important to remember that play()it won't be applied immediately. Instead, it will be applied the next time the AnimationPlayer is disposed. This can end up on the next frame, resulting in a "glitch" frame where the property change is applied but no animation is applied. If this proves to be a problem, play()you can advance(0) call update animation immediately after calling.

General¶ _

These examples illustrate two classes that can be used for 2D animation in Godot. AnimationPlayerA little more complex than AnimatedSprite2D, but it provides additional functionality because you can also animate other properties, such as position or scale. This class AnimationPlayercan also be used with AnimatedSprite2D. Experiment to see what works best for your needs.

2D Particle System¶

Introduction¶ _

Particle systems are used to simulate complex physical effects such as sparks, flames, magic particles, smoke, mist, etc.

The idea is that "particles" are emitted at fixed intervals and with a fixed lifetime. During its lifetime, each particle will have the same basic behavior. What makes each particle unique and gives a more organic look is the "randomness" associated with each parameter. Essentially, creating a particle system means setting the underlying physics parameters and then adding randomness to them.

Particle Node¶

Godot provides two different nodes for 2D particles, GPUParticles2D  and CPUParticles2D . GPUParticles2D is more advanced and uses the GPU to handle particle effects. CPUParticles2D is a CPU-driven option with similar functionality to GPUParticles2D, but with lower performance when using large numbers of particles. On the other hand, CPUParticles2D may perform better on low-end systems or GPU bottlenecks.

 While GPUParticles2D is configured via ParticleProcessMaterial (and optionally uses a custom shader), matching options are provided via node properties in CPUParticles2D (except for track settings).

You can convert a GPUParticles2D node to a CPUParticles2D node by clicking on the node in the inspector, then selecting Particles > Convert to CPUParticles2D from the toolbar at the top of the 3D Editor viewport.

The rest of this tutorial will use the GPUParticles2D node. First, add a GPUParticles2D node to the scene. After creating the node, you'll notice that only a white point is created, and there is a warning icon next to the GPUParticles2D node in the scene dock. This is because Node requires a ParticleProcessMaterial to function.

Particle Handling Materials¶

To add a processing material to your particle node, go to your inspector panel. Click the box next to it and choose from the drop-down menu.Process MaterialMaterialNew ParticleProcessMaterial

Your GPUParticles2D node should now emit white dots downwards.

texture¶ _

Particle systems use a single texture (possibly extending to animation textures via spritesheet in the future). Textures are set via the relevant texture properties:

Time parameters¶

Lifespan¶ _

How long each particle lives in seconds. When the lifetime ends, a new particle is created to replace it.

Lifespan: 0.5

Lifespan: 4.0

One shot¶

When enabled, the GPUParticles2D node will emit all particles once and then never again.

Preprocessing¶ _

A particle system starts by emitting zero particles, then starts emitting. This can be inconvenient when loading scenes and systems like torches, fog, etc. Glow begins the moment you enter. Preprocessing is used to let the system process a given number of seconds before the first actual drawing.

Velocity Scales¶

The default value of the speed scale 1is used to adjust the speed of the particle system. Lowering the value will make the particles slower, while increasing the value will make the particles faster.

Explosiveness¶ _

If lifetime is 1and there are 10 particles, it means that one particle is emitted every 0.1 seconds. The explosiveness parameter changes this and forces the particles to emit together. The scope is:

  • 0: Emit particles periodically (default).

  • 1: Emit all particles at the same time.

Intermediate values ​​are also allowed. This feature is useful for creating explosions or sudden bursts of particles:

Randomness¶ _

All physical parameters can be randomized. Random values ​​range from 0to  1. The formula for randomizing the parameter is:

initial_value = param_value + param_value * randomness

Fixed frame rate¶

This setting can be used to set the particle system to render at a fixed FPS. For example, changing the value to 2will cause particles to render at 2 frames per second. Note that this does not slow down the particle system itself.

Fractional Delta¶

This can be used to turn Fract Delta on or off.

Drawing parameters¶

Visibility Rectangle¶

The Visibility Rectangle controls the visibility of particles on the screen. If this rectangle is outside the viewport, the engine will not render the particles on screen.

The rectangle's Wand Hproperties control its width and height, respectively. and properties control the position of the upper left corner of the rectangle relative to the particle emitter X.Y

You can have Godot automatically generate a visibility rectangle using the toolbar above the 2d view. To do this, select the GPUParticles2D node and click. Godot will simulate the Particles2D node emitting particles for a few seconds, and set the rectangle to fit the surface the particles adopt.Particles > Generate Visibility Rect

You can use this option to control the emission duration. The maximum value is 25 seconds. If you need more time for the particles to move around, you can temporarily change the duration on the Particles2D node.Generation Time (sec)preprocess

Local coordinates¶

By default, this option is on, which means that the space into which particles are emitted is relative to the node. If you move a node, all particles move with it:

If disabled, particles will be emitted into global space, which means that particles already emitted are not affected if the node is moved:

Draw order¶

This controls the order in which individual particles are drawn. Index Indicates that particles are drawn according to their emission order (default). LifetimeIndicates that they are plotted in order of remaining life.

ParticleProcessMaterial Settings¶

direction¶ _

This is the base direction in which particles are emitted. The default is to make particles emit to the right. However, with the default gravity settings, particles will travel straight down.Vector3(1, 0, 0)

For this property to be noticeable, you need an initial velocity greater than 0. Here we set the initial velocity to 40. You'll notice that the particles are emitted to the right and then fall down due to gravity .

Propagation¶ _

This parameter is the angle in degrees that will be randomly added to base in either direction  Direction. 180A spread will be emitted in all directions (+/- 180). In order for propagation to do anything, the "initial velocity" parameter must be greater than 0.

Flatness¶ _

This property is only useful for 3D particles.

Gravity¶ _

The gravity applied to each particle.

Initial Velocity¶

Initial Velocity is the velocity (in pixels/second) at which particles are emitted. Velocity may change later due to gravity or other accelerations (described below).

Angular Velocity¶

Angular Velocity is the initial angular velocity applied to the particle.

Spin Speed¶

Spin velocity is the speed (in degrees per second) at which a particle rotates around its center.

Orbit Velocity¶

Orbital velocity is used to spin particles around their centers.

Linear Acceleration¶

The linear acceleration applied to each particle.

Radial Acceleration¶

If this acceleration is positive, particles are accelerated away from the center. If negative, they are absorbed by it.

Tangential Acceleration¶

This acceleration will use the tangent vector to the center. Combined with radial acceleration it works well.

Shock Reduction¶

Damping applies friction to particles, forcing them to stop. It is especially useful for sparks or explosions that typically start at high linear velocities and then stop as they subside.

angle¶ _

Determines the initial angle of the particle in degrees. This parameter is most useful for randomization.

scale¶ _

Determines the initial scale of the particles.

color¶ _

Used to change the color of emitted particles.

Hue Variation¶

This Variationvalue sets the initial hue change applied to each particle. This value controls the randomness ratio of the tint change.Variation Random

Emission shape¶

ParticleProcessMaterials allows you to set an Emission Mask, which determines the area and direction in which particles are emitted. These can be generated from textures in the project.

Make sure ParticleProcessMaterial is set and the GPUParticles2D node is selected. The Particles menu should appear in the toolbar:

Open it and select "Load Emission Mask":

Then choose a texture to use as a mask:

A dialog with several settings will appear.

Emission mask¶

Three types of emission masks can be generated from textures:

  • Solid Pixels: Particles will spawn from any area of ​​the texture, excluding transparent areas.

  • Border Pixels: Particles will spawn from the outer edges of the texture.

  • Directed Border Pixels: Similar to Border Pixels, but adds extra information to the mask to enable particles to be emitted from the border. Note that a will needs to be set up to use it.Initial Velocity

Emission Color¶

Capture from PixelWill cause particles to inherit the mask's color at their spawn point.

After clicking OK, the mask is generated and set to the ParticleProcessMaterial in the following section:Emission Shape

All values ​​in this section are auto-generated by the Load Emission Mask menu, so they should generally be left alone.

notes

Images should not be added to or added directly to. The "Load launch mask" menu should always be used.Point TextureColor Texture

2D Antialiasing¶

see also

Godot also supports anti-aliasing in 3D rendering. This is covered on the 3D antialiasing page.

Introduction¶ _

Scenes rendered in 2D may appear aliased due to limited resolution. These artifacts usually appear in the form of a "staircase" effect on the edges of geometry, and are most noticeable when using nodes such as Line2D Polygon2D , or TextureProgressBar . Custom drawings in 2D may also be aliased for methods that do not support anti-aliasing .

In the example below, you can notice how the edges have a blocky appearance:

The image is scaled by a factor of 2 through nearest neighbor filtering to make aliasing more visible.

To address this, Godot supports several ways to enable anti-aliasing on 2D renders.

Anti - aliasing properties in Line2D and custom plots¶

This is the recommended approach as it has less performance impact in most cases.

Line2D has an Antialiased property which you can enable in the inspector. Additionally, several methods for custom plotting in 2D support optional parameters that can be set when calling the function antialiased.true

These methods do not require MSAA to be enabled, which makes their baseline  performance costly. In other words, if you don't draw any antialiased geometry at some point, it won't permanently increase the cost.

The downside of these antialiasing methods is that they work by generating extra geometry. This can be a bottleneck if you are generating complex 2D geometry that is updated every frame. Also, Polygon2D, TextureProgressBar and some custom drawing methods do not have anti-aliasing properties. For these nodes, you can use 2D Multisample Antialiasing instead.

Multisample Antialiasing (MSAA)

Before enabling MSAA in 2D, it is important to understand what MSAA will run on. MSAA in 2D follows similar constraints as in 3D. While it doesn't introduce any blur, its range of application is limited. The main applications of 2D MSAA are:

  • Geometric edges such as line and polygon drawing.

  • Sprite edges only apply to pixels touching one of the texture edges . This works for both linear and nearest neighbor filtering. The edges of sprites created with image transparency are not affected by MSAA.

The downside of MSAA is that it only works on the edges. This is because MSAA increases the number of coverage samples, but not the number of color samples. However, since the number of color samples is not increased, the fragment shader is still only run once for each pixel. Therefore, MSAA does not affect in any way the following types of aliases:

  • Aliasing in nearest neighbor filtered textures (pixel art) .

  • Aliasing caused by custom 2D shaders.

  • Specular aliasing when using Light2D.

  • Alias ​​in font rendering.

MSAA can be enabled in the project settings by changing the value of the Render > Antialiasing > Quality > MSAA 2D setting. It is important to change the value of the MSAA 2D setting and not MSAA 3D , as they are completely separate settings.

Comparison between no antialiasing (left) and various MSAA levels (right). The upper left corner contains a Line2D node, and the upper right corner contains 2 TextureProgressBar nodes. The bottom contains 8 pixel art sprites, 4 of which are touching the edges (green background) and 4 of which are not (Godot logo):

  

Custom 2D Plot¶

Introduction¶ _

Godot has nodes to draw sprites, polygons, particles and all kinds of stuff. For most cases, this is sufficient. If there is no node that can draw the specific thing you need, you can make any 2D node (eg Control or  Node2D based ) draw custom commands.

Useful for custom drawing in 2D nodes . Here are some use cases:

  • Draw shapes or logic that existing nodes cannot do, such as images with trails or special animated polygons.

  • Visualizations that are not compatible with Node, such as Tetris boards. (The Tetris example uses a custom draw function to draw the blocks.)

  • Draw lots of simple objects. Custom drawing avoids the overhead of using a large number of nodes, potentially reducing memory usage and improving performance.

  • Make custom UI controls. There are many controls available, but when you have unusual needs, you may need to customize the controls.

Drawing¶ _

Add the script to any CanvasItem  derived node, such as Control or  Node2D . Then override that _draw()function.

GD script C#
extends Node2D

func _draw():
    # Your draw commands here
    pass

Drawing commands  are described in CanvasItem Class Reference. There are many.

Updating¶ _

The _draw()function is called only once, then the drawing commands are cached and remembered so no further calls are needed.

If a redraw is required due to state or other changes, call CanvasItem.queue_redraw()_draw() in the same node and make a new call.

Here's a slightly more complex example, a texture variable that will be repainted if modified:

GD script C#
extends Node2D

export (Texture) var texture setget _set_texture

func _set_texture(value):
    # If the texture variable is modified externally,
    # this callback is called.
    texture = value  # Texture was changed.
    queue_redraw()  # Trigger a redraw of the node.

func _draw():
    draw_texture(texture, Vector2())

In some cases it may be necessary to draw every frame. To do this, call it queue_redraw()from _process()the callback, like so:

GD script C#
extends Node2D

func _draw():
    # Your draw commands here
    pass

func _process(delta):
    queue_redraw()

Coordinates¶ _

The drawing API uses the CanvasItem's coordinate system, not necessarily pixel coordinates. This means it uses the coordinate space created after applying the CanvasItem's transform. Additionally, you can apply custom transformations on it using draw_set_transform or  draw_set_transform_matrix .

When using it draw_line, the width of the line should be considered. When using odd-sized widths, the position should shift to 0.5keep the line centered, as shown below.

GD script C#
func _draw():
    draw_line(Vector2(1.5, 1.0), Vector2(1.5, 4.0), Color.GREEN, 1.0)
    draw_line(Vector2(4.0, 1.0), Vector2(4.0, 4.0), Color.GREEN, 2.0)
    draw_line(Vector2(7.5, 1.0), Vector2(7.5, 4.0), Color.GREEN, 3.0)

The same applies to draw_rectthe method with.filled = false

GD script C#
func _draw():
    draw_rect(Rect2(1.0, 1.0, 3.0, 3.0), Color.GREEN)
    draw_rect(Rect2(5.5, 1.5, 2.0, 2.0), Color.GREEN, false, 1.0)
    draw_rect(Rect2(9.0, 1.0, 5.0, 5.0), Color.GREEN)
    draw_rect(Rect2(16.0, 2.0, 3.0, 3.0), Color.GREEN, false, 2.0)

Example: Drawing an Arc¶

We will now use the Godot engine's custom drawing capabilities to draw functionality not provided by Godot. For example, Godot provides a draw_circle()function to draw an entire circle. But what about drawing part of a circle? You will have to write a function to do this and draw it yourself.

Arc function¶

An arc is defined by its supporting circle parameters, namely the center position and radius. The arc itself is then defined by the angle at which it starts and the angle at which it stops. These are the 4 parameters we must provide to the plotting function. We'll also provide color values, so we can draw arcs in different colors if desired.

Basically, drawing a shape on the screen requires breaking it down into a certain number of points that connect from one point to another. As you can imagine, the more points your shape consists of, the smoother it will look, but it will also be heavier in terms of processing costs. In general, if your shape is large (or in 3D, close to the camera), it needs to draw more points than angular ones. Conversely, if your shape is small (or in 3D, far away from the camera), you can reduce its point count to save processing costs; this is called Level of Detail (LOD) . In our example we will simply use a fixed number of points regardless of the radius.

GD script C#
func draw_circle_arc(center, radius, angle_from, angle_to, color):
    var nb_points = 32
    var points_arc = PackedVector2Array()

    for i in range(nb_points + 1):
        var angle_point = deg_to_rad(angle_from + i * (angle_to-angle_from) / nb_points - 90)
        points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)

    for index_point in range(nb_points):
        draw_line(points_arc[index_point], points_arc[index_point + 1], color)

Remember the number of points our shape had to be broken down into? We nb_pointsfix this number in a variable as the value 32. Then, we initialize an empty one  PackedVector2Array, which is just an Vector2array of s.

The next step consists of computing the actual positions of the 32 points that make up the arc. This is done in the first for loop: we iterate over the number of points where the position is to be calculated, plus the last point. We first determine the angle of each point, between the start angle and end angle.

The reason each angle is reduced by 90° is that we'll be using trigonometry (you know, the cosine and sine stuff...) to calculate the 2D position for each angle. However,  radians cos()are used sin(), not degrees. Angles of 0° (0 radians) start at 3 o'clock, although we want to count from 12 o'clock. So we reduce each angle by 90° to count from 12 o'clock.

The actual position of a point lying on the circle at an angle (in radians) angleis given by . Since the sum and return values ​​are between -1 and 1, the location is on a circle of radius 1. To make the location lie on a support circle of radius , we simply multiply the location by . Finally, we need to position our circle of support at that location, which we do by adding it to our value. Finally, we insert the point into which which we defined earlier.Vector2(cos(angle), sin(angle))cos()sin()radiusradiuscenterVector2PackedVector2Array

Now, we need to actually make our point. As you can imagine, we don't simply draw 32 points: we need to draw everything between each point. We can use the previous method to calculate each point ourselves, and then draw them one by one. But that's too complicated and inefficient (unless explicitly needed), so we just draw lines between each pair of points. Unless our supporting circle has a very large radius, each line between a pair of points will never be long enough to see them. If this happens, we just need to increase the number of points.

Draw an arc on the screen¶

We now have a function that draws something on the screen; it's time _draw()to call it inside the function:

GD script C#
func _draw():
    var center = Vector2(200, 200)
    var radius = 80
    var angle_from = 75
    var angle_to = 195
    var color = Color(1.0, 0.0, 0.0)
    draw_circle_arc(center, radius, angle_from, angle_to, color)

result:

Arc polygon function¶

We can go a step further and write a function to draw not only the planar portion of the disk defined by the arc, but also its shape. The method is exactly the same as before, except we draw polygons instead of lines:

GD script C#
func draw_circle_arc_poly(center, radius, angle_from, angle_to, color):
    var nb_points = 32
    var points_arc = PackedVector2Array()
    points_arc.push_back(center)
    var colors = PackedColorArray([color])

    for i in range(nb_points + 1):
        var angle_point = deg_to_rad(angle_from + i * (angle_to - angle_from) / nb_points - 90)
        points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
    draw_polygon(points_arc, colors)

Dynamic custom plotting¶

Ok, we can now draw custom content on the screen. However, it's static; let's make the shape rotate around the center. The solution to this is to change the angle_from and angle_to values ​​over time. For our example, we will simply increase them by 50. This delta value must remain constant, otherwise the rotation speed will change accordingly.

First, we must make the angle_from and angle_to variables global at the top of the script. Also note that you can store them in other nodes and use get_node().

GD script C#
extends Node2D

var rotation_angle = 50
var angle_from = 75
var angle_to = 195

We change these values ​​in the _process(delta) function.

We also increase the angle_from and angle_to values ​​here. However, we must not forget about wrap()resulting values ​​between 0 and 360°! That is, if the angle is 361°, it is actually 1°. If you don't wrap the values, the script will work fine, but the angle values ​​will grow larger and larger over time until they reach the maximum integer value ( ) that Godot can manage. When this happens, Godot may crash or exhibit unexpected behavior.2^31 - 1

Finally, we must not forget to call the function queue_redraw(), it will be called automatically _draw(). This way, you can control when the frame is refreshed.

GD script C#
func _process(delta):
    angle_from += rotation_angle
    angle_to += rotation_angle

    # We only wrap angles when both of them are bigger than 360.
    if angle_from > 360 and angle_to > 360:
        angle_from = wrapf(angle_from, 0, 360)
        angle_to = wrapf(angle_to, 0, 360)
    queue_redraw()

Also, don't forget to modify the function _draw()to use these variables:

GD script C#
func _draw():
   var center = Vector2(200, 200)
   var radius = 80
   var color = Color(1.0, 0.0, 0.0)

   draw_circle_arc( center, radius, angle_from, angle_to, color )

let's run! It works, but the arc spins ridiculously fast! What's wrong?

The reason is that your GPU is actually displaying frames as fast as it can. We need to "normalize" the plot with this speed; for this we have to use the function delta's arguments _process(). deltaContains the time elapsed between the two last rendered frames. It's usually small (about 0.0003 seconds, but it depends on your hardware), so deltacontrolling your drawing with .

In our case we just need to rotation_anglemultiply the variable by in the function. This way, our 2 angles will be increased by a much smaller value, which directly depends on the rendering speed.delta_process()

GD script C#
func _process(delta):
    angle_from += rotation_angle * delta
    angle_to += rotation_angle * delta

    # We only wrap angles when both of them are bigger than 360.
    if angle_from > 360 and angle_to > 360:
        angle_from = wrapf(angle_from, 0, 360)
        angle_to = wrapf(angle_to, 0, 360)
    queue_redraw()

Let's run again! This time, the rotation appears fine!

Anti - aliased drawing¶

Godot provides a method parameter in draw_line to enable anti-aliasing, but not all custom drawing methods provide this antialiased parameter.

For antialiasedcustom drawing methods that don't provide parameters, you can instead enable 2D MSAA, which affects rendering in the entire viewport. This provides high-quality antialiasing, but at a higher performance cost and only for specific elements. See 2D Antialiasing for details.

Tools¶ _

You may also need to draw your own nodes when running them in the editor. This can be used as a preview or visualization of certain functionality or behavior. For more information, see Running code in the editor.

2D Motion Overview¶

Introduction¶ _

Every beginner encounters: "How do I move my character?" Depending on the style of game you're making, you may have special requirements, but generally movement in most 2D games is based on a small amount of design.

We'll be using CharacterBody2D in these examples , but the principles apply to other node types (Area2D, RigidBody2D) as well.

Settings¶ _

Each of the examples below uses the same scene setup. Start with a which has two children CharacterBody2D: Sprite2Dand CollisionShape2D. You can use the Godot icon ("icon.png") for the Sprite2D's texture or use any other 2D image you have.

Open and select the Input Map tab. Add the following input actions (see InputEvent for details ):Project -> Project Settings

8-way motion¶

In this case, you want the user to press the four directional keys (Up/Left/Down/Right or W/A/S/D) and move in the selected direction. The name "8-way movement" comes from the fact that the player can move diagonally by pressing two keys at the same time.

Add a script to the character and add the following code:

GD script C#
extends CharacterBody2D

@export var speed = 400

func get_input():
    var input_direction = Input.get_vector("left", "right", "up", "down")
    velocity = input_direction * speed

func _physics_process(delta):
    get_input()
    move_and_slide()

In get_input()the function, we use Input get_vector() to check four key events and sum to return a direction vector.

We can then set our velocity by multiplying this direction vector of length 1by our desired velocity.

hint

If you've never used vector math before, or need a refresher, you can check out an explanation of vector usage in Godot at Vector math.

notes

If the above code doesn't do anything when you press a key, double check that you've set up the input action correctly as described in the setup section of this tutorial.

Rotate+ Move¶

This type of movement is sometimes called "asteroid style" because it resembles the way classic arcade games work. Press left/right to rotate your character, and up/down to move it forward or backward in any direction.

GD script C#
extends CharacterBody2D

@export var speed = 400
@export var rotation_speed = 1.5

var rotation_direction = 0

func get_input():
    rotation_direction = Input.get_axis("left", "right")
    velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
    get_input()
    rotation += rotation_direction * rotation_speed * delta
    move_and_slide()

Here we've added two variables to keep track of our rotation direction and velocity. Rotation is applied directly to the body's rotationproperties.

To set the velocity, we take the body's  transform.x, which is a vector pointing in the "forward" direction of the body, and multiply that by the velocity.

Rotate+Move (Mouse)

This sporty style is a variation of the previous one. This time, the orientation is set by the mouse position rather than the keyboard. The character will always "look" at the mouse pointer. However, the forward/backward input remains the same.

GD script C#
extends CharacterBody2D

@export var speed = 400

func get_input():
    look_at(get_global_mouse_position())
    velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
    get_input()
    move_and_slide()

Here we use Node2D look_at() methods to point the player to the mouse position. Without this function, you can get the same effect by setting the angle like this:

GD script C#
rotation = get_global_mouse_position().angle_to_point(position)

Click and move¶

The last example uses only the mouse to control the character. Clicking on the screen will move the player to the target location.

GD script C#
extends CharacterBody2D

@export var speed = 400

var target = position

func _input(event):
    if event.is_action_pressed("click"):
        target = get_global_mouse_position()

func _physics_process(delta):
    velocity = position.direction_to(target) * speed
    # look_at(target)
    if position.distance_to(target) > 10:
        move_and_slide()

Note distance_to()the checks we do before moving. Without this test, the body "wobbles" when it reaches the target position, as it moves slightly past that position and tries to move back, only to move too far and repeat.

Uncommenting that look_at()line also makes the body point in its direction of motion, if you like.

hint

This technique can also be used as the basis for a "follow" character. The targetlocation can be the location of any object you want to move to.

General¶ _

You may find these code samples useful as a starting point for your own projects. Feel free to use them and experiment with them to see what you can do.

You can download this example project here:  2d_movement_starter.zip

Using TileSet¶

Introduction¶ _

A tile map is a grid of tiles used to create game layouts. There are several benefits to designing levels using TileMap nodes. First, they allow you to draw layouts by "drawing" tiles onto a grid, which is much faster than placing individual Sprite2D nodes one after the other . Second, they allow for larger levels because they are optimized for drawing large numbers of tiles. Finally, they allow you to add more functionality to your tiles with collision, occlusion, and navigation shapes.

To use tilemaps, you need to first create a TileSet. A TileSet is a collection of tiles that can be placed in a TileMap node. After creating TileSets, you will be able to place them using the TileMap editor .

To follow this guide, you will need an image containing your tiles, where each tile is the same size (large objects can be split into several tiles). This image is called a tilesheet . The tiles don't have to be square: they can be rectangular, hexagonal or isometric (pseudo 3D perspective).

Create a new TileSet¶

Using tile tables¶

This demo will use the following tiles taken from Kenney's Abstract Platformer pack . We'll use this particular tile table from the collection :

A tilesheet with 64×64 tiles. Credit : Kenny¶

Create a new TileMap node, then select it and create a new TileSet resource in the inspector:

Create new TileSet resource in TileMap node¶

After creating the TileSet resource, click the value to expand it in the inspector. The default collage shape is square, but you can also choose equidistant, half-offset square, or hexagonal (depending on the shape of the collage image). If using a tile shape other than square, you may also need to adjust the Tile Layout and Tile Offset Axis properties. Finally, enabling the Render > UV Clipping property may be useful if you wish to clip tiles by tile coordinates. This ensures that tiles cannot be drawn outside of the allocated area on the tile sheet.

Set the tile size to 64x64 in the inspector to match the example tile table:

Set the tile size to 64×64 to match the example tile table¶

If relying on automatic tile creation (as we'll do here), you must set the tile size before creating the atlas . The atlas will determine which tiles from the tilesheet can be added to a TileMap node (since not every part of an image may be a valid tile).

Open the TileSet panel at the bottom of the editor , and click the "+" icon in the lower left corner to add a new atlas:

Create a new atlas in a TileSet resource using the bottom panel¶

After creating an atlas, you must assign it a tilesheet texture. This can be done by selecting it in the left column of the bottom panel, then clicking on the value of the Texture property and selecting Quick Load (or Load ). Use the file dialog that appears to specify the path to the image file.

Load tilesheet image in newly created TileSet atlas¶

After specifying a valid image, you will be asked whether to automatically create tiles. The answer is :

Automatically create tiles based on tilesheet image content¶

This will automatically create tiles based on the tile size you specified earlier in the TileSet resource. This greatly speeds up the initial tile setup.

notes

Fully transparent slice table sections do not generate tiles when using automatic tile generation based on image content .

If there are tiles in the tile table that you don't want to appear in the atlas, select the eraser tool at the top of the tile set preview and click on the tile you want to remove:

Use the eraser tool to remove unwanted tiles from a TileSet atlas¶

You can also right click on a tile and select delete as an alternative to the eraser tool.

hint

As in the 2D and TileMap editors, you can pan the TileSet panel with the middle or right mouse button, and zoom with the mouse wheel or the top left button.

If you wish to get tiles from multiple tilesheet images in a single TileSet, create additional atlases and assign textures to each before continuing. It is also possible to use one image per tile this way (although a tile table is recommended for better usability).

You can adjust the properties of the atlas in the middle column:

Adjust TileSet atlas properties in the dedicated inspector (part of the TileSet panel)

The following properties can be adjusted on an atlas:

  • ID: Identifier (unique within this TileSet), used for sorting.

  • Name: A human-readable name for the atlas. For organizational purposes, descriptive names are used here (such as "terrain", "decoration", etc.).

  • Margin: The margin (in pixels) at the edge of the image that should not be selected as a tile. Increasing this value may be useful if you download tile images with margins around the edges (e.g. for attribution).

  • Separation: The spacing in pixels between each tile on the atlas. Increasing this value can be useful if you are using a tilesheet image that includes guides such as outlines between each tile.

  • Texture Region Size: The size (in pixels) of each tile on the atlas. In most cases, this should match the tile size defined in the TileMap property (although this is not strictly necessary).

  • Use Texture Fill: If checked, adds a 1-pixel transparent border around each tile to prevent texture bleeding when filtering is enabled. It is recommended to have this option enabled unless you are having rendering issues due to texture fills.

Note that changing texture margins, separations, and region sizes may result in missing tiles (as some of them will be outside the coordinates of the atlas image). To automatically regenerate tiles from the tile table, use the three vertical dot menu buttons at the top of the TileSet editor and select  Create tiles in non-transparent texture areas :

Automatically recreate tiles after changing atlas properties¶

Working with scene collections¶

Starting with Godot 4.0, you can place actual scenes as tiles. This allows you to use any collection of nodes as a tile. For example, you can use scene tiles to place game elements such as shops that players can interact with. You can also use scene tiles to place AudioStreamPlayer2D (for ambient sounds), particle effects, etc.

warn

Scene tiles have a greater performance overhead than atlases because each scene is instantiated individually for each placed tile.

It is recommended to only use scene tiles when necessary. To draw sprites in tiles without any advanced operations,  use an atlas instead .

For this example, we'll create a scene with a CPUParticles2D root node. Save the scene to a scene file (separate from the scene containing the TileMap), then switch to the scene containing the TileMap node. Open the TileSet editor and create a new Scenes Collection in the left column:

Creating SceneAssemblies in the TileSet Editor¶

After creating the scene assembly, you can optionally enter a descriptive name for the scene assembly in the middle column. Select this scene collection and create a new scene slot:

Create scene tiles after selecting a sceneset in the TileSet editor¶

Select this scene slot in the right column, then use fastload (or  load ) to load the scene file containing the particles:

Create scene slots and load scene files into them in the TileSet editor¶

You now have a scene tile in the TileSet. After switching to the TileMap editor, you will be able to select it from the scene collection and paint it like any other tile.

Merging multiple atlases into one atlas¶

Using multiple atlases in a single TileSet resource is sometimes useful, but can also be cumbersome in some cases (especially if you use one image per tile). Godot allows you to combine multiple atlases into one for easy organization.

To do this, you must create multiple atlases within a TileSet resource. Use the "three vertical dots" menu button located at the bottom of the mapset list, and select Open Mapset Merge Tool :

Open the atlas merge tool after creating multiple atlases¶

This will open a dialog where you can select multiple atlases by Shift or Ctrl-clicking multiple elements:

Using the Atlas Merge Tool Dialog¶

Select Merge to merge the selected atlases into a single atlas image (converted to a single atlas in a TileSet). Unmerged atlases will be deleted in the TileSet, but the original atlas images will remain on the file system . If you don't want to remove the unmerged atlas from the TileSet resource, select Merge (keep the original atlas) instead .

hint

TileSet has a tile proxy system. A Tile Proxy is a mapping table that allows a TileMap to be informed with a given TileSet that a given set of tile identifiers should be replaced by another set.

Tile proxies are set automatically when merging different atlases, but they can also be set manually thanks to the Manage Tile Proxies dialog, which you access using the "three vertical dots" menu mentioned above.

Manually creating tile proxies can be useful when you change the atlas ID or want to replace all tiles in one atlas with tiles in another. Note that when editing a TileMap, you can replace all cells with the corresponding mapped values.

Add collision, navigation and occlusion to TileSet¶

We have now successfully created a basic TileSet. We can now start using the TileMap node, but it currently lacks any form of collision detection. This means players and other objects can go straight through floors or walls.

If you're using 2D navigation , you'll also need to define navigation polygons for tiles to generate a navmesh that agents can use to find their way.

Finally, if you're using 2D lights and shadows or GPUParticles2D, you'll probably also want your TileSets to be able to cast shadows and collide with particles. This requires defining occlusion polygons for the "solid" tiles on the TileSet.

To be able to define collision, navigation and occlusion shapes for each tile, you need to first create a physics layer, navigation layer or occlusion layer for the TileSet asset. To do this, select the TileMap node, click on the TileSet property value in the inspector to edit it, then expand the physical layer and choose  Add Element :

Create Physical Layers (inside TileMap nodes) in TileSet Resource Inspector¶

If you also need navigation support, now is a good time to create a navigation layer:

Create a navigation layer (inside a TileMap node) in the TileSet resource inspector¶

If you need support for light polygon occluders, now is a good time to create an occlusion layer:

Create Occlusion Layers in the TileSet Asset Inspector (inside the TileMap node)

notes

The next steps in this tutorial are dedicated to creating collision polygons, but the process for navigation and occlusion is very similar. Their respective polygon editors behave in the same way, so these steps are not repeated for brevity.

The only caveat is that the tile's Occlusion Polygon property is part of the Render subsection in the Atlas Inspector. Make sure to expand this section so you can edit the polygon.

After creating a Physical Layer, you can access the Physical Layers section in the TileSet Atlas Inspector :

Open the collision editor in selection mode¶

You can quickly create a rectangular collision shape by pressing F while the TileSet editor is in focus. If the keyboard shortcuts don't work, try clicking on an empty space around the polygon editor to bring it into focus:

Use the default rectangular collision shape by pressing

In this tile collision editor you can use all 2D polygon editing tools:

  • Use the toolbar above the polygon to toggle between creating new polygons, editing existing polygons, and removing points on polygons. The "Three Vertical Points" menu button provides additional options such as rotating and flipping polygons.

  • Create new points by clicking and dragging the line between two points.

  • Delete a point by right-clicking it (or using the aforementioned delete tool and left-clicking).

  • Pan in the editor by middle-clicking or right-clicking. (Right-click panning only works in areas with no points nearby.)

You can use the default rectangle shape to quickly create a triangle collision shape by deleting one of the points:

Create triangular collision shapes by right-clicking one of the corners to delete it¶

You can also use rectangles as the basis for more complex shapes by adding more points:

Draw custom collisions for complex tile shapes¶

hint

If you have a large tileset, specifying collisions for each tile individually can take a lot of time. This is especially true since TileMaps tend to have many tiles with common collision patterns (such as solid blocks or 45-degree slopes). To quickly apply similar collision shapes to multiple tiles, use  the ability to assign properties to multiple tiles at once .

Assign custom metadata to TileSet's tiles¶

You can use custom data layers to assign custom data on a per-tile basis. This is useful for storing information specific to your game, such as how much damage a tile should do when a player touches it, or whether a tile can be destroyed with a weapon.

Data is associated with tiles in a TileSet: all instances of a placed tile will use the same custom data. If you need to create a tile variation with different custom data, this can be done by creating an alternate tile and changing only the alternate tile's custom data.

Create a custom data layer (inside a TileMap node) in the TileSet resource inspector¶

Example of a configured custom data layer with game-specific properties¶

You can reorder custom data without breaking existing metadata: the TileSet editor will automatically update after reordering custom data properties.

Note that in the editor, the property names do not appear (only their indices are shown, which matches the order in which they were defined). For example, for the custom data layer example shown above, we are assigning a tile to  set damage_per_secondthe metadata to :25destructiblefalse

Edit custom data in TileSet editor in selection mode¶

Tile property painting  is also available for custom data:

Assign custom data in TileSet editor using tile attribute drawing¶

Create terrain sets (automatic stitching)

notes

This feature is implemented in a different form than auto-tiling in Godot 3.x. Terrains are essentially a more powerful replacement for autotiles. Unlike autotiles, terrains can support transitions from one terrain to another, since a single tile can define multiple terrains at the same time.

Unlike before, autotiles are a specific type of tile, and terrain is simply a set of properties assigned to atlas tiles. These attributes are then used by the dedicated TileMap painting mode, which intelligently selects tiles with terrain data. This means that any terrain tile can be drawn as a terrain or as a single tile just like any other tile.

The "polished" tileset often has variants that you should use on corners or edges of platforms, floors, etc. While it is possible to place these manually, this can quickly become tedious. Handling this situation with procedurally generated levels is also difficult and requires a lot of code.

Godot provides terrain to automate this tile joining. This allows you to automatically use the "correct" tile variant.

Terrains are grouped into TerrainSets. Each terrain set is assigned a mode from  Match Corners and Sides , Match Corners and Match sides . They define how terrains in a terrainset match up with each other.

notes

The above modes correspond to the previous bitmask mode autotiles used in Godot 3.x: 2×2, 3×3 or 3×3 minimum. This is also similar to what the Tiled editor does.

With the TileMap node selected, go to the inspector and create a new terrain set in the TileSet resource :

Create TerrainSets (inside TileMap nodes) in the TileSet Asset Inspector¶

After creating a terrain set, one or more terrains must be created in the terrain set:

Creating terrains in terrainsets¶

In the TileSet editor, switch to selection mode and click on a tile. In the middle column, expand the Terrains section, and give the tile a Terrainset ID and a Terrain ID. means "No Terrain Set" or "No Terrain", which means you must first-1 set the Terrain Set to or larger before you can  set the Terrain to or larger.00

notes

Terrain Set IDs and Terrain IDs are independent of each other. They also start with 0, instead of 1.

Configuring terrain on individual tiles in selection mode of the TileSet editor¶

After doing this, you can now configure the Terrain Peering Bits section visible in the middle column . The alignment bit determines which tile will be placed based on adjacent tiles. -1A special value that refers to empty space.

For example, if a tile has all bits set to 0or higher, it will only appear if all 8 adjacent tiles use a tile with the same terrain ID. Exists in corners or sides. If a tile's bits are set to 0or higher, but the top-left, top, and top-right bits are set -1, it will only appear if there is empty space on top of it (including diagonal lines).

Configure terrain equivalence on individual tiles in TileSet editor's selection mode¶

An example configuration for a complete tile table looks like this:

Example of a complete tile table for a side-scrolling game¶

Example of a complete tile table for a side scrolling game with visible terrain equivalence¶

Assign properties to multiple tiles at once¶

There are two ways to assign properties to multiple tiles at once. Depending on your use case, one method may be faster than the other:

Using Multiple Tile Selection¶

If you wish to configure multiple properties at once, select the selection mode at the top of the TileSet editor:

Once Shift does this, you can select multiple tiles in the right column by holding and then clicking the tiles. You can also perform a rectangular selection by holding down the left mouse button and then dragging the mouse. Shift Finally, you can deselect an already selected tile (without affecting the rest of the selection) by holding down and then clicking on a selected tile.

You can then assign properties using the inspectors in the middle column of the TileSet editor. Only properties you change here will be applied to all selected tiles. Just like in the editor's inspector, different properties on the selected tile will remain different until you edit it.

With number and color attributes, you will also see a preview of the attribute value on all tiles in the atlas after editing the attribute:

Use selection mode to select multiple tiles, then apply attributes¶

Painting with tile attributes¶

If you wish to apply an attribute to multiple tiles at once, you can use the attribute paint mode for this.

Configure the attributes to paint in the middle column, then click (or hold down the left mouse button) on the tiles in the right column to "paint" the attributes onto the tiles.

Drawing Tile Properties Using the TileSet Editor¶

Tile attribute painting is especially useful for manually setting time-consuming attributes, such as collision shapes:

Draw the collision polygon, then left click on the tile to apply it¶

Create alternate tiles¶

Sometimes, you want to use a single tile image (found only once in the atlas), but configure it differently. For example, you might want to use the same tile image, but rotate, flip, or modulate it with a different color. This can be done using substitute tiles .

To create an alternate tile, right-click on the base tile in the atlas displayed in the TileSet editor and select Create Alternate Tile :

Create alternate tiles by right - clicking on the base tile in the TileSet editor¶

If you are currently in selection mode, the alternative tile will already be selected for editing. If you are not currently in selection mode, you can still create alternate tiles, but you will need to switch to selection mode and select the alternate tile to edit.

If you don't see an alternate tile, pan to the right of the atlas image, as alternate tiles always appear in the TileSet editor to the right of the base tile for a given atlas:

Configure alternate tiles after clicking in the TileSet editor¶

After selecting an alternate tile, you can use the middle column to change any properties as you would on the base tile. However, the list of properties exposed differs from the base tile:

  • Alternative ID: A unique numeric identifier for this alternate tile. Changing it will break the existing TileMap, so be careful! This ID also controls the ordering in the list of alternate tiles shown in the editor.

  • Rendering > Flip H: If true, the tile is flipped horizontally.

  • Rendering > Flip V: If true, the tile is flipped vertically.

  • Rendering > Transpose: If true, the tile is rotated 90 degrees counterclockwise. Use it with Flip H and/or Flip V to perform 180 or 270 degree rotations.

  • Rendering > Texture Origin: The origin used to draw the tile. This can be used to visually offset the tile compared to the base tile.

  • Render > Modulation: The color multiplier to use when rendering the tile.

  • Rendering > Material: The material to use for this tile. This can be used to apply different blend modes or custom shaders to individual tiles.

  • Z index: The sort order of this tile. Higher values ​​will cause tiles to be rendered in front of other tiles on the same layer.

  • Y Sort Origin: Vertical offset for sorting tiles based on their Y coordinate in pixels. This allows layers to be used as if they were at different heights for a top-down game. Adjusting this can help alleviate issues with sorting certain tiles. Only works when Y Sort Enabled puts tiles on the TileMap layer.true

You can create other alt tile variations by clicking the big "+" icon next to the alt tile. This is equivalent to selecting the base tile and right-clicking on it to select "Create Replacement Tile" again .

notes

When a replacement tile is created, none of the properties of the base tile are inherited. If you want the properties to be the same on the base and replacement tiles, you must set the properties again on the replacement tile.

Using TileMaps¶

see also

This page assumes you have already created or downloaded a TileSet. If not, read Using a TileSet first , as you will need a TileSet to create a TileMap.

Introduction¶ _

A tile map is a grid of tiles used to create game layouts. There are several benefits to designing levels using TileMap nodes. First, they can draw layouts by "drawing" tiles onto the grid, which is much faster than placing individual Sprite2D nodes one after the other . Second, they allow for larger levels because they are optimized for drawing large numbers of tiles. Finally, you can add collision, occlusion, and navigation shapes to your tiles, adding even more power to your TileMap.

notes

Godot 4.0 has moved several per-tile properties (such as tile rotation) from TileMap to TileSet. It is no longer possible to rotate individual tiles in the TileMap editor. Instead, the TileSet editor must be used to create alternate rotated tiles.

This change allows for greater design consistency, since not every tile needs to be rotated or flipped within a TileSet.

Specify TileSet in TileMap¶

If you followed the previous page on Using TileSets, you should have a TileSet resource built into your TileMap node. This is good for prototyping, but in real world projects you'll often have multiple levels reusing the same tileset.

The recommended way to reuse the same TileSet in multiple TileMap nodes is to save the TileSet to an external resource. To do this, click the drop-down menu next to the TileSet resource and choose Save :

Save built-in TileSet resources to external resource files¶

Create TileMap layer¶

Starting with Godot 4.0, you can place multiple layers in a single TileMap node . For example, this allows you to distinguish between foreground tiles and background tiles for better organization. You can place one tile per tier at a given location, and if you have more than one tier, you can overlap multiple tiles on top of each other.

By default, a TileMap node automatically has a prefab layer. You don't have to create additional layers if you only need one layer, but if you want to do so now, select the TileMap node and expand the Layers section in the inspector :

Create layers in TileMap nodes (example with 'background' and 'foreground')

Each layer has several properties that can be adjusted:

  • Name: The human-readable name displayed in the TileMap editor. This could be "background", "building", "vegetation", etc.

  • Enabled: If true, the layer is visible in the editor and when running the project.

  • Modulation: The color used as a multiplier for all tiles on the layer. This is also multiplied by each tile's Modulate property and the TileMap node's Modulate property. For example, you can use this to darken background tiles to make foreground tiles stand out more.

  • Y Sort Enabled: If true, the tiles are sorted according to their Y position on the TileMap. This can be used to prevent ordering issues with certain tilesets, especially isometric tiles.

  • Y-sort origin: The vertical offset (in pixels) used to Y-sort each tile. Only valid when Y Sort Enabled is true.

  • Z Index: Controls whether this layer is drawn in front or behind other TileMap layers. This value can be positive or negative; the layer with the highest z-index is drawn on top of the others. If multiple layers have the same Z-index property, the last layer in the layer list (the one that appears at the bottom of the list) will be drawn on top.

You can reorder layers by dragging and dropping the "three horizontal bars" icon to the left of the entries in the "Layers " section.

notes

You can create, rename or reorder layers in the future without affecting existing tiles. Be careful though, as removing a layer will also remove any tiles placed on that layer.

Open TileMap Editor¶

Select the TileMap node, and open the TileMap panel at the bottom of the editor:

Open the TileMap panel at the bottom of the editor. The TileMap node must be selected first.

Selecting tiles for painting¶

First, make sure you have selected the layer you want to paint on if you created other layers on top of it:

Select layers to paint in TileMap editor¶

hint

In the 2D editor, layers that you are not currently editing from the same TileMap node will be grayed out in the TileMap editor. You can disable this behavior by clicking the icon next to the layer selection menu ( highlights the selected TileMap layer tooltip).

If you have not created other layers, you can skip the above steps, because the first layer is automatically selected when entering the TileMap editor.

Before placing tiles in the 2D editor, you must select one or more tiles in the TileMap panel located at the bottom of the editor. To do this, click on a tile in the TileMap panel, or hold down the mouse button to select multiple tiles:

Selecting a tile in the TileMap editor by clicking¶

hint

As in the 2D and TileSet editors, you can use the middle or right mouse button to pan on the TileMap panel, and use the mouse wheel or the top left button to zoom.

You can also hold Shift to append to the current selection. When multiblock is selected, the multiblock is placed every time a paint operation is performed. This can be used to draw structures made of multiple tiles (such as large platforms or trees) in a single click.

The final selection does not have to be contiguous: if there is a gap between the selected tiles, it will be left empty in the pattern drawn in the 2D editor.

Select multiple tiles in the TileMap editor by holding down the left mouse button¶

If you created alternate tiles in the TileSet, you can select them to be drawn to the right of the base tile:

Select Alternate Tile in TileMap Editor¶

Finally, if you created your scene collection in a TileSet, you can place scene tiles in a TileMap:

Using the TileMap editor to place scene tiles containing particles¶

Drawing Modes and Tools¶

Using the toolbar at the top of the TileMap editor, you can choose between various painting modes and tools. These modes affect the behavior of clicking in the 2D editor, not the TileMap panel itself.

From left to right, the painting modes and tools you can choose from are:

Select¶ _

Select tiles by clicking on a single tile, or hold down the left mouse button to select multiple tiles using a rectangle in the 2D editor. Note that empty areas cannot be selected: if you create a rectangular selection, only non-empty tiles will be selected.

To append to the current selection, hold Shift and select a tile. To remove from the current selection, hold Ctrl and select a tile.

This selection can then be used in any other paint mode to quickly create a copy of the placed pattern.

While in selection mode, you cannot place new tiles, but you can still erase tiles by right-clicking after making a selection. No matter where you click in the selection, the entire selection will be deleted.

While in paint mode, you can temporarily toggle this mode by holding down Ctrl and then performing a selection.

hint

You can copy and paste placed tiles by performing a selection and pressing . Paste selection after left click. You can perform more copies this way by pressing again. Right-click or press Cancel Paste. Ctrl + CCtrl + VCtrl + VEscape

Draw¶ _

The standard paint mode allows you to place tiles by clicking or holding down the left mouse button.

If you right click, the currently selected tile will be removed from the tile map. In other words, it will be replaced by blank space.

If you select multiple tiles in the TileMap or use the selection tool, they will be placed every time you click or drag the mouse while holding down the left mouse button.

hint

In drawing mode, you can draw a line by holding down the left mouse button  before Shift , then dragging the mouse to the end point of the line. This is the same as using the line tool described below.

You can also draw a rectangle by  holding down the left mouse button before pressing Ctrl and Shift , then dragging the mouse to the endpoints of the rectangle. This is the same as using the rectangle tool described below.

Ctrl Finally, you can pick existing tiles in the 2D editor by holding and clicking a tile (or holding and dragging the mouse). This will switch the currently drawn tile to the one you just clicked. This is the same as using the selector tool described below.

line¶ _

With line drawing mode selected, you can draw a line that is always 1 tile thick (regardless of its orientation).

If you right click while in line drawing mode, you will erase a line.

If you have selected multiple tiles in the TileMap or with the selection tool, you can place them in a repeating pattern on a line.

While in paint or eraser mode, you can temporarily toggle this mode by holding Shift and then drawing.

Draw the platform diagonally with the line tool after selecting two tiles¶

rectangle¶ _

After selecting the rectangle drawing mode, you can draw an axis-aligned rectangle.

If you right-click in Rectangle Paint mode, you will erase the axis-aligned rectangle.

If you have selected multiple tiles in the TileMap or with the selection tool, they can be placed in a repeating pattern within a rectangle.

While in Paint or Eraser mode, you can temporarily toggle this mode by holding Ctrl and then Shift while drawing.

bucket full¶

When Bucket Fill mode is selected, you can choose whether painting should be limited to contiguous areas by toggling the Contiguous checkbox that appears on the right side of the toolbar .

If "Contiguous" is on (the default), only matching tiles that touch the current selection will be replaced. This continuous check is performed horizontally and vertically, but not diagonally.

If Contiguous is disabled , all tiles with the same ID in the entire TileMap will be replaced by the currently selected tile. If an empty tile with Contiguous unchecked is selected , all tiles within the rectangle containing the TileMap's valid area will be replaced.

If you right click in Bucket Fill mode, you will replace matching tiles with empty tiles.

If you have selected multiple tiles in the TileMap or with the selection tool, they can be placed in a repeating pattern within the fill area.

Using the bucket fill tool¶

Selectors¶ _

With picker mode selected, you can pick existing tiles in the 2D editor by holding Ctrl and clicking a tile. This will switch the currently drawn tile to the one you just clicked. You can also pick multiple tiles at once by holding down the left mouse button and forming a rectangular selection. Only non-empty tiles can be picked.

While in paint mode, you can temporarily toggle this mode by holding down Ctrl and clicking or dragging the mouse.

Eraser¶ _

This mode is combined with any other painting mode (Paint, Line, Rectangle, Bucket Fill). With eraser mode enabled, tiles are replaced with empty tiles when left clicking instead of drawing a new line.

You can temporarily toggle this mode by right-clicking instead of left-clicking in any other mode.

Random painting with scatter¶

When painting, you can choose to enable randomization . When enabled, painting will randomly select a tile among all currently selected tiles. This is supported by the paint, line, rectangle and bucket fill tools. To effectively draw randomly, you must select multiple tiles in the TileMap editor or use scatter (both methods can be combined).

If Scattering is set to a value greater than 0, there is a chance that no tiles will be placed when drawn. This is useful for adding occasional, non-repeating detail to large areas (such as adding grass or breadcrumbs on a large top-down TileMap).

Example when using paint mode:

Multi-select random selection, then hold down the left mouse button to draw¶

Example when using Bucket Fill mode:

Use the bucket fill tool for a single tile, but with randomization and scatter enabled¶

notes

Eraser mode does not take randomization and scattering into account. All tiles in the selection are always removed.

Saving and Loading Prefab Tile Placements Using Patterns¶

While you can copy and paste tiles in selection mode, you may want to save premade patterns of tiles to put together at any time. This can be done on a per TileMap basis by selecting the Patterns tab of the TileMap editor .

To create a new pattern, switch to selection mode, make a selection and press . Click on an empty area in the Pattern tab (a blue focus rectangle should appear around the empty area) and press: Ctrl + CCtrl + V

Create a new schema from a selection in the TileMap editor¶

To use an existing pattern, click its image in the Patterns tab, switch to any paint mode, and left-click somewhere in the 2D editor:

Placing Existing Patterns Using the TileMap Editor¶

As with multi-tile selection, the pattern will be repeated if used with Line, Rectangle, or Bucket Fill paint modes.

notes

Despite editing in the TileMap editor, the pattern is still stored in the TileSet resource. This allows pattern reuse in different TileMap nodes after loading a TileSet resource saved to an external file.

Automatically handle tile joins with Terrain¶

To use terrains, a TileMap node must have at least one terrain set and one terrain in that terrain set. If you haven't created a terrain set for a TileSet, see Creating a Terrain Set (Automatic Tile).

Terrain connections have 3 drawing modes:

  • Connect , where the tile is connected to surrounding tiles on the same TileMap layer.

  • Path where tiles are connected to tiles drawn with the same stroke (until the mouse button is released).

  • Tile-specific overrides to resolve conflicts or handle situations not covered by the terrain system.

Connect mode is easier to use, but Path is more flexible because it allows the artist more control over the painting process. For example, Path could allow roads to be directly adjacent to each other without connecting, while Connect would force two roads to connect.

Select join mode in Terrain tab of TileMap editor¶

Select path mode in Terrain tab of TileMap editor¶

Finally, you can select specific tiles from the terrain to resolve conflicts in certain situations:

Drawing with specific tiles in the Terrains tab of the TileMap editor¶

Any tile with at least one bit set to the value of the corresponding terrain ID will appear in the tile list for selection.

Handling missing tiles¶

If you delete a tile in a TileSet referenced in the TileMap, the TileMap will display a placeholder indicating that an invalid tile ID was placed:

Missing tiles in TileMap editor due to broken TileSet reference¶

These placeholders are not visible in a running project , but the tile data is still saved to disk. This allows you to safely close and reopen such scenes. Once you re-add tiles with matching IDs, they will appear as new tiles.

notes

Missing tile placeholders may not be visible until you select the TileMap node and open the TileMap editor.

Guess you like

Origin blog.csdn.net/drgraph/article/details/130815479