บทนำ
Godot 4 ได้เขียนระบบ TileMap ขึ้นใหม่ทั้งหมด หากคุณเคยใช้ TileMap ใน Godot 3 แทบทุกอย่างจะเปลี่ยนไป — ทั้งตัวแก้ไข TileSet, วิธีการนิยามกระเบื้อง, การปูกระเบื้องอัตโนมัติ, เลเยอร์ และ GDScript API คู่มือนี้จะอธิบายสถาปัตยกรรมใหม่ตั้งแต่เริ่มต้น
สำหรับผู้ใช้ 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
- เพิ่มโหนด TileMap เข้าไปในฉากของคุณ
- ใน Inspector ให้คลิกที่พร็อพเพอร์ตี Tile Set แล้วเลือก New TileSet
- กำหนด Tile Size (เช่น 16x16 หรือ 32x32)
ขั้นตอนที่ 2: เพิ่มแหล่งแอตลาส
- คลิกที่ TileSet เพื่อเปิดตัวแก้ไข TileSet ที่แผงด้านล่าง
- คลิกปุ่ม + แล้วเลือก Atlas
- ลากภาพไทล์เซตของคุณเข้าไปในพร็อพเพอร์ตี Texture
- ตัวแก้ไขจะแบ่งภาพออกเป็นกระเบื้องโดยอัตโนมัติตามขนาดกระเบื้องของคุณ คุณสามารถปรับพื้นที่เท็กซ์เจอร์และระยะขอบได้
ขั้นตอนที่ 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
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() จะเป็นดัชนีเลเยอร์เสมอ (0, 1, 2...) พารามิเตอร์ที่สองคือตำแหน่งเซลล์ในรูปแบบ Vector2i พารามิเตอร์ที่สามคือ source_id และพารามิเตอร์ที่สี่คือ atlas_coords ในรูปแบบ Vector2i
ระบบเทอร์เรน (การปูกระเบื้องอัตโนมัติ)
ระบบเทอร์เรนมาแทนที่ autotile ของ Godot 3 มันจะเลือกกระเบื้องรูปแบบที่ถูกต้องโดยอัตโนมัติตามกระเบื้องข้างเคียง
การตั้งค่าเทอร์เรน
- ใน TileSet ให้เพิ่ม Terrain Set (Inspector → Terrain Sets → Add Element)
- เลือกโหมดเทอร์เรน: Match Corners and Sides (47 กระเบื้อง), Match Corners (16 กระเบื้อง) หรือ Match Sides (16 กระเบื้อง)
- เพิ่มประเภทเทอร์เรนภายในเซต (เช่น "Grass", "Dirt", "Water")
- ในตัวแก้ไข TileSet ให้สลับไปที่โหมด Select เลือกกระเบื้อง แล้วระบายบิตการเชื่อมต่อเทอร์เรน (peering bits) บนกระเบื้องแต่ละอัน
การระบายเทอร์เรน
เมื่อกำหนดค่าเทอร์เรนเรียบร้อยแล้ว ให้สลับไปที่ตัวแก้ไข 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
ฟิสิกส์บนกระเบื้อง
วิธีเพิ่มคอลลิชันให้กับกระเบื้อง:
- เพิ่ม Physics Layer ใน Inspector ของ TileSet
- กำหนดค่าว่าเลเยอร์ฟิสิกส์นี้ใช้คอลลิชันเลเยอร์และมาสก์ใด
- ในตัวแก้ไข TileSet ให้สลับไปที่แท็บ Physics แล้ววาดรูปหลายเหลี่ยมคอลลิชันบนกระเบื้องแต่ละอัน
เคล็ดลับ: คุณสามารถมีเลเยอร์ฟิสิกส์หลายเลเยอร์สำหรับกระเบื้องประเภทต่าง ๆ ได้ เช่น เลเยอร์หนึ่งสำหรับกำแพง (ขัดขวางการเคลื่อนที่) และอีกเลเยอร์สำหรับอันตราย (กระตุ้นความเสียหายผ่านการซ้อนทับของ Area2D)
ข้อมูลกำหนดเองบนกระเบื้อง
เลเยอร์ข้อมูลกำหนดเองช่วยให้คุณแนบข้อมูลเมทาดาทาแบบกำหนดชนิดกับกระเบื้องใด ๆ ก็ได้ ซึ่งมีประโยชน์อย่างยิ่งสำหรับตรรกะของเกมเพลย์
การตั้งค่าข้อมูลกำหนดเอง
- ใน Inspector ของ TileSet ให้เพิ่ม Custom Data Layer
-
ตั้งชื่อ (เช่น "is_destructible") และกำหนดชนิดข้อมูล (เช่น
bool) - ในตัวแก้ไข 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: booldamage: intmovement_cost: floattile_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 ใน Inspector หรือผ่านโค้ด |
world_to_map() |
local_to_map() |
map_to_world() |
map_to_local() |
ข้อผิดพลาดที่พบบ่อย
-
ลืมสร้าง TileSet ก่อน โหนด TileMap จะไม่แสดงตัวแก้ไขกระเบื้องจนกว่าคุณจะกำหนดรีซอร์ส TileSet ให้ สร้างมันขึ้นมาใน Inspector
-
source_id ผิด หากคุณมีแหล่งแอตลาสเพียงแหล่งเดียว
source_idของมันคือ0เมื่อเพิ่มแหล่งที่สอง มันจะได้source_id = 1ตรวจสอบแผงด้านล่างของตัวแก้ไข TileSet — แท็บของแต่ละแหล่งจะแสดง ID ของมัน -
สับสนระหว่าง atlas_coords กับ tile ID ใน Godot 4 ไม่มี tile ID แบบง่ายอีกต่อไป แต่คุณจะอ้างอิงกระเบื้องด้วยตำแหน่งในกริดแอตลาสในรูปแบบ
Vector2i(column, row)แทน -
ไม่ระบุพารามิเตอร์เลเยอร์ ทุกการดำเนินการกับเซลล์ต้องมีดัชนีเลเยอร์เป็นอาร์กิวเมนต์แรก การลืมมันจะทำให้เกิดข้อผิดพลาดของอาร์กิวเมนต์
-
ใช้
set_cellv()เมธอดนี้ไม่มีอยู่แล้ว ให้ใช้set_cell()ด้วยลายเซ็นแบบใหม่