Quick answer: The most common cause is that collision shapes were not painted onto the tiles in the TileSet editor. Even if you set up physics layers on the TileSet, you must manually draw collision polygons on each tile that should be solid. Without shapes, the tiles have no physical presence.

Here is how to fix Godot tilemaplayer collision not working. Your tilemap looks great in the editor — platforms, walls, ground tiles all placed exactly where you want them — but your CharacterBody2D falls straight through everything. The tiles have no collision, and the physics engine treats them as if they do not exist. This is the most common TileMapLayer issue in Godot 4, and it comes down to how the tile set editor separates visual tiles from physics tiles.

The Symptom

You have a TileMapLayer node (or the older TileMap node) with tiles painted across your level. Visually the level renders correctly. But when you run the scene, your player character passes through every tile as if they are purely decorative. No collisions are detected, is_on_floor() never returns true, and the character free-falls through the entire map.

This is particularly frustrating because in many other engines, painting a tile implies that it is solid. Godot separates the visual representation from the physics representation. A tile can exist visually without having any physics body attached to it, and the tile set editor requires you to explicitly define collision shapes for each tile that should be solid.

A subtler variant of this problem is partial collision — some tiles collide and others do not, seemingly at random. This usually means you painted collision shapes on some tiles but not all of them, or that your tile set has multiple physics layers and shapes were painted on a layer that does not match the character’s collision mask.

Another variant involves tiles that collide but with incorrect shapes. The character may clip corners, fall through edges, or get stuck in gaps between tiles. This points to collision polygons that do not align with the tile boundaries, often caused by drawing custom shapes when a full-tile rectangle was intended.

Understanding TileSet Physics Layers

Godot 4’s tile system has a layered architecture for physics. Before any tile can participate in collision detection, two things must be true: the TileSet resource must have at least one physics layer defined, and each tile that should be solid must have a collision polygon drawn on that physics layer.

A physics layer on a TileSet is similar to the collision layer/mask system on individual nodes. Each physics layer has its own collision layer bits (what it IS) and collision mask bits (what it SEES). When you add a physics layer to a TileSet, you are creating a channel through which collision shapes on tiles can interact with other physics bodies in the scene.

You can have multiple physics layers on a single TileSet. This is useful when different tiles should interact with different groups of objects. For example, you might have one physics layer for solid ground (collision layer 1) and another for one-way platforms (collision layer 3). Each tile can have different collision shapes on different physics layers, or shapes on only one layer.

The TileMapLayer node itself does not have its own collision layer/mask in the way a StaticBody2D does. Instead, the collision properties come from the TileSet’s physics layers. This means you configure collision in the TileSet resource, not on the TileMapLayer node’s Inspector.

Setting Up Tile Collision Step by Step

First, open your TileSet resource. You can do this by selecting the TileMapLayer node and clicking the TileSet property in the Inspector, or by double-clicking the .tres file in the FileSystem dock.

Step 1: Add a physics layer. In the TileSet Inspector, find the Physics Layers section and click “Add Element.” This creates Physics Layer 0. Set its collision layer and mask bits to match your game’s collision setup. For a simple platformer, set collision layer to 1 (the same layer your character’s mask checks for) and leave the mask at 0 (tiles usually do not need to detect other objects).

Step 2: Paint collision shapes. Switch to the TileSet editor at the bottom of the screen. Select the Paint mode and choose Physics Layer 0 from the paint properties dropdown. Now select a tile and use the polygon tools to draw a collision shape. For full-tile rectangles, press F to auto-fill the tile extents. For slopes or partial tiles, draw a custom polygon by clicking to place vertices.

# Verify collision setup at runtime
extends TileMapLayer

func _ready():
  var tileset = tile_set
  if tileset == null:
    push_error("No TileSet assigned to TileMapLayer")
    return

  var physics_layers = tileset.get_physics_layers_count()
  print("TileSet has ", physics_layers, " physics layer(s)")

  if physics_layers == 0:
    push_warning("No physics layers on TileSet - tiles will have no collision")

Step 3: Verify layer/mask alignment. Your character’s collision mask must include the layer that the TileSet’s physics layer is on. If the TileSet physics layer has collision layer 1 enabled, your CharacterBody2D must have collision mask bit 1 enabled.

# Diagnostic: check if character can see tilemap layer
extends CharacterBody2D

func _ready():
  print("Character collision mask: ", collision_mask)
  # Bit 1 should be set if tiles are on layer 1
  if not get_collision_mask_value(1):
    push_warning("Character mask does not include layer 1 - cannot collide with default tiles")

Common Layer and Mask Mismatches

The collision layer/mask system trips up developers constantly because it requires both sides to be configured correctly. Here are the most common mismatches with TileMapLayer:

TileSet physics layer on layer 1, character mask on layer 0. Layers are 1-indexed in the editor UI but 0-indexed internally. When the Inspector shows “Layer 1” highlighted, the bit value is 1. If your code sets collision_mask = 0, the character detects nothing. Make sure the mask value includes the tile layer’s bit.

Multiple physics layers with shapes on the wrong one. If your TileSet has two physics layers and you painted collision shapes on Physics Layer 1 but your character’s mask only includes Physics Layer 0’s collision layer, the shapes will exist but the character will not interact with them. Check which physics layer has the actual shapes painted.

Character on layer 1, TileSet mask does not include layer 1. This is actually fine for one-way detection. The TileSet mask controls what the tilemap “sees,” but for static collision the character’s mask and the tile’s layer are what matter. The TileSet’s mask is only relevant if you need tiles to detect other bodies (which is unusual).

To debug these issues, enable the Visible Collision Shapes option under Debug in the top menu bar while running the game. This draws all collision shapes in the scene, making it immediately obvious which tiles have shapes and which do not. If you see your character’s shape but no tile shapes, the tiles are missing collision polygons.

Migrating from TileMap to TileMapLayer

If you were using the older TileMap node and upgraded to Godot 4.3 or later, you may need to migrate to TileMapLayer. The TileMap node was deprecated in favor of individual TileMapLayer nodes, where each layer is a separate node in the scene tree.

During migration, the TileSet resource and its physics layers should carry over unchanged. However, if you had per-layer collision settings on the old TileMap node, those need to be reconfigured on the TileSet’s physics layers instead. The most common issue during migration is that the TileSet’s physics layer collision bits reset to defaults, breaking existing collision setups.

To convert an existing TileMap to TileMapLayer nodes, you can right-click the TileMap node in the scene tree and look for conversion options, or manually create TileMapLayer nodes and assign the same TileSet resource. The tile data can be copied between them, and the collision shapes defined in the TileSet will automatically apply to the new TileMapLayer nodes.

If your game uses procedural tile placement via code, update your API calls. The methods for setting and getting cells are the same on TileMapLayer as they were on TileMap, but you call them on the layer node directly instead of specifying a layer index parameter.

"Every time someone tells me their tilemap collision is broken, the first question I ask is: did you actually paint collision shapes on the tiles? Nine out of ten times, they set up the physics layer but never painted the shapes."

Related Issues

If your tile collision shapes are present but the character clips through corners, see our guide on CharacterBody2D jittering against walls. For one-way platform tiles that the player cannot jump through, check one-way collision platform setup. If your collision layers and masks are confusing you across the entire project, our collision layer/mask deep dive explains the system from the ground up.

Paint the collision shapes. The physics layer alone is not enough.