NavigationAgent3D
实验性: This class may be changed or removed in future versions.
用于寻路至某个位置并且能够躲避障碍物的 3D 代理。
描述
用于寻路至某个位置并且能够躲避静态和动态障碍物的 3D 代理。父节点能够使用计算结果沿着路径动态前进。需要有导航数据才能正常工作。
躲避动态障碍物使用的是 RVO 防撞算法。避障的计算发生在物理之前,因此寻路信息能够在物理迭代时安全使用。
注意:设置 target_position 属性之后,必须在每个物理帧使用一次 get_next_path_position 函数来更新导航代理的内部路径逻辑。这个函数返回的向量位置应该用作该代理的父节点的下一次移动位置。
教程
属性
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
BitField[PathMetadataFlags] |
| |
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
|
方法
distance_to_target() const | |
get_avoidance_layer_value(layer_number: int) const | |
get_avoidance_mask_value(mask_number: int) const | |
get_current_navigation_path() const | |
get_current_navigation_result() const | |
get_navigation_layer_value(layer_number: int) const | |
get_navigation_map() const | |
get_rid() const | |
is_target_reached() const | |
void | set_avoidance_layer_value(layer_number: int, value: bool) |
void | set_avoidance_mask_value(mask_number: int, value: bool) |
void | set_navigation_layer_value(layer_number: int, value: bool) |
void | set_navigation_map(navigation_map: RID) |
void | set_velocity_forced(velocity: Vector3) |
信号
link_reached(details: Dictionary) 🔗
表示代理到达导航链接的信号。当代理移动到路径下一个位置的 path_desired_distance 范围内,且该位置是导航链接时发出。
根据 path_metadata_flags 的值,详细信息字典可能包含以下键:
position
:到达的链接的起始位置。rid
:链接的 RID。owner
:管理该链接的对象(通常是NavigationLink3D)。link_entry_position
:如果owner
可用且该所有者是一个 NavigationLink3D,它将包含代理正在进入时的链接点的全局位置。link_exit_position
:如果owner
可用且该所有者是一个 NavigationLink3D,它将包含代理正在退出时的链接点的全局位置。
navigation_finished() 🔗
表示代理导航完成的信号。如果目标可达,则导航会在抵达目标位置时停止。如果目标不可达,则导航会在抵达最后一个路径点时停止。每次加载的路径只会发出一次这个信号。
目标可达时,信号会在 target_reached 后发出。
path_changed() 🔗
当该代理必须更新加载的路径时发出:
因为路径以前是空的。
因为导航地图已经改变。
因为代理从当前路径段推得比 path_max_distance 更远。
target_reached() 🔗
表示代理到达目标的信号,即代理移到了与 target_position 相距 target_desired_distance 之内的位置。每次加载路径只会发出一次这个信号。
目标可达时,信号会在 navigation_finished 前发出。
并不是每次都能够到达目标位置,但是每次都能够到达最终位置。见 get_final_position。
velocity_computed(safe_velocity: Vector3) 🔗
计算出避障速度时发出通知。只要 avoidance_enabled 为 true
并且代理存在导航地图,就会在每次更新时发出。
waypoint_reached(details: Dictionary) 🔗
表示代理已到达航路点的信号。当代理移动到路径下一个位置的 path_desired_distance 范围内时发出。
根据 path_metadata_flags 的值,详细信息字典可能包含以下键:
position
:到达的路标点的位置。type
:包含该路标的导航基元(区块或链接)的类型。rid
:包含的导航基元(区块或链接)的 RID。owner
:管理包含的导航基元(区块或链接)的对象。
属性说明
bool avoidance_enabled = false
🔗
如果为 true
,该代理会在 NavigationServer3D 上注册 RVO 避障回调。当设置 velocity 并且处理完成时,会通过与 velocity_computed 的信号连接接收到安全速度 safe_velocity
Vector3。注册的代理过多会为避障处理带来显著的性能开销,应该仅在需要它的代理上启用。
决定该 NavigationAgent 避障层的位域。avoidance_mask 中该位域存在交集的其他代理会躲避这个代理。
决定该 NavigationAgent 会躲避那些代理和障碍物的位域,需要该位域与对方的 avoidance_layers 存在至少一个共同的比特位。
float avoidance_priority = 1.0
🔗
该代理不会针对 avoidance_mask 存在匹配但 avoidance_priority 更低的代理调整速度。相应地,优先级更低的代理则会对其速度进行更大的调整,从而避免与这个代理发生碰撞。
如果为 true
,则为该代理显示调试内容。
Color debug_path_custom_color = Color(1, 1, 1, 1)
🔗
如果 debug_use_custom 为 true
,则该代理使用该颜色,不使用全局颜色。
float debug_path_custom_point_size = 4.0
🔗
如果 debug_use_custom 为 true
,则该代理使用该栅格化点尺寸进行路径点的渲染,不使用全局点尺寸。
bool debug_use_custom = false
🔗
如果为 true
,则该代理使用 debug_path_custom_color 中定义的颜色,不使用全局颜色。
避障代理的高度。2D 避障时,代理会忽略位于其上方或低于当前位置 + 高度的其他代理或障碍物。3D 避障时只使用半径球体,该设置无效。
如果为 true
,并且代理使用 2D 避障,它将记住设置的 y 轴速度并在避障步进后重新应用它。虽然 2D 避障没有 y 轴并在平坦平面上进行模拟,但该设置可以帮助柔化不均匀 3D 几何体上最明显的裁剪。
该代理所需考虑的最大邻居数。
代理所能达到的最大移动速度。
决定该代理计算路径所使用的导航地区导航层的位域。运行时进行修改会清空当前的导航路径,并根据新的导航层生成一条新的路径。
float neighbor_distance = 50.0
🔗
搜索其他代理的距离。
float path_desired_distance = 1.0
🔗
距离阈值,用于确定是否已到达某个路径点。使用这个值,代理就不必精确地到达某个路径点,只需到达该路径点的大致区域内即可。如果这个值设得太大,该 NavigationAgent 会跳过路径上的点,这可能导致它离开该导航网格。如果这个值设得太小,该 NavigationAgent 会陷入重新寻路的死循环,因为它会在每次物理帧更新后都会超过下一个点。
float path_height_offset = 0.0
🔗
这个 NavigationAgent 的任何向量路径位置的 Y 坐标值都会减去这个高度偏移量。NavigationAgent 的高度偏移量既不会改变也不会影响导航网格和寻路结果。要支持不同大小的代理,需要提供其他使用了带有导航网格区块的导航地图,并且开发者使用合适的代理半径或高度对其进行了烘焙。
float path_max_distance = 5.0
🔗
允许代理偏离通往最终位置的理想路径的最大距离。可能为了防撞而产生偏离。超出最大距离时,会重新计算理想路径。
BitField[PathMetadataFlags] path_metadata_flags = 7
🔗
void set_path_metadata_flags(value: BitField[PathMetadataFlags])
BitField[PathMetadataFlags] get_path_metadata_flags()
与导航路径一起返回的附加信息。
PathPostProcessing path_postprocessing = 0
🔗
void set_path_postprocessing(value: PathPostProcessing)
PathPostProcessing get_path_postprocessing()
对 pathfinding_algorithm 找到的原始路径走廊应用的路径后期处理。
PathfindingAlgorithm pathfinding_algorithm = 0
🔗
void set_pathfinding_algorithm(value: PathfindingAlgorithm)
PathfindingAlgorithm get_pathfinding_algorithm()
路径查询中使用的寻路算法。
该避障代理的半径。这是该避障代理的“身体”,不是避障机制的起始半径(由 neighbor_distance 控制)。
不会影响正常的寻路。要修改角色的寻路半径,请在烘焙 NavigationMesh 资源时使用不同的 NavigationMesh.agent_radius 属性,针对不同的角色大小使用不同的导航地图。
float simplify_epsilon = 0.0
🔗
以世界单位表示的路径简化量。
如果为 true
,将返回路径的简化版本,其中移除了不太重要的路径点。简化量由 simplify_epsilon 控制。简化使用 Ramer-Douglas-Peucker 算法的变体进行曲线点抽取。
路径简化有助于缓解使用某些代理类型和脚本行为可能出现的各种路径跟踪问题。例如“开放场”中的“转向”代理或避让。
float target_desired_distance = 1.0
🔗
与目标的距离阈值,小于该阈值时会认为已抵达目标位置。已抵达目标位置时会发出 target_reached 并结束导航(见 is_navigation_finished 和 navigation_finished)。
将这个属性设置为大于 path_desired_distance 的值可以提前结束导航(导航会在到达最后一个路径点之前停止)。
将这个属性设置为小于 path_desired_distance 的值则会让导航在更接近目标位置的地方结束(导航在抵达最后一个路径点后不会立即停止)。不过如果设得太小,代理就会陷入重新移动的循环,因为每次物理帧更新时移动的距离都会超过与目标的实际距离。
Vector3 target_position = Vector3(0, 0, 0)
🔗
设置后,会向 NavigationServer 请求一条新的从当前代理位置到 target_position 的导航路径。
float time_horizon_agents = 1.0
🔗
考虑其他代理的前提下,该代理的速度的最短安全时间,这个速度是通过碰撞躲避算法计算的。数值越大,代理响应其他代理的速度就越快,但选择速度的自由度也就越小。太高的取值会大大降低代理的移动速度。必须为正数。
float time_horizon_obstacles = 0.0
🔗
考虑静态避障障碍物的前提下,该代理的速度的最短安全时间,这个速度是通过碰撞躲避算法计算的。数值越大,代理响应静态避障障碍物的速度就越快,但选择速度的自由度也就越小。太高的取值会大大降低代理的移动速度。必须为正数。
bool use_3d_avoidance = false
🔗
如果为 true
,则代理会在 3D 空间中计算全向的避障速度,例如发生在空中、水下、太空中的游戏。使用 3D 避障的代理只会躲避其他使用 3D 避障的代理、对基于半径的障碍物作出反应。会忽略基于顶点的障碍物。
如果为 false
,则代理会在 2D 空间中沿 X 和 Z 轴计算避障速度,忽略 Y 轴。使用 2D 避障的代理只会躲避其他使用 2D 避障的代理、对基于半径和基于顶点的障碍物作出反应。其他使用 2D 避障的代理如果在该代理之下,或者高于该代理当前位置与 height 之和则会被忽略。
Vector3 velocity = Vector3(0, 0, 0)
🔗
为代理设置新的需求速度。避障仿真会尽可能尝试满足这个速度,但为了躲避与其他代理和障碍物的碰撞也会对它进行修改。将代理传送至新的位置时,请使用 set_velocity_forced 重置内部仿真速度。
方法说明
float distance_to_target() const 🔗
返回与目标位置的距离,使用的是代理的全局位置。用户必须设置 target_position 才能获得精确结果。
bool get_avoidance_layer_value(layer_number: int) const 🔗
返回 avoidance_layers 位掩码中指定的层是否启用,给定的 layer_number
应在 1 和 32 之间。
bool get_avoidance_mask_value(mask_number: int) const 🔗
返回 avoidance_mask 位掩码中指定的掩码是否启用,给定的 mask_number
应在 1 和 32 之间。
PackedVector3Array get_current_navigation_path() const 🔗
返回这个代理从起点到终点的当前路径,使用全局坐标。该路径只会在目标位置发生变化,或者代理要求重新计算路径时更新。路径数组不应用于直接路径移动,因为代理有自己的内部路径逻辑,手动更改路径数组可能会破坏该逻辑。每个物理帧上使用一次预期的 get_next_path_position,来接收用于该代理移动的下一个路径点,因为该函数还会更新内部路径逻辑。
int get_current_navigation_path_index() const 🔗
返回该代理当前位于导航路径 PackedVector3Array 中的哪一个索引。
NavigationPathQueryResult3D get_current_navigation_result() const 🔗
返回该代理目前正在使用的路径所对应的路径查询结果。
Vector3 get_final_position() 🔗
返回当前导航路径上可到达的最终位置的全局坐标。如果该代理需要更新导航路径,从而使该代理发出 path_changed 信号,则该位置可能会发生变化。
bool get_navigation_layer_value(layer_number: int) const 🔗
返回 navigation_layers 位掩码中指定的层是否启用,给定的 layer_number
应在 1 和 32 之间。
RID get_navigation_map() const 🔗
返回这个 NavigationAgent 节点的导航地图的 RID。这个函数返回的始终是在 NavigationAgent 上设置的地图,不是 NavigationServer 上的抽象代理所使用的地图。如果通过 NavigationServer API 修改了代理的地图,该 NavigationAgent 节点是不会感知到地图的变化的。请使用 set_navigation_map 修改该 NavigationAgent 的导航地图,能够同时在 NavigationServer 上的代理。
Vector3 get_next_path_position() 🔗
返回可以移动至的下一个位置,使用全局坐标,确保中途没有静态对象的阻挡。如果该代理没有导航路径,则会返回该代理父节点的位置。这个函数每个物理帧都必须调用一次,更新 NavigationAgent 内部的路径逻辑。
返回这个代理在 NavigationServer3D 上的 RID。
bool is_navigation_finished() 🔗
如果代理的导航已完成,则返回 true
。如果目标可达,则导航将在达到目标时结束。如果目标不可达,则导航将在到达路径的最后一个航路点时结束。
注意:虽然 true
更喜欢停止调用更新函数,例如 get_next_path_position。这避免了由于调用重复的路径更新而使常设代理抖动。
如果 get_final_position 位于 target_position 的 target_desired_distance 范围内,则返回 true
。
bool is_target_reached() const 🔗
如果代理到达目标,即代理移动到 target_position 的 target_desired_distance 范围内,则返回 true
。不一定总能到达目标,但应总能到达最终位置。请参阅 get_final_position。
void set_avoidance_layer_value(layer_number: int, value: bool) 🔗
根据 value
启用或禁用 avoidance_layers 位掩码中指定的层,给定的 layer_number
应在 1 和 32 之间。
void set_avoidance_mask_value(mask_number: int, value: bool) 🔗
根据 value
启用或禁用 avoidance_mask 位掩码中指定的掩码,给定的 mask_number
应在 1 和 32 之间。
void set_navigation_layer_value(layer_number: int, value: bool) 🔗
根据 value
,启用或禁用 navigation_layers 位掩码中指定的层,给定的 layer_number
应在 1 和 32 之间。
void set_navigation_map(navigation_map: RID) 🔗
设置这个 NavigationAgent 节点所应使用的导航地图的 RID,同时还会更新 NavigationServer 上的代理 agent
。
void set_velocity_forced(velocity: Vector3) 🔗
将防撞仿真的内部速度替换为 velocity
。代理传送到新的位置之后,应该在同一帧里使用这个函数。如果频繁调用这个函数,可能会让代理卡住。