使用 NavigationPath
获取 NavigationPath
导航路径可以直接从NavigationServer查询,并且不需要任何其他节点或对象,只要导航地图具有可使用的导航网格即可。
要获取 2D 路径,请使用 NavigationServer2D.map_get_path(地图, 起点, 终点, 优化, 导航层)
。
要获取 3D 路径,请使用 NavigationServer3D.map_get_path(地图, 起点, 终点, 优化, 导航层)
。
有关需要额外设定的更多可自定义导览路径查询,请参阅 使用 NavigationPathQueryObject。
查询所需的参数之一是导航地图的RID。每个游戏世界都有一个自动创建的默认导航地图。默认导航地图可以使用 get_world_2d().get_navigation_map()
从任何Node2D继承节点检索,也可以使用 get_world_3d().get_navigation_map()
从任意Node3D继承节点检索。第二和第三参数是起始位置和目标位置,作为2D的Vector2或3D的Vector3。
If the optimized
parameter is true
, path positions will be shortened along polygon corners with an additional funnel algorithm pass. This works well for free movement on navigation meshes with unequally sized polygons as the path will hug around corners along the polygon corridor found by the A* algorithm. With small cells the A* algorithm creates a very narrow funnel corridor that can create ugly corner paths when used with grids.
如果 optimized
参数为 false
,则路径位置将放置在每个多边形边缘的中心。这适用于具有相同大小多边形的导航网格上的纯网格移动,因为路径将穿过网格单元的中心。在网格之外,由于多边形通常用一条长边覆盖大的开放区域,这可能会产生不必要的长迂回路径。
2D GDScript3D GDScript
extends Node2D
# Basic query for a navigation path using the default navigation map.
func get_navigation_path(p_start_position: Vector2, p_target_position: Vector2) -> PackedVector2Array:
if not is_inside_tree():
return PackedVector2Array()
var default_map_rid: RID = get_world_2d().get_navigation_map()
var path: PackedVector2Array = NavigationServer2D.map_get_path(
default_map_rid,
p_start_position,
p_target_position,
true
)
return path
extends Node3D
# Basic query for a navigation path using the default navigation map.
func get_navigation_path(p_start_position: Vector3, p_target_position: Vector3) -> PackedVector3Array:
if not is_inside_tree():
return PackedVector3Array()
var default_map_rid: RID = get_world_3d().get_navigation_map()
var path: PackedVector3Array = NavigationServer3D.map_get_path(
default_map_rid,
p_start_position,
p_target_position,
true
)
return path
NavigationServer返回的 path
将是2D的 PackedVector2Array
或3D的 PackedVector3Array
。这些只是一个经过内存优化的矢量位置 Array
。阵列内的所有位置矢量都保证位于NavigationPolygon或NavigationMesh内。如果路径数组不是空的,则其导航网格位置最靠近第一个索引 path[0]
位置处的起始位置。离目标位置最近的可用导航网格位置是最后一个索引 path[path.size()-1]
位置。之间的所有索引都是参与者在不离开导航网格的情况下到达目标所应遵循的路径点。
备注
如果目标位置位于未合并或连接的不同导览网格上,则导览路径将通往起始位置导览网格上最接近的可能位置。
以下脚本透过使用 set_movement_target()
设定目标位置,使用预设导览地图沿着导览路径移动Node3D继承节点。
GDScript
@onready var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
var movement_speed: float = 4.0
var movement_delta: float
var path_point_margin: float = 0.5
var current_path_index: int = 0
var current_path_point: Vector3
var current_path: PackedVector3Array
func set_movement_target(target_position: Vector3):
var start_position: Vector3 = global_transform.origin
current_path = NavigationServer3D.map_get_path(
default_3d_map_rid,
start_position,
target_position,
true
)
if not current_path.is_empty():
current_path_index = 0
current_path_point = current_path[0]
func _physics_process(delta):
if current_path.is_empty():
return
movement_delta = movement_speed * delta
if global_transform.origin.distance_to(current_path_point) <= path_point_margin:
current_path_index += 1
if current_path_index >= current_path.size():
current_path = []
current_path_index = 0
current_path_point = global_transform.origin
return
current_path_point = current_path[current_path_index]
var new_velocity: Vector3 = global_transform.origin.direction_to(current_path_point) * movement_delta
global_transform.origin = global_transform.origin.move_toward(global_transform.origin + new_velocity, movement_delta)