Introducción
Godot 4 reescribió por completo el sistema TileMap. Si usaste TileMap en Godot 3, casi todo ha cambiado — el editor de TileSet, cómo se definen los tiles, el auto-tiling, las capas y la API de GDScript. Esta guía cubre la nueva arquitectura desde cero.
Usuarios de Godot 3: Los antiguos autotile, set_cellv() y cell_size han desaparecido por completo. Consulta la sección Migración desde Godot 3 al final de la página.
La nueva arquitectura de TileMap
El sistema TileMap de Godot 4 tiene dos componentes principales:
- Nodo TileMap — El nodo que añades a tu escena. Contiene una o más capas y hace referencia a un recurso TileSet.
- Recurso TileSet — Define los tiles en sí. Contiene fuentes (atlas, colección de escenas, etc.), capas de física, capas de navegación, capas de datos personalizados y conjuntos de terreno.
Cambio clave: En Godot 3, el tamaño del tile se establecía en el nodo TileMap. En Godot 4, el tamaño del tile se define en el recurso TileSet, y el TileMap simplemente lo referencia.
Fuentes de TileSet
Un TileSet puede tener múltiples fuentes, cada una identificada por un source_id (entero). Los tipos de fuente incluyen:
- TileSetAtlasSource — El tipo más común. Una única imagen de textura que contiene varios tiles dispuestos en una cuadrícula.
- TileSetScenesCollectionSource — Cada tile es una escena empaquetada, útil para tiles animados o interactivos.
Configurar un TileSet
Paso 1: Crear el recurso TileSet
- Añade un nodo TileMap a tu escena.
- En el Inspector, haz clic en la propiedad Tile Set y selecciona New TileSet.
- Establece el Tile Size (por ejemplo, 16x16 o 32x32).
Paso 2: Añadir una fuente de atlas
- Haz clic en el TileSet para abrir el editor de TileSet en el panel inferior.
- Haz clic en el botón + y selecciona Atlas.
- Arrastra tu imagen de tileset a la propiedad Texture.
- El editor la divide automáticamente en tiles según tu tamaño de tile. Puedes ajustar la región de textura y los márgenes.
Paso 3: Configurar las propiedades de los tiles
En el editor de TileSet, puedes añadir varios tipos de capas que se aplican a todos los tiles:
- Physics Layers — Formas de colisión para los tiles
- Navigation Layers — Polígonos transitables para el pathfinding
- Custom Data Layers — Datos tipados arbitrarios (bool, int, float, String, etc.)
- Terrain Sets — Para auto-tiling (el reemplazo del autotile de Godot 3)
Capas de TileMap
Un único nodo TileMap puede contener múltiples capas. Es una gran mejora respecto a Godot 3, donde necesitabas nodos TileMap separados para el fondo y el primer plano. Cada capa puede tener sus propios ajustes de z-index, y-sort y modulate.
Configuración de capas habitual:
- Layer 0 — Fondo (suelo, terreno) — z-index: -1
- Layer 1 — Terreno (paredes, obstáculos) — z-index: 0
- Layer 2 — Primer plano (decoración por encima del jugador) — z-index: 1
API de GDScript para capas
# Set a cell on layer 0
tilemap.set_cell(0, Vector2i(5, 3), source_id, atlas_coords)
# Get cell info
var source = tilemap.get_cell_source_id(0, Vector2i(5, 3))
var coords = tilemap.get_cell_atlas_coords(0, Vector2i(5, 3))
# Erase a cell
tilemap.erase_cell(0, Vector2i(5, 3))
# Check if a cell is occupied
if tilemap.get_cell_source_id(0, Vector2i(5, 3)) != -1:
print("Cell has a tile")
Nota sobre la API: El primer parámetro de set_cell() es siempre el índice de capa (0, 1, 2...). El segundo es la posición de la celda como Vector2i. El tercero es el source_id, y el cuarto son las atlas_coords como Vector2i.
Sistema de terreno (Auto-Tiling)
El sistema de terreno reemplaza el autotile de Godot 3. Selecciona automáticamente la variante de tile correcta según los tiles vecinos.
Configurar terrenos
- En TileSet, añade un Terrain Set (Inspector → Terrain Sets → Add Element).
- Elige el modo de terreno: Match Corners and Sides (47 tiles), Match Corners (16 tiles) o Match Sides (16 tiles).
- Añade tipos de terreno dentro del conjunto (por ejemplo, «Grass», «Dirt», «Water»).
- En el editor de TileSet, cambia al modo Select, selecciona un tile y pinta los bits de peering de terreno en cada tile.
Pintar terrenos
Una vez configurados los terrenos, cambia al editor de TileMap y selecciona la pestaña Terrains. Elige tu tipo de terreno y pinta directamente en el mapa. Godot seleccionará automáticamente la variante de tile correcta.
# Set terrain programmatically
tilemap.set_cells_terrain_connect(0, [Vector2i(5, 3)], 0, 0)
# Parameters: layer, cells array, terrain_set, terrain index
Física en los tiles
Para añadir colisión a los tiles:
- Añade una Physics Layer en el Inspector del TileSet.
- Configura qué capa y máscara de colisión usa esta capa de física.
- En el editor de TileSet, cambia a la pestaña Physics y dibuja polígonos de colisión en cada tile.
Consejo: Puedes tener varias capas de física para distintos tipos de tiles. Por ejemplo, una capa para paredes (bloquea el movimiento) y otra para peligros (provoca daño mediante solapamiento con Area2D).
Datos personalizados en los tiles
Las capas de datos personalizados te permiten adjuntar metadatos tipados a cualquier tile. Esto resulta extremadamente útil para la lógica de juego.
Configurar datos personalizados
- En el Inspector del TileSet, añade una Custom Data Layer.
-
Nómbrala (por ejemplo, «is_destructible») y establece el tipo (por ejemplo,
bool). - En el editor de TileSet, cambia a la pestaña Custom Data y establece los valores por tile.
Leer datos personalizados en código
var tile_data = tilemap.get_cell_tile_data(0, Vector2i(5, 3))
if tile_data:
var is_destructible = tile_data.get_custom_data("is_destructible")
var damage = tile_data.get_custom_data("damage")
if is_destructible:
destroy_tile(Vector2i(5, 3))
Ejemplos habituales de datos personalizados:
is_destructible: booldamage: intmovement_cost: floattile_type: String(por ejemplo, "water", "lava", "ice")spawn_chance: float
Colocación procedural de tiles
Colocar tiles mediante código es sencillo con la nueva API:
# Fill a rectangular area
for x in range(20):
for y in range(10):
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(0, 0))
# Random tile placement
for x in range(50):
for y in range(50):
if randf() > 0.7:
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(1, 0))
else:
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(0, 0))
# Get all used cells on a layer
var used_cells: Array[Vector2i] = tilemap.get_used_cells(0)
print("Layer 0 has ", used_cells.size(), " tiles")
# Clear all tiles on a layer
tilemap.clear_layer(0)
# Clear everything
tilemap.clear()
Conversión de coordenadas de mundo a mapa
# Convert world position to map coordinates
var map_pos: Vector2i = tilemap.local_to_map(world_position)
# Convert map coordinates to world position (center of tile)
var world_pos: Vector2 = tilemap.map_to_local(Vector2i(5, 3))
# Example: check what tile the player is standing on
var player_tile = tilemap.local_to_map(tilemap.to_local(player.global_position))
var tile_data = tilemap.get_cell_tile_data(0, player_tile)
if tile_data:
var tile_type = tile_data.get_custom_data("tile_type")
print("Player is on: ", tile_type)
Migración desde Godot 3
| Godot 3 | Godot 4 |
|---|---|
TileMap.cell_size |
TileSet.tile_size |
set_cellv(pos, tile_id) |
set_cell(layer, pos, source_id, atlas_coords) |
get_cellv(pos) |
get_cell_source_id(layer, pos) |
autotile |
Sistema de terreno (Terrain Sets) |
| Una sola capa por nodo TileMap | Múltiples capas en un solo TileMap |
TileMap.tile_set = preload(...) |
El recurso TileSet se asigna en el Inspector o mediante código |
world_to_map() |
local_to_map() |
map_to_world() |
map_to_local() |
Errores comunes
-
Olvidar crear primero un TileSet. El nodo TileMap no mostrará el editor de tiles hasta que asignes un recurso TileSet. Crea uno en el Inspector.
-
source_id incorrecto. Si solo tienes una fuente de atlas, su
source_ides0. Añadir una segunda fuente le asignasource_id = 1. Revisa el panel inferior del editor de TileSet — cada pestaña de fuente muestra su ID. -
Confundir atlas_coords con IDs de tile. En Godot 4 no existen los IDs de tile simples. En su lugar, referencias los tiles por su posición en la cuadrícula del atlas como
Vector2i(column, row). -
No especificar el parámetro de capa. Cada operación de celda requiere un índice de capa como primer argumento. Olvidarlo provoca errores de argumentos.
-
Usar
set_cellv(). Este método ya no existe. Usaset_cell()con la nueva firma.