ziva-sh/godot-tilemaplayer

Corrige le code Godot 4.3+ TileMapLayer - set_cell(coords, source_id, atlas_coords), lecture des cellules et données personnalisées, effacement, conversion de coordonnées, terrains, collisions de tuiles via les couches physiques TileSet, trouver la tuile touchée par un corps, et migration depuis le nœud TileMap obsolète et son API basée sur l'index de couche. À utiliser pour placer, lire ou effacer des tuiles en GDScript, construire un TileSet en code, générer des niveaux procéduralement, gérer les collisions de tuiles, ou porter du code TileMap depuis Godot 3 ou Godot 4.0.

Qu'est-ce que godot-tilemaplayer ?

Cette compétence fournit un guide de référence complet et à jour pour l'API `TileMapLayer` de Godot 4.3+, en remplacement du nœud `TileMap` désormais obsolète. Elle explique comment placer (`set_cell`), lire (`get_cell_source_id`, `get_cell_atlas_coords`) et effacer (`erase_cell`) des tuiles individuellement, ainsi que comment itérer sur les cellules utilisées. Le guide détaille l'utilisation des données personnalisées par tuile, des terrains (autotiling) avec `set_cells_terrain_connect`, et la gestion des collisions physiques, y compris la méthode pour identifier la tuile touchée par un `CharacterBody2D` en utilisant le point de contact. Elle couvre également la construction d'un `TileSet` en code pour la génération procédurale de niveaux, et propose une table de migration claire pour porter le code depuis `TileMap` (Godot 4.0) et même l'ancienne API Godot 3. Destinée aux développeurs utilisant Godot Engine, cette compétence met en garde contre les erreurs courantes comme l'utilisation de coordonnées pixel au lieu de coordonnées de carte, ou l'oubli de configurer les couches physiques dans le TileSet.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ziva-sh/godot-skills/tree/HEAD/skills/godot-tilemaplayer

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

TileMapLayer (Godot 4.3+)

Godot 4.3 a ajouté le nœud TileMapLayer et rendu TileMap obsolète. Chaque TileMapLayer représente une seule couche, donc un niveau avec sol, murs et décoration sera composé de trois nœuds TileMapLayer frères partageant un même TileSet. N'écrivez pas de nouveau code utilisant TileMap, et n'utilisez jamais l'API Godot 3 (set_cellv, world_to_map, set_cell(x, y, tile_id)).

L'API des cellules

