Godot中TileSetAtlasSource的create_tile函数仅生效一次后报错
使用Godot Engine v4.0.2.stable.official.7a0977ce2版本,通过代码加载TileSet图集纹理后定义tiles时遇到异常:create_tile函数仅能成功创建1个瓦片,后续调用抛出错误:
"Cannot create tile. The tile is outside the texture or tiles are already present in the space the tile would cover"
已确认纹理加载正常(放入TextureRect显示无问题),图集尺寸256x256,瓦片大小16x16,遍历图集坐标调用create_tile的代码如下:
func _setup_tile_atlas(atlas: TileSetAtlasSource, tile_size: Vector2i) -> void: atlas.texture_region_size = tile_size # Vector2(16, 16) atlas.use_texture_padding = true var atlas_size = atlas.get_atlas_grid_size() # Vector2(16, 16) for y in atlas_size.y: for x in atlas_size.x: var coord = Vector2i(x * tile_size.x, y * tile_size.y) atlas.create_tile(coord, tile_size) #ERRORS print(atlas.has_tile(coord)) print(atlas.get_tile_size_in_atlas(coord)) print(atlas.get_tile_texture_region(coord))
调试发现仅Vector2i(0, 0)位置存在瓦片,且该瓦片的纹理区域为[P: (0, 0), S: (256, 256)](即整个图集大小),疑惑明明显式传入tile_size参数为何出现此情况。
问题出在create_tile的参数使用逻辑上,修正要点如下:
传入网格坐标而非像素坐标
TileSetAtlasSource.create_tile的第一个参数需要的是网格索引坐标(比如(0,0)、(1,0)这种对应图集上的瓦片位置),不是像素偏移值。你之前传入的x * tile_size.x是像素位置,属于参数类型错误。无需重复传入tile_size参数
已经通过atlas.texture_region_size = tile_size定义了瓦片的像素尺寸,调用create_tile时只需传入网格坐标即可。重复传入tile_size会导致Godot误解,将第一个瓦片错误设置为整个图集大小,占用所有空间后后续瓦片无法创建。
修正后的代码:
func _setup_tile_atlas(atlas: TileSetAtlasSource, tile_size: Vector2i) -> void: atlas.texture_region_size = tile_size # 设置单块瓦片的像素大小 atlas.use_texture_padding = true var atlas_grid_size = atlas.get_atlas_grid_size() # 获取图集可划分的瓦片行列数(16,16) for y in range(atlas_grid_size.y): for x in range(atlas_grid_size.x): var grid_coord = Vector2i(x, y) # 使用网格索引坐标 atlas.create_tile(grid_coord) # 无需额外传入tile_size print(atlas.has_tile(grid_coord)) print(atlas.get_tile_size_in_atlas(grid_coord)) print(atlas.get_tile_texture_region(grid_coord))
额外注意:get_atlas_grid_size()返回的是行列数,遍历的时候要用range()包裹,确保循环次数正确(比如range(16)会生成0到15的索引,对应16个瓦片)。
内容的提问来源于stack exchange,提问作者DotFX

