概要
2Dゲームの背景を作る上で欠かせないタイルマップ。しかし、草地と土の境界、崖の角など、タイルのつなぎ目を一つ一つ手作業で配置していくのは非常に骨の折れる作業です。Godot 4では、この問題を解決する「Terrains」機能(旧Godot 3のAutotileに相当)が搭載されており、タイルを自動で適切に配置してくれます。
Terrains機能の核心:Peering Bitsを理解する
Terrains機能の心臓部は、Peering Bitsと呼ばれる接続ルールの定義です。これは、各タイルが「どのような隣接タイルを持つべきか」をエンジンに教えるための情報です。
ステップ1: Terrain SetとTerrainの作成
まず、地形の種類を定義します。ここでは例として「草(Grass)」と「土(Dirt)」の2つの地形で進めます。
TileMapノードを選択し、インスペクタからTileSetプロパティをクリックして、画面下のTileSetエディタを開きます。TileSetエディタの左パネルから「+」ボタンを押し、「Terrains」を選択して新しいTerrain Setを作成します。- 作成した
Terrain SetのModeを、タイルセットの構造に合わせて設定します。Match Corners and Sidesは角と辺の両方を考慮する最も柔軟なモードで、複雑な地形の境界に適しています。Match Sidesは辺のみを考慮するシンプルなモードで、角の接続パターンが不要なタイルセットに向いています。 Terrain Setを展開し、Terrainsプロパティで「配列のサイズを追加」を2回クリックし、2つのTerrainスロットを作成します。- それぞれの
Nameを「Grass」「Dirt」とし、識別のために分かりやすいColorを設定します。
ステップ2: 各タイルにTerrain情報を設定 (Peering Bits)
ここが最も重要な作業です。タイルセット内の各タイルに対して、「どの部分がどの地形で、どのように隣接するか」を教えていきます。
TileSetエディタ上部で「選択」モードになっていることを確認します。- タイルセット画像から、設定したいタイル(例: 草の中心タイル)を選択します。
- 右側のインスペクタで
Properties>Terrains>Terrain Setを先ほど作成した0に設定します。 Terrainプロパティで、このタイルが属する地形(例: Grass)を選択します。Paintブラシ(筆アイコン)に切り替え、Terrain Peeringプロパティを使って接続ルールを塗っていきます。
Peering Bitsは3x3のグリッドで表現されます。
- 中心のマス: このタイル自身の地形を表します。
- 周りの8マス: 隣接する8方向のタイルの地形を表します。
ステップ3: Terrainブラシでマップを描画する
すべての設定が完了したら、マップを描画します。
- メインシーンの
TileMapノードを選択します。 - エディタ上部のツールバーから
Terrainsタブを選択します。 - パレットに、先ほど設定した「Grass」や「Dirt」が表示されているはずです。
- 描きたい地形を選択し、マップ上をドラッグしてみてください。Godotが自動的にPeering Bitsのルールに従って正しい境界タイルを配置してくれます。
よくある間違いとベストプラクティス
| よくある間違い | ベストプラクティス |
|---|---|
| Peering Bitsの不完全な設定 | すべての境界パターンを網羅する。特に「地形 vs 何もない空間」の境界を忘れずに設定することが重要です。 |
| 巨大な単一タイルセット画像 | 機能ごとにタイルセットを分割する。「地面」「装飾」「衝突判定用」など、役割で分けると管理が楽になります。 |
| すべてのタイルをオートタイルにしようとする | オートタイルと手動配置を組み合わせる。基本的な地形はTerrainsで描き、特殊なタイルは手動で配置するのが効率的です。 |
パフォーマンス最適化
Terrains機能で広大なマップを作りたくなりますが、数万タイルを描画するとパフォーマンスが問題になることがあります。
- レイヤーの活用:
TileMapは複数のレイヤーを持つことができます。地面、建物、装飾品など、更新頻度や役割に応じてレイヤーを分割しましょう。 - 視界外描画の無効化:
TileMapノードにVisibilityEnabler2Dノードを子として追加することで、画面外に出たときに処理を停止させることができます。 - チャンク(Chunking): オープンワールドのような非常に広大なマップでは、プレイヤーの周辺領域だけを動的に読み込み・アンロードする手法が有効です。
GDScriptとの連携
Terrains機能はGDScriptと組み合わせることで、プロシージャルなダンジョン生成なども実現可能です。
@onready var tile_map: TileMap = $TileMap
func _ready():
# レイヤー0、座標(10, 5)のタイル情報を取得
var cell_coords = Vector2i(10, 5)
var source_id = tile_map.get_cell_source_id(0, cell_coords)
var atlas_coords = tile_map.get_cell_atlas_coords(0, cell_coords)
print("タイル情報: Source=%s, Atlas=%s" % [source_id, atlas_coords])
# レイヤー0、座標(10, 5)に新しいタイルを配置する
tile_map.set_cell(0, cell_coords, 1, Vector2i(2, 3), 0)
# Terrainを使ってタイルを配置することも可能
func place_tile_with_terrain(layer: int, coords: Vector2i, terrain_set: int, terrain_id: int):
# この関数は、周囲のタイルを考慮して自動で正しいタイルを選択して配置します
tile_map.set_cells_terrain_connect(layer, [coords], terrain_set, terrain_id)
set_cells_terrain_connect() を使えば、GDScriptからでもTerrainsの自動接続機能を呼び出すことができます。
まとめ
Terrains機能の設定は、最初は少し手間がかかります。しかし、一度設定してしまえば、その後のレベルデザインの効率は劇的に向上します。
- Peering Bitsの理解がTerrainsマスターへの鍵
- GDScriptの
set_cells_terrain_connect()でプロシージャル生成も可能 - 大規模マップではレイヤー分割やチャンクシステムでパフォーマンス最適化
まずは簡単な2種類の地形でTerrains機能を試し、その便利さを体感してみてください。