はじめに

Godot 4ではTileMapシステムが完全に書き直されました。Godot 3でTileMapを使っていた場合、ほぼすべてが変更されています — TileSetエディタ、タイルの定義方法、オートタイリング、レイヤー、GDScript APIなど。このガイドでは新しいアーキテクチャをゼロから解説します。

Godot 3ユーザーへ: 旧来のautotileset_cellv()cell_sizeはすべて廃止されました。ページ下部のGodot 3からの移行セクションを参照してください。

新しいTileMapアーキテクチャ

Godot 4のTileMapシステムは2つの主要コンポーネントで構成されています:

  • TileMapノード — シーンに追加するノード。1つ以上のレイヤーを持ち、TileSetリソースを参照します。
  • TileSetリソース — タイル自体を定義します。ソース(アトラス、シーンコレクションなど)、物理レイヤー、ナビゲーションレイヤー、カスタムデータレイヤー、テレインセットを含みます。

重要な変更: Godot 3ではタイルサイズはTileMapノードで設定していました。Godot 4ではタイルサイズはTileSetリソースで定義され、TileMapはそれを参照するだけです。

TileSetソース

TileSetは複数のソースを持つことができ、各ソースはsource_id(整数)で識別されます。ソースの種類:

  • TileSetAtlasSource — 最も一般的なタイプ。グリッド状に配置された複数のタイルを含む1枚のテクスチャ画像です。
  • 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 — オートタイリング用(Godot 3のautotileの後継)

TileMapレイヤー

1つのTileMapノードで複数のレイヤーを持てるようになりました。Godot 3では背景と前景に別々のTileMapノードが必要でしたが、これは大きな改善です。各レイヤーは独自のz-index、y-sort、モジュレート設定を持てます。

一般的なレイヤー構成:

  • Layer 0 — 背景(地面、床) — z-index: -1
  • Layer 1 — 地形(壁、障害物) — z-index: 0
  • Layer 2 — 前景(プレイヤーの上に表示される装飾) — z-index: 1

レイヤーのGDScript API

# 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()の第1引数は常にレイヤーインデックス(0, 1, 2...)です。第2引数はVector2iでのセル位置。第3引数はsource_id、第4引数はVector2iでのatlas_coordsです。

テレインシステム(オートタイリング)

テレインシステムはGodot 3のautotileを置き換えるものです。隣接するタイルに基づいて正しいタイルバリアントを自動選択します。

テレインのセットアップ

  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. TileSetインスペクターでPhysics Layerを追加。
  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 (e.g., "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ノードごとに1レイヤー 1つのTileMapに複数レイヤー
TileMap.tile_set = preload(...) TileSetリソースをインスペクターまたはコードで割り当て
world_to_map() local_to_map()
map_to_world() map_to_local()

よくある間違い

  1. TileSetの作成を忘れる。 TileSetリソースを割り当てるまでTileMapノードはタイルエディタを表示しません。インスペクターで作成してください。

  2. source_idの間違い。 アトラスソースが1つだけの場合、source_id0です。2つ目のソースを追加するとsource_id = 1になります。TileSetエディタの下部パネルで各ソースタブのIDを確認してください。

  3. atlas_coordsとタイルIDの混同。 Godot 4にはシンプルなタイルIDはありません。代わりに、アトラスグリッド内の位置をVector2i(列, 行)で参照します。

  4. レイヤーパラメータの指定忘れ。 すべてのセル操作は第1引数にレイヤーインデックスが必要です。忘れると引数エラーが発生します。

  5. set_cellv()を使う。 このメソッドはもう存在しません。新しいシグネチャのset_cell()を使用してください。