Godot中如何通过坐标查找或引用已实例化的3D对象?
Godot 程序化地图空白区域填充解决方案
核心思路:主动记录已占用坐标
因为所有房间/隧道平面都是你通过instantiate()生成的,最高效的方式是在生成时直接记录它们的放置坐标,而不是事后去场景中查找。这样后续判断空白区域时只需查询记录的集合,速度快且逻辑简单。
具体实现步骤
1. 初始化已占用坐标集合
在脚本开头定义一个HashSet(适合存储唯一坐标)来记录所有被平面占用的网格坐标:
var occupied_coords: HashSet[Vector3i] = HashSet.new()
2. 生成平面时记录坐标
每次生成房间/隧道平面时,将其放置的网格坐标添加到集合中:
func generate_map(): var plane_scene = preload("res://assets/plane.tscn") # 示例:生成一个平面并记录坐标 var plane_coord = Vector3i(2, 0, 0) # 你的2x2步长网格坐标 var new_plane = plane_scene.instantiate() new_plane.global_position = plane_coord add_child(new_plane) occupied_coords.add(plane_coord)
如果已经生成完所有平面,可通过遍历场景节点补录坐标:
func collect_existing_plane_coords(map_parent: Node3D): for plane in map_parent.get_children(): # 若平面锚点是中心,需转换为网格坐标(根据你的平面设置调整) var grid_coord = Vector3i( round(plane.global_position.x / 2) * 2, 0, round(plane.global_position.z / 2) * 2 ) occupied_coords.add(grid_coord)
3. 修正填充空白的代码
修复你原代码中的拼写错误,并用坐标集合判断空白区域:
func fill_empty_spaces(): var cube = preload("res://assets/cube.tscn") var coord = Vector3i(0, 0, 0) for x in range(32): coord.x = x * 2 # 直接计算网格X坐标,避免累加出错 for z_idx in range(32): coord.z = z_idx * -2 # 直接计算网格Z坐标,逻辑更清晰 # 跳过已占用的坐标 if coord in occupied_coords: continue # 生成并放置立方体 var new_cube = cube.instantiate() add_child(new_cube) new_cube.global_position = coord # 直接设置位置,替代global_translate
关键注意点
- 确保平面和立方体的坐标严格对齐:如果你的平面锚点是中心而非网格原点,需要将平面位置转换为对应的网格坐标(比如
round(pos/2)*2),避免出现判断误差。 - 使用
HashSet而非数组存储坐标:数组查询的时间复杂度是O(n),HashSet是O(1),在32x32的网格下差异不大,但更大地图时效率差距明显。
内容的提问来源于stack exchange,提问作者romaji9
相关产品推荐
相关产品推荐

