Введение

В Godot 4 система TileMap была полностью переписана. Если вы использовали TileMap в Godot 3, изменилось почти всё — редактор TileSet, способ определения тайлов, автотайлинг, слои и API GDScript. В этом руководстве новая архитектура разбирается с нуля.

Пользователям Godot 3: Старые autotile, set_cellv() и cell_size полностью удалены. См. раздел Миграция с Godot 3 внизу страницы.

Новая архитектура TileMap

Система TileMap в Godot 4 состоит из двух основных компонентов:

  • Нода TileMap — Нода, которую вы добавляете в сцену. Она содержит один или несколько слоёв и ссылается на ресурс TileSet.
  • Ресурс TileSet — Определяет сами тайлы. Содержит источники (атлас, коллекцию сцен и т. д.), физические слои, слои навигации, слои пользовательских данных и наборы ландшафта.

Ключевое изменение: В Godot 3 размер тайла задавался на ноде TileMap. В Godot 4 размер тайла определяется в ресурсе TileSet, а TileMap просто ссылается на него.

Источники TileSet

TileSet может иметь несколько источников, каждый из которых идентифицируется по source_id (целое число). Типы источников включают:

  • TileSetAtlasSource — Самый распространённый тип. Одно изображение-текстура, содержащее несколько тайлов, расположенных сеткой.
  • TileSetScenesCollectionSource — Каждый тайл является упакованной сценой, что удобно для анимированных или интерактивных тайлов.

Настройка TileSet

Шаг 1: Создайте ресурс TileSet

  1. Добавьте в сцену ноду TileMap.
  2. В инспекторе нажмите на свойство Tile Set и выберите New TileSet.
  3. Задайте Tile Size (например, 16x16 или 32x32).

Шаг 2: Добавьте источник-атлас

  1. Нажмите на TileSet, чтобы открыть редактор TileSet на нижней панели.
  2. Нажмите кнопку + и выберите Atlas.
  3. Перетащите изображение тайлсета в свойство Texture.
  4. Редактор автоматически разбивает его на тайлы на основе вашего размера тайла. Вы можете настроить область текстуры и отступы.

Шаг 3: Настройте свойства тайлов

В редакторе TileSet вы можете добавлять различные типы слоёв, которые применяются ко всем тайлам:

  • Physics Layers — Формы коллизий для тайлов
  • Navigation Layers — Проходимые полигоны для поиска пути
  • Custom Data Layers — Произвольные типизированные данные (bool, int, float, String и т. д.)
  • Terrain Sets — Для автотайлинга (замена autotile из Godot 3)

Слои TileMap

Одна нода TileMap может содержать несколько слоёв. Это большое улучшение по сравнению с Godot 3, где для фона и переднего плана нужны были отдельные ноды TileMap. Каждый слой может иметь собственные настройки z-index, y-sort и modulate.

Типичная настройка слоёв:

  • Layer 0 — Фон (земля, пол) — z-index: -1
  • Layer 1 — Ландшафт (стены, препятствия) — z-index: 0
  • Layer 2 — Передний план (декор поверх игрока) — z-index: 1

API GDScript для слоёв

# 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")

Примечание об API: Первый параметр в set_cell() всегда индекс слоя (0, 1, 2...). Второй — позиция ячейки как Vector2i. Третий — source_id, а четвёртый — atlas_coords как Vector2i.

Система ландшафта (автотайлинг)

Система ландшафта заменяет autotile из Godot 3. Она автоматически выбирает правильный вариант тайла на основе соседних тайлов.

Настройка ландшафтов

  1. В TileSet добавьте Terrain Set (Инспектор → Terrain Sets → Add Element).
  2. Выберите режим ландшафта: Match Corners and Sides (47 тайлов), Match Corners (16 тайлов) или Match Sides (16 тайлов).
  3. Добавьте типы ландшафта внутри набора (например, «Grass», «Dirt», «Water»).
  4. В редакторе TileSet переключитесь в режим Select, выберите тайл и закрасьте биты соседства ландшафта на каждом тайле.

Рисование ландшафтов

Когда ландшафты настроены, переключитесь в редактор TileMap и выберите вкладку Terrains. Выберите тип ландшафта и рисуйте прямо на карте. Godot автоматически подберёт правильный вариант тайла.

# Set terrain programmatically
tilemap.set_cells_terrain_connect(0, [Vector2i(5, 3)], 0, 0)
# Parameters: layer, cells array, terrain_set, terrain index

Физика на тайлах

Чтобы добавить коллизии к тайлам:

  1. Добавьте Physics Layer в инспекторе TileSet.
  2. Настройте, какой слой коллизий и маску использует этот физический слой.
  3. В редакторе TileSet переключитесь на вкладку Physics и нарисуйте полигоны коллизий на каждом тайле.

Совет: Вы можете иметь несколько физических слоёв для разных типов тайлов. Например, один слой для стен (блокирует движение) и другой для опасностей (наносит урон через пересечение с Area2D).

Пользовательские данные на тайлах

Слои пользовательских данных позволяют прикреплять типизированные метаданные к любому тайлу. Это чрезвычайно полезно для игровой логики.

Настройка пользовательских данных

  1. В инспекторе TileSet добавьте Custom Data Layer.
  2. Дайте ему имя (например, «is_destructible») и задайте тип (например, bool).
  3. В редакторе TileSet переключитесь на вкладку Custom Data и задайте значения для каждого тайла.

Чтение пользовательских данных в коде

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))

Распространённые примеры пользовательских данных:

  • is_destructible: bool
  • damage: int
  • movement_cost: float
  • tile_type: String (например, "water", "lava", "ice")
  • spawn_chance: float

Процедурное размещение тайлов

Размещать тайлы программно с помощью нового 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()

Преобразование координат мира в координаты карты

# 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)

Миграция с 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 Система ландшафта (Terrain Sets)
Один слой на ноду TileMap Несколько слоёв в одном TileMap
TileMap.tile_set = preload(...) Ресурс TileSet назначается в инспекторе или через код
world_to_map() local_to_map()
map_to_world() map_to_local()

Распространённые ошибки

  1. Забыть сначала создать TileSet. Нода TileMap не покажет редактор тайлов, пока вы не назначите ресурс TileSet. Создайте его в инспекторе.

  2. Неправильный source_id. Если у вас только один источник-атлас, его source_id равен 0. Добавление второго источника даёт ему source_id = 1. Проверьте нижнюю панель редактора TileSet — на каждой вкладке источника показан его ID.

  3. Путаница atlas_coords с ID тайлов. В Godot 4 нет простых ID тайлов. Вместо этого вы ссылаетесь на тайлы по их позиции в сетке атласа как Vector2i(столбец, строка).

  4. Не указан параметр слоя. Каждая операция с ячейкой требует индекс слоя в качестве первого аргумента. Забыв его, вы получите ошибки аргументов.

  5. Использование set_cellv(). Этот метод больше не существует. Используйте set_cell() с новой сигнатурой.