- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
TileData 是 Godot 4 中承载单个瓦片全部配置的核心资源类:从纹理翻转、色调调制、材质与 Z 排序,到碰撞多边形、遮挡多边形、导航多边形、自定义数据与地形(terrain)衔接规则,全部由它管理。本文将基于 TileData 类参考文档,结合 TileSet 类文档、TileMapLayer 类文档 与 使用 TileSet 教程,逐一剖析其全部属性、方法与信号,并给出在运行时用_tile_data_runtime_update()动态改写瓦片的可运行 GDScript 示例。读完本文,你将能系统掌握瓦片级配置的每一项能力,并能在游戏运行时按需修改任意格子上的瓦片数据。
TileData 在 TileSet 体系中的定位
在 Godot 4 的瓦片系统中,资源分为两层:
- TileSet:一个瓦片集合,负责定义图集(atlas)、场景集合、物理/导航/遮挡/自定义数据等"层"的结构与全局参数;
- TileData:集合中每一个瓦片的个体配置,即"设置单个瓦片的一组设定"。
按官方类文档的定义,TileData继承自Object(见 class_tiledata.rst),是 TileSet 中单个瓦片的设置集合。它通常在瓦片集编辑器(TileSet editor)中编辑,但也可以在运行时通过 TileMapLayer._tile_data_runtime_update() 进行修改。
理解这个层次关系非常关键:TileSet 决定"瓦片有哪些可选类型与层",而 TileData 决定"这个瓦片具体长什么样、有哪些碰撞、属于哪个地形、携带什么游戏数据"。创建图集后,每个由编辑器自动生成的瓦片都会附带一个独立的 TileData 实例。
属性总览(11 项)
TileData 共有 11 个属性,覆盖渲染表现、地形归属与排序三类需求:
| 属性 | 类型 | 默认值 | 作用 |
|---|---|---|---|
| flip_h | bool | false | 纹理水平翻转 |
| flip_v | bool | false | 纹理垂直翻转 |
| material | Material | —(空) | 该瓦片使用的材质 |
| modulate | Color | Color(1, 1, 1, 1) | 瓦片颜色调制(相乘) |
| probability | float | 1.0 | 随机绘制时该瓦片被选中的相对概率 |
| terrain | int | -1 | 该瓦片使用的地形 ID |
| terrain_set | int | -1 | 该瓦片使用的地形集 ID |
| texture_origin | Vector2i | Vector2i(0, 0) | 瓦片绘制位置偏移 |
| transpose | bool | false | 交换水平/垂直 UV(转置显示) |
| y_sort_origin | int | 0 | 用于 y-sort 排序的垂直基准点 |
| z_index | int | 0 | 相对于 TileMapLayer 的绘制顺序 |
渲染相关属性:翻转、转置与绘制偏移
flip_h / flip_v分别控制瓦片纹理的水平与垂直翻转。true时纹理沿对应轴镜像。
transpose是三者中最容易混淆的一个:它为true时瓦片"转置"显示,即交换水平和垂直方向的纹理 UV,效果等价于把瓦片旋转 90 度后垂直翻转。因此组合使用这三个开关可以产生各种旋转效果。在 使用 TileSet 教程 中给出了精确的组合结论:
- 顺时针旋转 90°:开启Flip H + Transpose;
- 顺时针旋转 180°:开启Flip H + Flip V;
- 顺时针旋转 270°:开启Flip V + Transpose。
(在 Godot 4.2 及以后,TileMap 编辑器工具栏已提供直接的旋转/翻转按钮,无需再为放置阶段创建替代瓦片。)
texture_origin(默认Vector2i(0, 0))以像素为单位偏移瓦片实际绘制的锚点位置,可用于让瓦片相对格点"浮起"或视觉错位。
材质与颜色调制
material指定该瓦片使用的 Material,可以是:
- CanvasItemMaterial:使用默认着色器,用于调整混合模式等;
- ShaderMaterial:为该瓦片定制自定义着色器。
这让单个瓦片可以拥有与其他瓦片完全不同的渲染方式,适合水面、熔岩、动态装饰等特殊效果。modulate则是一个Color乘数(默认白色Color(1, 1, 1, 1)),直接与纹理颜色相乘,是制作暗色地面、夜晚色调、冻结或高亮瓦片的轻量手段。
排序相关属性:z_index 与 y_sort_origin
z_index是瓦片相对所在 TileMapLayer 节点的绘制顺序索引,数值越大越靠前渲染,用于在同一层内制造前后遮挡关系。
y_sort_origin是瓦片用于 y 轴排序的垂直基准点(像素)。在俯视角(top-down)游戏中,把它调整到瓦片底部可让角色"走到瓦片后面"时被正确遮挡;只有 TileMapLayer 节点在CanvasItem > Ordering下开启Y Sort Enabled时它才生效(此约束同样记录在 使用 TileSet 教程 的替代瓦片属性一节)。
probability:随机绘制权重
probability(默认1.0)表示当使用随机绘制模式(在 TileMap 编辑器中绘制"随机瓦片图案")时,该瓦片被选中的相对概率。数值越大越常被选中;通过为同一格位的多个瓦片变体设置不同概率,可以营造出自然的草丛、碎石分布效果。
地形属性:terrain_set 与 terrain
地形系统是 Godot 3.x "自动瓦片(autotile)" 的进化形态。与旧版不同,地形只是附加在图集瓦片上的若干属性,由瓦片级专用绘制模式"聪明地"挑选合适的瓦片,因此任何地形瓦片既可以当地形绘制,也可以像普通瓦片一样单独放置。
terrain_set是该瓦片所属的地形集 ID,terrain是该瓦片在地形集内使用的地形 ID。两者的默认值都是-1,含义分别是"未分配地形集"与"未分配地形"。在编辑器 Select 模式下展开瓦片属性的Terrains栏即可设置;必须先设置Terrain Set ≥ 0,才能设置Terrain ≥ 0(两者 ID 从0而非1开始计数,且相互独立)。
地形集自身有一个匹配模式 TerrainMode,决定了地形之间如何衔接:
- TERRAIN_MODE_MATCH_CORNERS_AND_SIDES(0):要求四角与四边都与相邻瓦片的地形匹配;
- TERRAIN_MODE_MATCH_CORNERS(1):只要求四角匹配;
- TERRAIN_MODE_MATCH_SIDES(2):只要求四边匹配。
这三个模式分别对应旧版自动瓦片的 2×2、3×3 与 3×3 minimal 位掩码模式,也类似 Tiled 编辑器的功能。
Terrain Peering Bits:地形衔接的核心机制
真正决定"哪个瓦片在哪种邻居环境下出现"的是地形窥视位(Terrain Peering Bits),由以下两个方法读写:
- set_terrain_peering_bit(peering_bit, terrain):为给定方向设置该瓦片的地形窥视位;
- get_terrain_peering_bit(peering_bit):读取指定方向的地形窥视位值。
peering_bit使用 TileSet.CellNeighbor 枚举,它按顺时针顺序定义了以当前格子为中心的 16 个邻接方位:从CELL_NEIGHBOR_RIGHT_SIDE = 0、CELL_NEIGHBOR_RIGHT_CORNER = 1开始,依次覆盖右侧、右下、下方、左下、左侧、左上、上方、右上共 8 个方向,每个方向都有SIDE(边)与CORNER(角)两个位。在调用这两个方法前,应先用 is_valid_terrain_peering_bit() 确认该方向对本瓦片有效。
窥视位取值规则:-1代表"该方向是空位",而0及以上的整数表示该方向必须与指定地形 ID 匹配。例如:
- 一个瓦片所有窥视位都设为
0或更大,则它只在 8 个邻居全部使用同地形 ID 的瓦片时才会出现(用于地形内部填充); - 若上方三个位(左上角、上边、右上角)都设为
-1,则它只在上方(含斜上方)为空时出现——这正是平台边缘、地面顶端的典型配置。
下图展示了在 TileSet 编辑器 Select 模式下为单个瓦片配置地形窥视位的情形,编辑器中间栏的Terrain Peering Bits区域会随瓦片选择动态显示全部 8 个方向的位值:
一个完整的地形瓦片表(包含角块、边块、内部块)即可通过组合窥视位自动衔接,大幅减少手工摆放平台边缘的工作量,对程序化生成的关卡同样有效。
信号:changed
TileData 只定义一个信号:
changed()—— 当该瓦片的任一属性被修改时发出。由于 TileData 属于 Resource 体系,编辑器中修改瓦片属性会自动触发它;在运行时通过 setter 修改属性同样会发出该信号,可用于同步自定义逻辑(如瓦片状态变化后的表现刷新)。
方法全解:瓦片级碰撞、遮挡、导航与自定义数据
TileData 的方法全部围绕"按层索引读写多边形/数据"展开。Godot 4 的 TileSet 允许一个瓦片拥有多个物理层、多个遮挡层、多个导航层,因此绝大多数方法都要求传入layer_id(层索引);而多边形(多边形索引polygon_index)从0开始计数,一个瓦片在每个层上可以持有多个多边形。
1. 碰撞多边形(Physics)
物理层用于为瓦片生成静态碰撞体,玩家和物体落到上面时会被阻挡。相关方法成对出现(先计数/添加,再读写单个多边形):
- add_collision_polygon(layer_id):在指定物理层上添加一个碰撞多边形(随后可用 set 系列方法填充顶点);
- get_collision_polygons_count(layer_id) / set_collision_polygons_count(layer_id, polygons_count):查询/设定该物理层上的多边形数量;
- get_collision_polygon_points(layer_id, polygon_index) / set_collision_polygon_points(layer_id, polygon_index, polygon):以
PackedVector2Array读写多边形顶点; - remove_collision_polygon(layer_id, polygon_index):删除指定多边形;
- 单向平台支持:is_collision_polygon_one_way() / set_collision_polygon_one_way(layer_id, polygon_index, one_way),以及 get_collision_polygon_one_way_margin() / set_collision_polygon_one_way_margin(layer_id, polygon_index, one_way_margin)。开启单向碰撞后,角色可从下方穿过、从上方站立,
one_way_margin控制单向判定生效的边缘距离。
物理层的碰撞行为还受 TileSet 全局参数影响:每个物理层在 TileSet 上定义了碰撞层与掩码(见 TileSet.get_physics_layer_collision_layer() 与 get_physics_layer_collision_mask()),瓦片生成的碰撞体按这些层/掩码参与物理世界交互。在编辑器中,创建物理层后进入 TileSet 面板的Physics Layer区域即可用 2D 多边形编辑工具绘制碰撞形状(快捷键 :kbd:F快速生成矩形);对于大量同类碰撞瓦片,教程推荐使用 多选批量赋值 或属性绘制模式一次铺开。
2. 恒定速度(传送带等动态地形)
两个"速度"方法特别适合制作传送带、风道等动态地形——注意它们不会移动或旋转瓦片本身,而是把速度施加给与瓦片碰撞的物体:
- set_constant_linear_velocity(layer_id, velocity):设置恒定线速度(
Vector2),官方文档明确点出其典型用途就是传送带(conveyor belts);读取用 get_constant_linear_velocity(); - set_constant_angular_velocity(layer_id, velocity):设置恒定角速度(
float,弧度/秒);读取用 get_constant_angular_velocity()。
两者均按物理层layer_id独立配置,同一瓦片在不同层上可有不同的速度行为。
3. 遮挡多边形(Light Occluder)
遮挡层用于 2D 光照系统:为瓦片定义遮挡多边形后,DirectionalLight2D、PointLight2D 等光源的光线会被瓦片挡住,形成阴影;GPUParticles2D 粒子也可以与遮挡体碰撞。相关方法:
- add_occluder_polygon(layer_id) 与 get_occluder_polygons_count(layer_id) / set_occluder_polygons_count(layer_id, polygons_count):管理遮挡层上的多边形数量;
- set_occluder_polygon(layer_id, polygon_index, polygon) / get_occluder_polygon(layer_id, polygon_index, flip_h, flip_v, transpose):读写指定索引的遮挡多边形;
- remove_occluder_polygon(layer_id, polygon_index):删除多边形。
注意两个已弃用方法:
set_occluder()/get_occluder()被标记为Deprecated,官方建议改用上述*_occluder_polygon()系列(见 class_tiledata.rst)。在编辑器里,瓦片的遮挡多边形位于图集检视器的Rendering子栏目下,展开后才能编辑。
翻转参数(flip_h / flip_v / transpose):多个 getter(如get_occluder_polygon、get_navigation_polygon)都接受这三个布尔参数,允许在不改变瓦片原始多边形数据的前提下,返回经过翻转/转置变换后的多边形——非常适合在运行时复用同一份几何数据生成镜像瓦片。
4. 导航多边形(Navigation)
为瓦片配置导航多边形后,TileMap 可以生成导航网格,供 NavigationAgent2D 等角色寻路。相关方法:
- set_navigation_polygon(layer_id, navigation_polygon):为指定导航层设置 NavigationPolygon;
- get_navigation_polygon(layer_id, flip_h, flip_v, transpose):返回指定导航层的导航多边形,同样支持三个变换参数。
在 使用 TileSet 教程 中,创建导航层与绘制碰撞多边形的流程一致(同为 2D 多边形编辑),只是多边形将用于导航网格生成,而非物理碰撞。
5. 自定义数据层(Custom Data)
自定义数据层用于在每个瓦片上存储游戏专属数据,例如"该瓦片每秒造成的伤害"、"是否可被武器破坏"、"属于哪片区域"等。它与 TileSet 中的自定义数据层定义配合使用:
- set_custom_data(layer_name, value) / get_custom_data(layer_name):按层名读写(值类型为
Variant,任意类型均可); - set_custom_data_by_layer_id(layer_id, value) / get_custom_data_by_layer_id(layer_id):按层索引读写;
- has_custom_data(layer_name):先判断名为
layer_name的层是否存在,再读取,避免运行时访问不存在的层。
在 TileSet 检视器中创建自定义数据层后,即可在 Select 模式下为每个瓦片填写数值。下图是教程中配置的两个自定义数据层示例(damage_per_second与destructible),它们会被存储进每个瓦片各自的 TileData 中:
自定义数据还有两点实用特性:
- 数据与瓦片绑定:数据存于 TileSet 中的瓦片定义上,所有已放置的该瓦片实例共享同一份数据;若需要"同图不同数据"的变体,应创建替代瓦片(Alternative Tile)并只修改替代瓦片的数据;
- 重排安全:自定义数据层在 TileSet 中可任意重排,编辑器会自动更新既有元数据,不会破坏旧数据对应关系。
此外,TileSet 编辑器的属性绘制模式也支持自定义数据批量赋值,方便为大片瓦片区域快速填充数值。
运行时修改 TileData:_tile_data_runtime_update 实战
TileData 通常在编辑器中配置,但官方文档明确支持运行时改写。核心入口是 TileMapLayer 的两个虚方法:
- _use_tile_data_runtime_update(coords):返回
true表示坐标为coords的格子需要运行时更新。务必只对确有需要的格子返回true,否则每个格子都会在运行时被处理,造成显著性能损失; - _tile_data_runtime_update(coords, tile_data):当
_use_tile_data_runtime_update对某格子返回true时被调用,传入即将被 TileMapLayer 内部使用的 TileData 对象,允许就地修改。
官方文档的两条重要警告
- 子资源共享:传入的
tile_data的子资源与 TileSet 中是同一份。直接修改它们可能影响整个 TileSet——例如对get_navigation_polygon()返回的多边形做修改,会波及所有使用该瓦片的格子。需要独立副本时,务必先duplicate()这些子资源; - 动态更新通知:如果 TileData 的属性会随时间变化,需要调用 notify_runtime_tile_data_update() 通知 TileMapLayer 重新更新;但该调用会触发整层重算,开销较大,应尽量限制调用频率。
可运行示例:给特定格子设置自定义数据与翻转
下面是一个完整的 GDScript 示例,展示如何在运行时为"进门后"的格子写入自定义数据、翻转瓦片,并读取已存数据:
extends TileMapLayer # 只有被标记的格子才需要运行时更新 func _use_tile_data_runtime_update(coords: Vector2i) -> bool: return coords == Vector2i(3, 2) or coords == Vector2i(4, 2) func _tile_data_runtime_update(coords: Vector2i, tile_data: TileData) -> void: # 1) 翻转与色调:不会影响 TileSet 中的原瓦片定义 tile_data.flip_h = true tile_data.modulate = Color(0.6, 0.9, 1.0) # 淡蓝 # 2) 自定义数据:前提是 TileSet 中已定义名为 "destructible" 的层 if tile_data.has_custom_data("destructible"): tile_data.set_custom_data("destructible", false) # 按索引读写同样可行: # tile_data.set_custom_data_by_layer_id(0, false) print("destructible = ", tile_data.get_custom_data("destructible")) # 3) 恒定线速度:做成"传送带"效果(需该瓦片已配置物理层) # tile_data.set_constant_linear_velocity(0, Vector2(120, 0)) # 4) 为瓦片动态追加一个三角形碰撞多边形(物理层 0) # var idx := tile_data.get_collision_polygons_count(0) # tile_data.add_collision_polygon(0) # tile_data.set_collision_polygon_points(0, idx, PackedVector2Array([ # Vector2(0, 0), Vector2(32, 0), Vector2(0, 32) # ])) # 当上面的修改结果会随时间变化时,主动请求一次整层更新 func _on_something_changed() -> void: notify_runtime_tile_data_update()要点回顾:
- 判断层存在性:读写自定义数据前先用
has_custom_data(layer_name)检查; - 修改多边形:
add_collision_polygon(layer_id)会新增一个空多边形并返回其索引位置,随后用set_collision_polygon_points()填充顶点(坐标为相对瓦片左上角的局部坐标); - 勿直接改共享子资源:对导航/遮挡多边形的运行时变换,优先使用 getter 自带的
flip_h/flip_v/transpose参数返回临时副本,而不是原地修改 TileSet 中的共享数据。
替代瓦片与 TileData 的关系
要创建同一图集图片的"不同配置变体"(如旋转、翻转、不同色调、不同自定义数据),官方推荐使用替代瓦片(Alternative Tile)。替代瓦片在 TileSet 编辑器中位于图集基础瓦片右侧,创建后可以像基础瓦片一样修改 TileData 的任意属性,但有一个关键区别:
创建替代瓦片时,基础瓦片的任何属性都不会被继承——若希望两者表现一致,需要在替代瓦片上重新设置(此约束记录于 使用 TileSet 教程 的替代瓦片一节)。
这意味着每个替代瓦片拥有自己独立、完整的 TileData 实例,非常适合"同一图片、多种行为"的场景(例如同一个箱子贴图,替代瓦片 A 带碰撞、替代瓦片 B 是可破坏的装饰)。
小结:TileData 的能力全景
| 能力域 | 关键属性 / 方法 | 典型用途 |
|---|---|---|
| 渲染表现 | flip_h、flip_v、transpose、modulate、material、texture_origin | 镜像、旋转、变色、自定义着色器、绘制偏移 |
| 排序 | z_index、y_sort_origin | 前后遮挡、俯视角高度排序 |
| 随机绘制 | probability | 自然分布的草丛、碎石 |
| 地形衔接 | terrain、terrain_set、get/set_terrain_peering_bit、is_valid_terrain_peering_bit | 自动衔接平台边缘、程序化关卡 |
| 物理 | 碰撞多边形系列 + 单向平台 + 恒定速度系列 | 静态碰撞、单向跳台、传送带 |
| 光照 | 遮挡多边形系列 | 2D 阴影、粒子碰撞 |
| 寻路 | 导航多边形系列 | 生成导航网格供角色寻路 |
| 游戏数据 | 自定义数据系列 +has_custom_data | 伤害值、可破坏性等瓦片级元数据 |
| 变更通知 | changed信号 | 属性修改后的逻辑同步 |
| 运行时改写 | TileMapLayer 的_use/_tile_data_runtime_update+notify_runtime_tile_data_update | 动态地形、状态切换、传送带 |
理解 TileData 就等于理解了 Godot 4 瓦片系统的"最后一公里":TileSet 负责搭建层与结构,TileData 负责在每个瓦片上落地碰撞、光照、导航、地形与游戏数据。需要进一步了解其所在的完整体系,可继续阅读 TileSet 类参考、TileMapLayer 类参考,以及 使用 TileSet 教程 与 使用 TileMap 教程。
- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
相关推荐
Godot GridMap 完整指南:3D 瓦片地图的 MeshLibrary、碰撞、导航与运行时脚本控制
Godot GridMap 完整指南:3D 瓦片地图的 MeshLibrary、碰撞、导航与运行时脚本控制 GridMap 是 Godot 中构建 3D 关卡的
文档教程游戏开发Godot 3D CPU 粒子系统完全指南:CPUParticles3D 属性、发射形状与运行时控制全解析
Godot 3D CPU 粒子系统完全指南:CPUParticles3D 属性、发射形状与运行时控制全解析 导读 :本文以 Godot Engine 官方文档仓
文档教程游戏开发Godot 2D 碰撞形状节点 CollisionShape2D 完全指南:属性详解、单向碰撞与性能调优
Godot 2D 碰撞形状节点 CollisionShape2D 完全指南:属性详解、单向碰撞与性能调优 本文围绕 Godot 官方文档仓库中的 Collisi
文档教程游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考