Introduzione
Godot 4 ha riscritto completamente il sistema TileMap. Se hai usato TileMap in Godot 3, è cambiato quasi tutto — l'editor TileSet, il modo in cui vengono definiti i tile, l'auto-tiling, i livelli e l'API GDScript. Questa guida illustra la nuova architettura da zero.
Utenti Godot 3: I vecchi autotile, set_cellv() e cell_size sono tutti scomparsi. Vedi la sezione Migrazione da Godot 3 in fondo alla pagina.
La nuova architettura di TileMap
Il sistema TileMap di Godot 4 è composto da due componenti principali:
- Nodo TileMap — Il nodo che aggiungi alla tua scena. Contiene uno o più livelli e fa riferimento a una risorsa TileSet.
- Risorsa TileSet — Definisce i tile stessi. Contiene sorgenti (atlas, collezione di scene, ecc.), livelli di fisica, livelli di navigazione, livelli di dati personalizzati e terrain set.
Cambiamento importante: In Godot 3 la dimensione del tile veniva impostata sul nodo TileMap. In Godot 4 la dimensione del tile è definita nella risorsa TileSet, e il TileMap si limita a farvi riferimento.
Sorgenti TileSet
Un TileSet può avere più sorgenti, ciascuna identificata da un source_id (intero). I tipi di sorgente includono:
- TileSetAtlasSource — Il tipo più comune. Una singola immagine texture che contiene più tile disposti in una griglia.
- TileSetScenesCollectionSource — Ogni tile è una scena impacchettata, utile per tile animati o interattivi.
Configurare un TileSet
Passo 1: Creare la risorsa TileSet
- Aggiungi un nodo TileMap alla tua scena.
- Nell'Inspector, clicca sulla proprietà Tile Set e seleziona New TileSet.
- Imposta la Tile Size (es. 16x16 o 32x32).
Passo 2: Aggiungere una sorgente atlas
- Clicca sul TileSet per aprire l'editor TileSet nel pannello inferiore.
- Clicca sul pulsante + e seleziona Atlas.
- Trascina l'immagine del tuo tileset nella proprietà Texture.
- L'editor la suddivide automaticamente in tile in base alla dimensione del tile. Puoi regolare la regione della texture e i margini.
Passo 3: Configurare le proprietà dei tile
Nell'editor TileSet puoi aggiungere vari tipi di livello che si applicano a tutti i tile:
- Physics Layers — Forme di collisione per i tile
- Navigation Layers — Poligoni percorribili per il pathfinding
- Custom Data Layers — Dati tipizzati arbitrari (bool, int, float, String, ecc.)
- Terrain Sets — Per l'auto-tiling (il sostituto dell'autotile di Godot 3)
Livelli TileMap
Un singolo nodo TileMap può contenere più livelli. Questo è un notevole miglioramento rispetto a Godot 3, dove servivano nodi TileMap separati per lo sfondo e il primo piano. Ogni livello può avere le proprie impostazioni di z-index, y-sort e modulate.
Configurazione tipica dei livelli:
- Layer 0 — Sfondo (terreno, pavimento) — z-index: -1
- Layer 1 — Terrain (muri, ostacoli) — z-index: 0
- Layer 2 — Primo piano (decorazioni sopra il giocatore) — z-index: 1
API GDScript per i livelli
# 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 sull'API: Il primo parametro di set_cell() è sempre l'indice del livello (0, 1, 2...). Il secondo è la posizione della cella come Vector2i. Il terzo è il source_id, e il quarto è l'atlas_coords come Vector2i.
Sistema Terrain (Auto-Tiling)
Il sistema terrain sostituisce l'autotile di Godot 3. Seleziona automaticamente la variante di tile corretta in base ai tile adiacenti.
Configurare i terrain
- In TileSet, aggiungi un Terrain Set (Inspector → Terrain Sets → Add Element).
- Scegli la modalità terrain: Match Corners and Sides (47 tile), Match Corners (16 tile) o Match Sides (16 tile).
- Aggiungi i tipi di terrain all'interno del set (es. "Grass", "Dirt", "Water").
- Nell'editor TileSet, passa alla modalità Select, seleziona un tile e dipingi i terrain peering bit su ogni tile.
Dipingere i terrain
Una volta configurati i terrain, passa all'editor TileMap e seleziona la scheda Terrains. Scegli il tuo tipo di terrain e dipingi direttamente sulla mappa. Godot selezionerà automaticamente la variante di tile corretta.
# Set terrain programmatically
tilemap.set_cells_terrain_connect(0, [Vector2i(5, 3)], 0, 0)
# Parameters: layer, cells array, terrain_set, terrain index
Fisica sui tile
Per aggiungere la collisione ai tile:
- Aggiungi un Physics Layer nell'Inspector del TileSet.
- Configura quali collision layer e mask usa questo livello di fisica.
- Nell'editor TileSet, passa alla scheda Physics e disegna i poligoni di collisione su ogni tile.
Suggerimento: Puoi avere più livelli di fisica per diversi tipi di tile. Ad esempio, un livello per i muri (blocca il movimento) e un altro per i pericoli (attiva il danno tramite sovrapposizione Area2D).
Dati personalizzati sui tile
I livelli di dati personalizzati ti permettono di associare metadati tipizzati a qualsiasi tile. Questo è estremamente utile per la logica di gioco.
Configurare i dati personalizzati
- Nell'Inspector del TileSet, aggiungi un Custom Data Layer.
-
Assegnagli un nome (es. "is_destructible") e imposta il tipo (es.
bool). - Nell'editor TileSet, passa alla scheda Custom Data e imposta i valori per ogni tile.
Leggere i dati personalizzati nel codice
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))
Esempi comuni di dati personalizzati:
is_destructible: booldamage: intmovement_cost: floattile_type: String(es. "water", "lava", "ice")spawn_chance: float
Posizionamento procedurale dei tile
Posizionare i tile in modo programmatico è semplice con la nuova 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()
Conversione da coordinate mondo a coordinate mappa
# 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)
Migrazione da 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 terrain (Terrain Sets) |
| Un livello per nodo TileMap | Più livelli in un solo TileMap |
TileMap.tile_set = preload(...) |
Risorsa TileSet assegnata nell'Inspector o tramite codice |
world_to_map() |
local_to_map() |
map_to_world() |
map_to_local() |
Errori comuni
-
Dimenticare di creare prima un TileSet. Il nodo TileMap non mostra l'editor dei tile finché non assegni una risorsa TileSet. Creane una nell'Inspector.
-
source_id sbagliato. Se hai una sola sorgente atlas, il suo
source_idè0. Aggiungendo una seconda sorgente le viene assegnatosource_id = 1. Controlla il pannello inferiore dell'editor TileSet — ogni scheda sorgente mostra il proprio ID. -
Confondere atlas_coords con gli ID dei tile. In Godot 4 non esistono ID di tile semplici. Al contrario, fai riferimento ai tile tramite la loro posizione nella griglia dell'atlas come
Vector2i(column, row). -
Non specificare il parametro del livello. Ogni operazione sulle celle richiede un indice di livello come primo argomento. Dimenticarlo causa errori di argomento.
-
Usare
set_cellv(). Questo metodo non esiste più. Usaset_cell()con la nuova firma.