Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
NavigationAgent3D¶
用于寻路至某个位置并且能够躲避障碍物的 3D 代理。
描述¶
用于寻路至某个位置并且能够躲避静态和动态障碍物的 3D 代理。父节点能够使用计算结果沿着路径动态前进。需要有导航数据才能正常工作。
躲避动态障碍物使用的是 RVO 防撞算法。避障的计算发生在物理之前,因此寻路信息能够在物理迭代时安全使用。
注意:设置 target_position 属性之后,必须在每个物理帧使用一次 get_next_path_position 函数来更新导航代理的内部路径逻辑。这个函数返回的向量位置应该用作该代理的父节点的下一次移动位置。
教程¶
属性¶
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
BitField<PathMetadataFlags> |
|
|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
方法¶
distance_to_target ( ) const |
|
get_avoidance_layer_value ( int layer_number ) const |
|
get_avoidance_mask_value ( int mask_number ) const |
|
get_current_navigation_path ( ) const |
|
get_current_navigation_path_index ( ) const |
|
get_current_navigation_result ( ) const |
|
get_navigation_layer_value ( int layer_number ) const |
|
get_navigation_map ( ) const |
|
get_rid ( ) const |
|
is_target_reached ( ) const |
|
void |
set_avoidance_layer_value ( int layer_number, bool value ) |
void |
set_avoidance_mask_value ( int mask_number, bool value ) |
void |
set_navigation_layer_value ( int layer_number, bool value ) |
void |
set_navigation_map ( RID navigation_map ) |
void |
set_velocity_forced ( Vector3 velocity ) |
信号¶
link_reached ( Dictionary details )
当到达一个导航链接时通知。
根据 path_metadata_flags 的值,详细信息字典可能包含以下键:
position
:到达的链接的起始位置。rid
:链接的 RID。owner
:管理该链接的对象(通常是NavigationLink3D)。link_entry_position
:如果owner
可用且该所有者是一个 NavigationLink3D,它将包含代理正在进入时的链接点的全局位置。link_exit_position
:如果owner
可用且该所有者是一个 NavigationLink3D,它将包含代理正在退出时的链接点的全局位置。
navigation_finished ( )
当代理内部导航路径索引到达加载路径数组的最后一个索引时,每个加载路径发出一次。可以使用 get_current_navigation_path_index 接收代理内部导航路径索引。
path_changed ( )
当该代理必须更新加载的路径时发出:
因为路径以前是空的。
因为导航地图已经改变。
因为代理从当前路径段推得比 path_max_distance 更远。
target_reached ( )
当代理的全局位置第一次在 target_desired_distance 内到达 target_position 时,每个加载路径发出一次。
velocity_computed ( Vector3 safe_velocity )
计算出避障速度时发出通知。设置了 velocity 才会发出。仅在 avoidance_enabled 为 true 时发出。
waypoint_reached ( Dictionary details )
当已到达路径上的一个路标时发出通知。
根据 path_metadata_flags 的值,详细信息字典可能包含以下键:
position
:到达的路标点的位置。type
:包含该路标的导航基元(区块或链接)的类型。rid
:包含的导航基元(区块或链接)的 RID。owner
:管理包含的导航基元(区块或链接)的对象。
属性说明¶
bool avoidance_enabled = false
如果为 true
,该代理会在 NavigationServer3D 上注册 RVO 避障回调。当设置 velocity 并且处理完成时,会通过与 velocity_computed 的信号连接接收到安全速度 safe_velocity
Vector3。注册的代理过多会为避障处理带来显著的性能开销,应该仅在需要它的代理上启用。
int avoidance_layers = 1
决定该 NavigationAgent 避障层的位域。avoidance_mask 中该位域存在交集的其他代理会躲避这个代理。
int avoidance_mask = 1
决定该 NavigationAgent 会躲避那些代理和障碍物的位域,需要该位域与对方的 avoidance_layers 存在至少一个共同的比特位。
float avoidance_priority = 1.0
该代理不会针对 avoidance_mask 存在匹配但 avoidance_priority 更低的代理调整速度。相应地,优先级更低的代理则会对其速度进行更大的调整,从而避免与这个代理发生碰撞。
bool debug_enabled = false
如果为 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 中定义的颜色,不使用全局颜色。
float height = 1.0
避障代理的高度。2D 避障时,代理会忽略位于其上方或低于当前位置 + 高度的其他代理或障碍物。3D 避障时只使用半径球体,该设置无效。
bool keep_y_velocity = true
如果为 true
,并且代理使用 2D 避障,它将记住设置的 y 轴速度并在避障步进后重新应用它。虽然 2D 避障没有 y 轴并在平坦平面上进行模拟,但该设置可以帮助减轻不均匀 3D 几何体上最明显的裁剪。
int max_neighbors = 10
该代理所需考虑的最大邻居数。
float max_speed = 10.0
代理所能达到的最大移动速度。
int navigation_layers = 1
决定该代理计算路径所使用的导航地区导航层的位域。运行时进行修改会清空当前的导航路径,并根据新的导航层生成一条新的路径。
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 ( BitField<PathMetadataFlags> value )
BitField<PathMetadataFlags> get_path_metadata_flags ( )
与导航路径一起返回的附加信息。
PathPostProcessing path_postprocessing = 0
void set_path_postprocessing ( PathPostProcessing value )
PathPostProcessing get_path_postprocessing ( )
对 pathfinding_algorithm 找到的原始路径走廊应用的路径后期处理。
PathfindingAlgorithm pathfinding_algorithm = 0
void set_pathfinding_algorithm ( PathfindingAlgorithm value )
PathfindingAlgorithm get_pathfinding_algorithm ( )
路径查询中使用的寻路算法。
float radius = 0.5
该避障代理的半径。这是该避障代理的“身体”,不是避障机制的起始半径(由 neighbor_distance 控制)。
不会影响正常的寻路。要修改角色的寻路半径,请在烘焙 NavigationMesh 资源时使用不同的 NavigationMesh.agent_radius 属性,针对不同的角色大小使用不同的导航地图。
float target_desired_distance = 1.0
距离阈值,用于确定是否已到达最终目标点。使用这个值,代理就不必精确地到达最终目标点,到达目标点的大致区域内即可。如果这个值设得太小,该 NavigationAgent 会陷入重新寻路的死循环,因为它在每次物理帧更新后都会超过或者到达不了最终目标点。
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 ( int layer_number ) const
返回 avoidance_layers 位掩码中指定的层是否启用,给定的 layer_number
应在 1 和 32 之间。
bool get_avoidance_mask_value ( int mask_number ) 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 ( int layer_number ) 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 内部的路径逻辑。
RID get_rid ( ) const
返回这个代理在 NavigationServer3D 上的 RID。
bool is_navigation_finished ( )
如果已到达当前加载的导航路径的末尾,则返回 true
。
注意:虽然 true 更喜欢停止调用更新函数,例如 get_next_path_position。这避免了由于调用重复的路径更新而使常设代理抖动。
bool is_target_reachable ( )
如果 get_final_position 位于 target_position 的 target_desired_distance 范围内,则返回 true
。
bool is_target_reached ( ) const
如果已到达 target_position,则返回 true。目标位置并不总是可达。终点位置应该总是可达的。见 get_final_position。
void set_avoidance_layer_value ( int layer_number, bool value )
根据 value
启用或禁用 avoidance_layers 位掩码中指定的层,给定的 layer_number
应在 1 和 32 之间。
void set_avoidance_mask_value ( int mask_number, bool value )
根据 value
启用或禁用 avoidance_mask 位掩码中指定的掩码,给定的 mask_number
应在 1 和 32 之间。
void set_navigation_layer_value ( int layer_number, bool value )
根据 value
,启用或禁用 navigation_layers 位掩码中指定的层,给定的 layer_number
应在 1 和 32 之间。
void set_navigation_map ( RID navigation_map )
设置这个 NavigationAgent 节点所应使用的导航地图的 RID,同时还会更新 NavigationServer 上的代理 agent
。
void set_velocity_forced ( Vector3 velocity )
将防撞仿真的内部速度替换为 velocity
。代理传送到新的位置之后,应该在同一帧里使用这个函数。如果频繁调用这个函数,可能会让代理卡住。