TileMapLayer
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — TileMapLayer
TileMapLayer
节点继承关系
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
单层瓦片地图——每个图层就是一个独立节点,一张纸画一层内容。
生活比喻:TileMap 就像一本透明描图纸册——所有图层叠在同一本册子里管理。而 TileMapLayer 就像把每张描图纸单独拿出来,变成一张一张独立的纸。你可以单独移动某张纸、单独隐藏某张纸、甚至给某张纸单独加脚本逻辑,比"全塞在一个节点里"灵活得多。
TileMapLayer 是 Godot 4.3 引入的新节点,用来替代 TileMap 中内置的多层系统。它的核心理念是:一个节点就是一层瓦片。
节点用途
提供独立的单层瓦片地图,可以自由组合多个 TileMapLayer 节点来实现多层效果。
和 TileMap 的对比:
| 特性 | TileMap | TileMapLayer |
|---|---|---|
| 图层管理 | 一个节点内包含多个图层 | 每个图层是独立的节点 |
| 场景树可见性 | 图层不在场景树中 | 每个图层在场景树中可见 |
| 独立脚本 | 难以给单个图层加脚本 | 每个图层可以有自己的脚本 |
| Y 排序 | 所有图层共享 | 每个图层可以独立设置 Y 排序 |
| 推荐程度 | 旧方案,仍可用 | Godot 4.3+ 官方推荐 |
使用场景
- Godot 4.3 及以上版本的 2D 游戏关卡
- 需要给不同图层加不同行为逻辑时(比如地面层不动,水面层有动画脚本)
- 需要独立控制图层的显示/隐藏、碰撞开关时
- 多个图层需要不同的 Y 排序原点时
常用节点搭配
| 节点 | 用途 | 是否必需 |
|---|---|---|
| TileSet | 瓦片集合资源 | 是 |
| TileMapLayer | 另一个 TileMapLayer 节点(组成多层) | 可选 |
| TileMapLayerCollection | 批量管理多个 TileMapLayer | 可选 |
生效必备素材/资源
| 资源 | 类型 | 说明 |
|---|---|---|
| TileSet | TileSet | 瓦片集合——定义每块瓦片的图片、碰撞、自定义属性等 |
| 瓦片图集图片 | Texture2D | 包含所有瓦片图案的大图,引擎自动切割 |
注意
和 TileMap 一样,TileMapLayer 也必须关联一个 TileSet 资源才能工作。多个 TileMapLayer 可以共享同一个 TileSet,也可以各自使用不同的 TileSet。
节点属性与信号
瓦片属性
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
| tile_set | TileSet | null | — | 使用的瓦片集合资源(核心属性,必须设置) |
| tile_map_data | TileMapData | — | — | 存储所有瓦片放置数据的内部资源 |
| rendering_quadrant_size | int | 16 | — | 渲染分块大小,值越大渲染批次越少但精度越低 |
| y_sort_origin | int | 0 | — | Y 排序原点偏移,用于 2D 深度排序 |
| collision_enabled | bool | true | — | 是否启用碰撞(可以单独关闭某一层的碰撞) |
| collision_visibility_mode | int | 0 | — | 编辑器中碰撞形状的显示模式 |
| navigation_enabled | bool | true | — | 是否启用导航(可以单独关闭某一层的导航) |
| navigation_visibility_mode | int | 0 | — | 编辑器中导航区域的显示模式 |
| x_draw_order | int | 0 | — | 瓦片的绘制顺序(默认从左上到右下) |
| z_index | int | 0 | Node2D | 渲染层级,数值越大越靠前 |
变换属性
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
| position | Vector2 | (0,0) | Node2D | 相对父节点位置 |
| rotation | float | 0.0 | Node2D | 旋转角度(弧度) |
| scale | Vector2 | (1,1) | Node2D | 缩放 |
常用信号
| 信号 | 参数 | 说明 |
|---|---|---|
| changed | — | 瓦片内容发生变化时触发 |
常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
| SetCell(coords, sourceId, atlasCoords) | void | 在指定坐标放置瓦片(不需要指定图层,因为自身就是一层) |
| GetCellTileData(coords) | TileData | 获取指定坐标的瓦片数据 |
| EraseCell(coords) | void | 擦除指定坐标的瓦片 |
| GetUsedCells() | Array | 获取所有已放置瓦片的格子坐标 |
| GetUsedCellsById(sourceId) | Array | 获取使用了某个瓦片源的所有坐标 |
和 TileMap 方法的区别
注意 TileMapLayer 的方法不需要 layer 参数,因为一个 TileMapLayer 节点本身就代表一层。比如 TileMap 要写 SetCell(0, coords, ...),TileMapLayer 只需写 SetCell(coords, ...)。
代码示例
C#
using Godot;
public partial class GroundLayer : TileMapLayer
{
public override void _Ready()
{
// 在坐标 (3, 5) 放置草地瓦片
SetCell(new Vector2I(3, 5), 0, new Vector2I(1, 0));
// 读取瓦片数据
TileData data = GetCellTileData(new Vector2I(3, 5));
if (data != null)
{
Variant isWalkable = data.GetCustomData("walkable");
GD.Print($"位置(3,5)是否可行走: {isWalkable}");
}
// 动态擦除一块瓦片(比如被炸弹炸毁)
EraseCell(new Vector2I(3, 5));
}
}GDScript
extends TileMapLayer
func _ready():
# 在坐标 (3, 5) 放置草地瓦片
set_cell(Vector2i(3, 5), 0, Vector2i(1, 0))
# 读取瓦片数据
var data = get_cell_tile_data(Vector2i(3, 5))
if data:
var is_walkable = data.get_custom_data("walkable")
print("位置(3,5)是否可行走: ", is_walkable)
# 动态擦除一块瓦片(比如被炸弹炸毁)
erase_cell(Vector2i(3, 5))多层组合示例
下面演示如何用多个 TileMapLayer 节点组合出多层地图效果:
C#
using Godot;
public partial class LevelManager : Node2D
{
private TileMapLayer _groundLayer;
private TileMapLayer _decorLayer;
private TileMapLayer _collisionLayer;
public override void _Ready()
{
// 通过节点路径获取各个图层
_groundLayer = GetNode<TileMapLayer>("GroundLayer");
_decorLayer = GetNode<TileMapLayer>("DecorLayer");
_collisionLayer = GetNode<TileMapLayer>("CollisionLayer");
// 装饰层放在地面层前面渲染
_decorLayer.ZIndex = 1;
// 运行时关闭碰撞层的碰撞(比如进入剧情模式)
_collisionLayer.CollisionEnabled = false;
}
}GDScript
extends Node2D
@onready var ground_layer: TileMapLayer = $GroundLayer
@onready var decor_layer: TileMapLayer = $DecorLayer
@onready var collision_layer: TileMapLayer = $CollisionLayer
func _ready():
# 装饰层放在地面层前面渲染
decor_layer.z_index = 1
# 运行时关闭碰撞层的碰撞(比如进入剧情模式)
collision_layer.collision_enabled = false新手建议
如果你刚开始学 Godot,用 TileMap 还是 TileMapLayer 都可以。但如果你的 Godot 版本是 4.3 或更高,建议直接用 TileMapLayer,因为它是未来的方向,而且每个图层独立成节点后管理起来确实更方便。
