Godot 3.51等距自动图块游戏:如何修改NavigationMesh限制寻路范围
Godot 3.5.1 程序化地图寻路边界限制与验证方案
一、解决寻路超出可玩区域的可行方案
方案1:直接裁剪NavigationMesh到可玩区域
针对自动图块生成的导航网格,无需单独获取每个Tile的导航多边形实例,直接操作Tilemap关联的NavigationRegion2D即可:
- 定义可玩区域范围(比如用
Rect2表示相机限制的区域),将其转换为PolygonShape2D用于裁剪。 - 获取Tilemap子节点的
NavigationRegion2D(若没有则手动添加,确保Tilemap生成的导航网格关联到该节点)。 - 提取导航网格的所有多边形,用
Geometry2D.clip_polygons()裁剪到可玩区域内,再更新导航网格。
示例代码:
# 假设camera_limit_rect是已定义的可玩区域矩形 var play_area_shape = PolygonShape2D.new() play_area_shape.set_rect(camera_limit_rect) var nav_region = $Tilemap/NavigationRegion2D var nav_mesh = nav_region.navigation_mesh.duplicate() # 复制原网格避免直接修改源数据 var clipped_polygons = [] for poly in nav_mesh.polygons: # 裁剪单个多边形,将结果加入列表 var clipped = Geometry2D.clip_polygons(poly, play_area_shape.polygon) clipped_polygons.append_array(clipped) # 更新导航网格并应用 nav_mesh.polygons = clipped_polygons nav_region.navigation_mesh = nav_mesh
方案2:用导航层区分可玩/不可玩区域
这是更轻量化的方案,适合程序化生成时直接配置:
- 在Tilemap的自动图块编辑器中,给可玩区域的Tile设置导航层1,给边界外的不可玩Tile设置导航层2。
- 控制玩家移动的
NavigationAgent2D,仅勾选导航层1(通过navigation_layers属性设置)。 - 寻路系统会自动忽略导航层2的区域,路径不会超出可玩范围。
二、地图可行性验证方法
遍历所有随机生成的兴趣点,验证起点到每个点的路径终点是否与兴趣点匹配:
- 使用
NavigationAgent2D的get_simple_path()方法获取起点到兴趣点的路径。 - 若路径为空,或路径最后一个点与兴趣点的距离超过阈值(如1.0,根据Tile大小调整),判定地图无效。
- 所有兴趣点验证通过则保留地图,否则重新生成。
示例代码:
func is_map_valid(start_pos: Vector2, interest_points: Array[Vector2]) -> bool: var nav_agent = NavigationAgent2D.new() nav_agent.navigation_layers = 1 # 仅使用可玩区域的导航层 for target_point in interest_points: var path = nav_agent.get_simple_path(start_pos, target_point) if path.empty(): return false # 检查路径终点与目标点的距离 if path[-1].distance_to(target_point) > 1.0: return false return true
内容的提问来源于stack exchange,提问作者Iakl
相关产品推荐
相关产品推荐