Une cellule est identifiée par des coordonnées entières de carte (Vector2i). Une tuile est identifiée par trois valeurs :

  • source_id : l'ID d'une source dans le TileSet (une texture d'atlas ou une collection de scènes). La première source est généralement 0 ; vérifiez dans l'éditeur TileSet ou avec la valeur de retour de TileSet.add_source().
  • atlas_coords : la colonne et la ligne de la tuile dans cet atlas, en tuiles, pas en pixels.
  • alternative_tile : 0 sauf si vous avez créé des alternatives retournées ou pivotées.
extends TileMapLayer

const SOURCE_ID := 0
const GRASS := Vector2i(0, 0)
const WALL := Vector2i(1, 0)


func _ready() -> void:
	for x in range(10):
		set_cell(Vector2i(x, 5), SOURCE_ID, GRASS)
	set_cell(Vector2i(3, 4), SOURCE_ID, WALL)

	var source_id := get_cell_source_id(Vector2i(3, 4))  # -1 quand la cellule est vide
	var atlas := get_cell_atlas_coords(Vector2i(3, 4))  # Vector2i(-1, -1) quand vide
	print(source_id, atlas)

	erase_cell(Vector2i(3, 4))
	print(get_used_cells().size(), " cellules, limites ", get_used_rect())


func cell_at_global(global_point: Vector2) -> Vector2i:
	return local_to_map(to_local(global_point))


func center_of_cell(coords: Vector2i) -> Vector2:
	# map_to_local retourne le centre de la cellule dans l'espace local de cette couche.
	return to_global(map_to_local(coords))

Points importants :

  • set_cell(coords) avec les arguments par défaut efface la cellule (source_id vaut par défaut -1). Passez toujours source_id et atlas_coords lorsque vous placez une tuile.
  • Définir des atlas_coords qui n'existent pas dans l'atlas enregistre la cellule sans erreur (get_cell_source_id() retourne la source), et get_cell_tile_data() affichera plus tard The TileSetAtlasSource atlas has no tile at (x, y). et retournera null.
  • local_to_map() et map_to_local() fonctionnent dans l'espace local de la couche. Convertissez avec to_local() / to_global() lorsque la couche est déplacée ou mise à l'échelle.
  • get_used_cells_by_id(source_id, atlas_coords) trouve toutes les cellules utilisant une tuile particulière.
  • Les modifications sont regroupées jusqu'à la fin de l'image. Appelez update_internals() si vous avez besoin que les collisions ou les tuiles de scène soient mises à jour immédiatement.

Données personnalisées par tuile

Ajoutez une couche de données personnalisées dans le TileSet (Inspecteur > TileSet > Couches de données personnalisées, par exemple damage de type int), peignez les valeurs dans l'éditeur TileSet, puis lisez-les :

extends TileMapLayer


func damage_at(coords: Vector2i) -> int:
	var data := get_cell_tile_data(coords)
	if data == null:
		return 0
	return data.get_custom_data("damage")

get_cell_tile_data() retourne null pour les cellules vides et pour les tuiles de collection de scènes, donc vérifiez avant d'appeler des méthodes dessus.

Terrains (autotiling)

Les masques de bits autotile de Godot 3 sont devenus des ensembles de terrains. Dans le TileSet, ajoutez un ensemble de terrains et un terrain, puis peignez les bits de voisinage de chaque tuile dans l'éditeur TileSet. En code, passez toutes les cellules que vous voulez remplir :

extends TileMapLayer

const TERRAIN_SET := 0
const DIRT := 0


func paint_room(rect: Rect2i) -> void:
	var cells: Array[Vector2i] = []
	for x in range(rect.position.x, rect.end.x):
		for y in range(rect.position.y, rect.end.y):
			cells.append(Vector2i(x, y))
	set_cells_terrain_connect(cells, TERRAIN_SET, DIRT)

set_cells_terrain_connect() choisit les tuiles pour que les bords se connectent ; set_cells_terrain_path() est pour les routes et rivières dessinées comme un chemin. Si le résultat montre des tuiles incorrectes ou manquantes, les bits de voisinage dans le TileSet sont incomplets ; le code ne peut pas corriger cela.

Collision

Les tuiles n'ont de collision que si le TileSet possède une couche physique (Inspecteur TileSet > Couches physiques > Ajouter un élément) et que la tuile a un polygone de collision sur cette couche (éditeur TileSet, sélectionnez la tuile, Physique > Couche physique 0 ; appuyez sur F pour un rectangle pleine tuile). La propriété collision_enabled de la couche est activée par défaut. Les couches physiques portent également collision_layer et collision_mask, définis sur le TileSet, pas sur le nœud.

Pour trouver quelle tuile un CharacterBody2D a touchée, utilisez le point de collision. get_coords_for_body_rid() retourne les coordonnées d'un quadrant physique, pas d'une cellule, sauf si physics_quadrant_size est 1 (Godot 4.5+ fusionne jusqu'à 16 x 16 cellules en un seul corps par défaut) :

extends CharacterBody2D

@export var level: TileMapLayer


func _physics_process(delta: float) -> void:
	velocity += get_gravity() * delta
	move_and_slide()
	for i in get_slide_collision_count():
		var collision := get_slide_collision(i)
		if collision.get_collider() == level:
			# Avancez légèrement dans la tuile, car le point de contact est sur son bord.
			var inside := collision.get_position() - collision.get_normal()
			var coords := level.local_to_map(level.to_local(inside))
			print("Touche la tuile ", coords)

Construire un TileSet en code

Utile pour les niveaux procéduraux et pour les tests qui ne peuvent pas utiliser l'éditeur TileSet. Les points du polygone de collision sont relatifs au centre de la tuile.

extends Node2D


func _ready() -> void:
	var tile_set := TileSet.new()
	tile_set.tile_size = Vector2i(16, 16)
	tile_set.add_physics_layer()

	var source := TileSetAtlasSource.new()
	source.texture = load("res://tiles.png") as Texture2D
	source.texture_region_size = Vector2i(16, 16)
	source.create_tile(Vector2i(0, 0))
	var source_id := tile_set.add_source(source)

	var data := source.get_tile_data(Vector2i(0, 0), 0)
	data.add_collision_polygon(0)
	data.set_collision_polygon_points(0, 0, PackedVector2Array([
		Vector2(-8, -8), Vector2(8, -8), Vector2(8, 8), Vector2(-8, 8),
	]))

	var layer := TileMapLayer.new()
	layer.tile_set = tile_set
	add_child(layer)
	layer.set_cell(Vector2i(0, 0), source_id, Vector2i(0, 0))

Migration depuis TileMap

Dans l'éditeur : sélectionnez le TileMap, ouvrez le panneau inférieur TileMap, cliquez sur l'icône de boîte à outils et choisissez "Extraire les couches TileMap en tant que nœuds TileMapLayer individuels". Ensuite, mettez à jour les scripts : chaque méthode de TileMap qui prenait un index de layer en premier argument devient une méthode sur le nœud de cette couche, sans l'index.

Ancien codeTileMapLayer
tile_map.set_cell(0, coords, source_id, atlas_coords)ground.set_cell(coords, source_id, atlas_coords)
tile_map.get_cell_source_id(1, coords)walls.get_cell_source_id(coords)
tile_map.get_used_cells(0)ground.get_used_cells()
tile_map.set_layer_enabled(2, false)decoration.enabled = false
tile_map.set_layer_z_index(1, 5)walls.z_index = 5
Godot 3 set_cellv(pos, id), world_to_map(p), map_to_world(c)set_cell(coords, source_id, atlas_coords), local_to_map(p), map_to_local(c)

Erreurs courantes

  • Passer des positions en pixels à set_cell(). Convertissez d'abord avec local_to_map().
  • Appeler set_cell(coords, tile_index) avec un seul nombre : le deuxième argument est l'ID de source, et atlas_coords vaut par défaut Vector2i(-1, -1), ce qui efface la cellule.
  • Attendre des collisions d'un TileSet sans couche physique, ou de tuiles sans polygone peint.
  • Utiliser get_coords_for_body_rid() avec la valeur par défaut de physics_quadrant_size et obtenir une coordonnée de quadrant.
  • Appeler des méthodes sur get_cell_tile_data() sans vérification null.
  • Ajouter un nœud TileMap pour un nouveau travail parce que des tutoriels plus anciens le font. Utilisez un TileMapLayer par couche.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

ziva-sh/godot-4-api-pitfalls

Fixes Godot 3 APIs and GDScript syntax that AI assistants write into Godot 4 projects, such as KinematicBody2D, move_and_slide(velocity), export, onready, setget, yield, string connect(), instance(), rand_range, the Tween node, File, change_scene, Spatial, rect_* properties, Pool*Array, OS time functions and the old TileMap API. Use when writing, reviewing or porting GDScript for Godot 4.x, when a script fails with "not declared", "not found in base", "was removed in Godot 4" or "is not present

ziva-sh/godot-control-layout

Builds Godot 4 Control UIs that resize instead of clipping or overlapping - containers versus anchors, anchor presets from code, size flags, custom_minimum_size, MarginContainer margins, Label wrapping, mouse_filter, CanvasLayer HUDs, Godot 4 theme override names (add_theme_color_override and friends) and the display/window/stretch settings for multiple resolutions. Use when creating or fixing menus, HUDs, dialogs and inventory screens, when UI elements are cut off, zero-sized, overlapping, igno

ziva-sh/godot-scene-organization

Structures Godot 4 projects so scenes stay reusable and references do not break - when to make a scene, a script or a Resource, instancing with @export PackedScene, preload and load, @onready and %UniqueName node access, _ready order, groups, autoloads, class_name, and resource UIDs with the .uid files added in Godot 4.4, including how to move or rename files safely. Use when creating new scenes or scripts, deciding how nodes find each other, adding global state or an event bus, moving or renami

ziva-sh/godot-signals

Godot 4 signal patterns and their failure modes - declaring typed signals, emit(), connect() and disconnect() with Callables, bind() and unbind(), lambdas, CONNECT_ONE_SHOT and CONNECT_DEFERRED, await on signals and timers, editor-made connections stored in .tscn files, and the call down, signal up rule. Use when wiring UI buttons, timers, Area2D or body events and custom game events, when replacing Godot 3 connect("signal", self, "method") or yield code, or when debugging "already connected", "

Skills associés