Introdução
O Godot 4 reescreveu completamente o sistema TileMap. Se você usava o TileMap no Godot 3, quase tudo mudou — o editor de TileSet, a forma como os tiles são definidos, o auto-tiling, as camadas e a API do GDScript. Este guia aborda a nova arquitetura do zero.
Usuários do Godot 3: Os antigos autotile, set_cellv() e cell_size foram todos removidos. Consulte a seção Migração do Godot 3 no final da página.
Nova Arquitetura do TileMap
O sistema TileMap do Godot 4 tem dois componentes principais:
- Node TileMap — O node que você adiciona à sua cena. Ele contém uma ou mais camadas e referencia um recurso TileSet.
- Recurso TileSet — Define os próprios tiles. Contém fontes (atlas, coleção de cenas, etc.), camadas de física, camadas de navegação, camadas de dados personalizados e conjuntos de terreno.
Mudança importante: No Godot 3, o tamanho do tile era definido no node TileMap. No Godot 4, o tamanho do tile é definido no recurso TileSet, e o TileMap apenas o referencia.
Fontes de TileSet
Um TileSet pode ter várias fontes, cada uma identificada por um source_id (inteiro). Os tipos de fonte incluem:
- TileSetAtlasSource — O tipo mais comum. Uma única imagem de textura contendo vários tiles organizados em uma grade.
- TileSetScenesCollectionSource — Cada tile é uma cena empacotada, útil para tiles animados ou interativos.
Configurando um TileSet
Passo 1: Criar o Recurso TileSet
- Adicione um node TileMap à sua cena.
- No Inspetor, clique na propriedade Tile Set e selecione New TileSet.
- Defina o Tile Size (por exemplo, 16x16 ou 32x32).
Passo 2: Adicionar uma Fonte de Atlas
- Clique no TileSet para abrir o editor de TileSet no painel inferior.
- Clique no botão + e selecione Atlas.
- Arraste a imagem do seu tileset para a propriedade Texture.
- O editor a divide automaticamente em tiles com base no seu tamanho de tile. Você pode ajustar a região da textura e as margens.
Passo 3: Configurar as Propriedades do Tile
No editor de TileSet, você pode adicionar vários tipos de camada que se aplicam a todos os tiles:
- Physics Layers — Formas de colisão para tiles
- Navigation Layers — Polígonos caminháveis para pathfinding
- Custom Data Layers — Dados tipados arbitrários (bool, int, float, String, etc.)
- Terrain Sets — Para auto-tiling (o substituto do autotile do Godot 3)
Camadas do TileMap
Um único node TileMap pode conter várias camadas. Isso é uma grande melhoria em relação ao Godot 3, onde você precisava de nodes TileMap separados para o fundo e o primeiro plano. Cada camada pode ter suas próprias configurações de z-index, y-sort e modulate.
Configuração comum de camadas:
- Layer 0 — Fundo (chão, piso) — z-index: -1
- Layer 1 — Terreno (paredes, obstáculos) — z-index: 0
- Layer 2 — Primeiro plano (decoração acima do jogador) — z-index: 1
API do GDScript para Camadas
# 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 a API: O primeiro parâmetro em set_cell() é sempre o índice da camada (0, 1, 2...). O segundo é a posição da célula como Vector2i. O terceiro é o source_id, e o quarto é o atlas_coords como Vector2i.
Sistema de Terreno (Auto-Tiling)
O sistema de terreno substitui o autotile do Godot 3. Ele seleciona automaticamente a variante de tile correta com base nos tiles vizinhos.
Configurando Terrenos
- No TileSet, adicione um Terrain Set (Inspetor → Terrain Sets → Add Element).
- Escolha o modo de terreno: Match Corners and Sides (47 tiles), Match Corners (16 tiles) ou Match Sides (16 tiles).
- Adicione tipos de terreno dentro do conjunto (por exemplo, "Grass", "Dirt", "Water").
- No editor de TileSet, mude para o modo Select, selecione um tile e pinte os bits de peering de terreno em cada tile.
Pintando Terrenos
Depois que os terrenos estiverem configurados, mude para o editor de TileMap e selecione a aba Terrains. Escolha o tipo de terreno e pinte diretamente no mapa. O Godot selecionará automaticamente a variante de tile correta.
# Set terrain programmatically
tilemap.set_cells_terrain_connect(0, [Vector2i(5, 3)], 0, 0)
# Parameters: layer, cells array, terrain_set, terrain index
Física nos Tiles
Para adicionar colisão aos tiles:
- Adicione uma Physics Layer no Inspetor do TileSet.
- Configure qual camada de colisão e máscara esta camada de física usa.
- No editor de TileSet, mude para a aba Physics e desenhe polígonos de colisão em cada tile.
Dica: Você pode ter várias camadas de física para diferentes tipos de tile. Por exemplo, uma camada para paredes (bloqueia o movimento) e outra para perigos (aciona dano por sobreposição via Area2D).
Dados Personalizados nos Tiles
As camadas de dados personalizados permitem anexar metadados tipados a qualquer tile. Isso é extremamente útil para a lógica de jogabilidade.
Configurando Dados Personalizados
- No Inspetor do TileSet, adicione uma Custom Data Layer.
-
Dê um nome a ela (por exemplo, "is_destructible") e defina o tipo (por exemplo,
bool). - No editor de TileSet, mude para a aba Custom Data e defina os valores por tile.
Lendo Dados Personalizados no 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))
Exemplos comuns de dados personalizados:
is_destructible: booldamage: intmovement_cost: floattile_type: String(por exemplo, "water", "lava", "ice")spawn_chance: float
Posicionamento Procedural de Tiles
Posicionar tiles programaticamente é simples com a nova 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()
Conversão de Coordenadas de Mundo para 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)
Migração do 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) |
| Uma única camada por node TileMap | Várias camadas em um único TileMap |
TileMap.tile_set = preload(...) |
Recurso TileSet atribuído no Inspetor ou via código |
world_to_map() |
local_to_map() |
map_to_world() |
map_to_local() |
Erros Comuns
-
Esquecer de criar um TileSet primeiro. O node TileMap não exibirá o editor de tiles até que você atribua um recurso TileSet. Crie um no Inspetor.
-
source_id incorreto. Se você tiver apenas uma fonte de atlas, seu
source_idé0. Adicionar uma segunda fonte lhe dásource_id = 1. Verifique o painel inferior do editor de TileSet — cada aba de fonte mostra seu ID. -
Confundir atlas_coords com IDs de tile. No Godot 4, não há IDs de tile simples. Em vez disso, você referencia os tiles pela sua posição na grade do atlas como
Vector2i(column, row). -
Não especificar o parâmetro de camada. Toda operação de célula requer um índice de camada como primeiro argumento. Esquecê-lo causa erros de argumento.
-
Usar
set_cellv(). Este método não existe mais. Useset_cell()com a nova assinatura.