NavigationServer2D
实验性: This class may be changed or removed in future versions.
继承: Object
用于访问低阶 2D 导航的服务器接口。
描述
NavigationServer2D 是负责处理导航地图、区块、代理的服务器。不负责处理 AStar2D 和 AStarGrid2D 的 A* 导航。
地图被划分为多个区块,这些区块由导航多边形组成。它们共同定义了 2D 世界中的可穿越区域。
注意:大多数 NavigationServer2D 的更改都是在下一个物理帧进行的,不会立即生效。包括所有对地图、区块、代理的更改,无论是通过场景树中导航相关的节点作出的更改,还是通过脚本作出的更改。
两个区块必须共享一条相似的边才能相连。如果一条边的两个顶点与另一条边上相应顶点的距离都小于 edge_connection_margin
,那么就会认为这两条边是相连的。
可以使用 region_set_navigation_layers 为区块分配导航层,使用 map_get_path 请求路径时会对导航层进行检查。可用于允许或禁止某些对象进入特定的区域。
使用碰撞躲避系统就需要使用代理。你可以为代理设置目标速度,然后服务器就会发出回调,提供修改后的速度。
注意:碰撞躲避系统并不考虑区块。直接使用修改后的速度可能会将代理移动到可达区域之外。这是碰撞躲避系统的缺陷,更复杂的场合可能需要使用物理引擎。
服务器会对所有调用进行跟踪,并在同步阶段执行。这意味着你可以放心地从任何线程请求对地图作出任何修改。
教程
方法
信号
当导航地图更新时、地区移动或被修改时发出。
navigation_debug_changed() 🔗
当导航调试设置更改时发出。仅在调试版本中可用。
方法说明
创建代理。
bool agent_get_avoidance_enabled(agent: RID) const 🔗
如果指定的 agent
使用避障,则返回 true
。
int agent_get_avoidance_layers(agent: RID) const 🔗
返回指定 agent
的 avoidance_layers
位掩码。
int agent_get_avoidance_mask(agent: RID) const 🔗
返回指定 agent
的 avoidance_mask
位掩码。
float agent_get_avoidance_priority(agent: RID) const 🔗
返回指定 agent
的 avoidance_priority
。
RID agent_get_map(agent: RID) const 🔗
返回请求 agent
目前分配到的导航地图 RID。
int agent_get_max_neighbors(agent: RID) const 🔗
返回在导航中指定的 agent
考虑的其他代理的最大数量。
float agent_get_max_speed(agent: RID) const 🔗
返回指定 agent
的最大速度。
float agent_get_neighbor_distance(agent: RID) const 🔗
返回在导航中到指定 agent
考虑的其他代理的最大距离。
bool agent_get_paused(agent: RID) const 🔗
如果指定的 agent
处于暂停状态,则返回 true
。
Vector2 agent_get_position(agent: RID) const 🔗
返回在世界空间中指定的 agent
的位置。
float agent_get_radius(agent: RID) const 🔗
返回指定 agent
的半径。
float agent_get_time_horizon_agents(agent: RID) const 🔗
返回指定的 agent
如果持续使用由仿真过程计算出的速度移动,能够不与其他代理发生碰撞的最短时间。
float agent_get_time_horizon_obstacles(agent: RID) const 🔗
返回指定的 agent
如果持续使用由仿真过程计算出的速度移动,能够不与静态障碍物发生碰撞的最短时间。
Vector2 agent_get_velocity(agent: RID) const 🔗
返回指定 agent
的速度。
bool agent_has_avoidance_callback(agent: RID) const 🔗
如果指定的 agent
有避障回调,则返回 true
。
bool agent_is_map_changed(agent: RID) const 🔗
如果该地图在上一帧发生了改变,则返回 true。
void agent_set_avoidance_callback(agent: RID, callback: Callable) 🔗
设置在 agent
的每个避障处理步骤之后调用的回调 Callable。计算出的 safe_velocity
将在物理计算之前通过信号发送。
注意:只要代理还在导航地图上且未被释放,创建的回调就会始终独立于 SceneTree 状态进行处理。要为某个代理禁用回调的发送,请再次使用一个空的 Callable 来调用 agent_set_avoidance_callback。
void agent_set_avoidance_enabled(agent: RID, enabled: bool) 🔗
如果 enabled
为 true
,则指定的 agent
使用避障。
void agent_set_avoidance_layers(agent: RID, layers: int) 🔗
设置该代理的 avoidance_layers
位掩码。
void agent_set_avoidance_mask(agent: RID, mask: int) 🔗
设置该代理的 avoidance_mask
位掩码。
void agent_set_avoidance_priority(agent: RID, priority: float) 🔗
设置该代理的 avoidance_priority
,优先级 priority
在 0.0(最低优先级)到 1.0(最高优先级)之间。
agent
指定的代理不会针对 avoidance_mask
存在匹配但 avoidance_priority
更低的代理调整速度。相应地,优先级更低的代理则会对其速度进行更大的调整,从而避免与这个代理发生碰撞。
void agent_set_map(agent: RID, map: RID) 🔗
将代理放入地图中。
void agent_set_max_neighbors(agent: RID, count: int) 🔗
设置在导航中,该代理所考虑的其他代理的最大数量。这个数越大,模拟的运行时间越长。如果这个数太小,则模拟会不安全。
void agent_set_max_speed(agent: RID, max_speed: float) 🔗
设置该代理的最大速度。必须为正数。
void agent_set_neighbor_distance(agent: RID, distance: float) 🔗
设置在导航中,该代理所考虑的其他代理的最大距离。这个数越大,模拟的运行时间越长。如果这个数太小,则模拟会不安全。
void agent_set_paused(agent: RID, paused: bool) 🔗
如果 paused
为 true,则不会对指定的 agent
进行处理,例如计算避障速度以及收到避障回调。
void agent_set_position(agent: RID, position: Vector2) 🔗
设置该代理在世界空间中的位置。
void agent_set_radius(agent: RID, radius: float) 🔗
设置该代理的半径。
void agent_set_time_horizon_agents(agent: RID, time_horizon: float) 🔗
考虑其他代理的前提下,该代理的速度的最短安全时间,这个速度是通过仿真得到的。数值越大,代理响应其他代理的速度就越快,但该代理选择速度的自由度也就越小。太高的取值会大大降低代理的移动速度。必须为正数。
void agent_set_time_horizon_obstacles(agent: RID, time_horizon: float) 🔗
考虑其他静态避障障碍物的前提下,该代理的速度的最短安全时间,这个速度是通过仿真得到的。数值越大,代理响应存在的静态避障障碍物的速度就越快,但该代理选择速度的自由度也就越小。太高的取值会大大降低代理的移动速度。必须为正数。
void agent_set_velocity(agent: RID, velocity: Vector2) 🔗
将 velocity
设置为指定代理 agent
的新的需求速度。避障仿真会尽可能尝试满足这个速度,但为了躲避与其他代理和障碍物的碰撞也会对它进行修改。将代理传送至新的较远的位置时,请改用 agent_set_velocity_forced 重置内部速度状态。
void agent_set_velocity_forced(agent: RID, velocity: Vector2) 🔗
将指定代理 agent
的避障仿真内部速度替换为 velocity
。将代理传送至新的较远的位置时,应该在同一帧里使用这个函数。频繁调用这个函数可能让代理卡住。
void bake_from_source_geometry_data(navigation_polygon: NavigationPolygon, source_geometry_data: NavigationMeshSourceGeometryData2D, callback: Callable = Callable()) 🔗
使用提供的 source_geometry_data
中的数据烘焙提供的 navigation_polygon
。该过程完成后,将调用可选的 callback
。
void bake_from_source_geometry_data_async(navigation_polygon: NavigationPolygon, source_geometry_data: NavigationMeshSourceGeometryData2D, callback: Callable = Callable()) 🔗
使用提供的 source_geometry_data
中的数据烘焙提供的 navigation_polygon
,并作为在后台线程上运行的异步任务。该过程完成后,将调用可选的 callback
。
销毁给定的 RID。
bool get_debug_enabled() const 🔗
如果该 NavigationServer 启用了调试,则返回 true
。
返回该 NavigationServer 上所有已创建的导航地图的 RID。会同时返回已创建的 2D 和 3D 导航地图,因为理论上它们之间是没有区别的。
bool is_baking_navigation_polygon(navigation_polygon: NavigationPolygon) const 🔗
当提供的导航多边形正在后台线程上烘焙时返回 true
。
在地图上新建两个地点之间的链接。
bool link_get_enabled(link: RID) const 🔗
如果指定的 link
已启用,则返回 true
。
Vector2 link_get_end_position(link: RID) const 🔗
返回链接 link
的结束位置。
float link_get_enter_cost(link: RID) const 🔗
返回 link
链接的进入消耗。
RID link_get_map(link: RID) const 🔗
返回请求的导航链接 link
当前分配的导航地图的 RID。
int link_get_navigation_layers(link: RID) const 🔗
返回 link
的导航层。
int link_get_owner_id(link: RID) const 🔗
返回管理该链接的对象的 ObjectID
。
Vector2 link_get_start_position(link: RID) const 🔗
返回 link
链接的入口位置。
float link_get_travel_cost(link: RID) const 🔗
返回 link
链接的移动消耗。
bool link_is_bidirectional(link: RID) const 🔗
返回该 link
是否能够双向通行。
void link_set_bidirectional(link: RID, bidirectional: bool) 🔗
设置该 link
是否能够双向通行。
void link_set_enabled(link: RID, enabled: bool) 🔗
如果 enabled
为 true
,则指定的 link
会在它的当前导航地图中生效。
void link_set_end_position(link: RID, position: Vector2) 🔗
设置 link
的出口位置。
void link_set_enter_cost(link: RID, enter_cost: float) 🔗
设置 link
的进入消耗 enter_cost
。
void link_set_map(link: RID, map: RID) 🔗
设置该链接的导航地图 RID。
void link_set_navigation_layers(link: RID, navigation_layers: int) 🔗
设置该链接的导航层。可以在(使用 map_get_path)进行路径请求时选择链接。
void link_set_owner_id(link: RID, owner_id: int) 🔗
设置管理该链接的对象的 ObjectID
。
void link_set_start_position(link: RID, position: Vector2) 🔗
设置 link
的入口位置。
void link_set_travel_cost(link: RID, travel_cost: float) 🔗
设置 link
的移动消耗 travel_cost
。
创建一张新地图。
void map_force_update(map: RID) 🔗
该函数将立即强制指定的导航 map
RID 的同步。默认情况下,导航地图仅在每个物理帧结束时同步。该函数可用于立即(重新)计算该导航地图的所有导航网格和区块连接。这使得可以在同一帧中对修改后的地图的导航路径立即执行查询(如果需要,可以执行多次)。
由于技术上的限制,当前的 NavigationServer 命令队列将被冲刷。这意味着所有已在当前物理帧中入队的更新命令都会被执行,即使是那些用于其他地图、不属于指定地图的区块和代理的更新命令。 昂贵计算的导航网格和地图的区块连接将仅针对指定地图进行。其他地图将在物理帧结束时接收正常同步。如果指定的地图在强制更新后又收到了修改,则它将在其他地图收到更新时再次更新。
避障处理和 safe_velocity
信号的分发不受该函数影响,仍继续发生在物理帧结束时的所有地图和代理上。
注意:能力越大,责任越大。该函数仅该用于用户真正知道自己在做什么并且有充分理由的情况。强制立即更新导航地图需要锁定 NavigationServer 并冲刷整个 NavigationServer 命令队列。这不仅会严重影响游戏的性能,而且如果缺乏远见且使用不当,还会引入 bug。
Array[RID] map_get_agents(map: RID) const 🔗
返回所有与请求的导航地图 map
关联的导航代理的 RID。
float map_get_cell_size(map: RID) const 🔗
返回地图的单元格大小,用于将导航网格的顶点进行栅格化。
Vector2 map_get_closest_point(map: RID, to_point: Vector2) const 🔗
返回导航网格表面上与提供的 to_point
距离最近的点。
RID map_get_closest_point_owner(map: RID, to_point: Vector2) const 🔗
返回由 map_get_closest_point 返回的点的所有者地区的 RID。
float map_get_edge_connection_margin(map: RID) const 🔗
返回地图的边界连接边距。边界连接边距是用于连接两个地区的距离。
int map_get_iteration_id(map: RID) const 🔗
返回导航地图的当前迭代 ID。导航地图发生更改并同步时都会增加迭代 ID。迭代 ID 为 0 表示导航地图从未进行过同步。
注意:迭代 ID 超过取值范围后会绕回 1。
float map_get_link_connection_radius(map: RID) const 🔗
返回该地图的链接连接半径。该距离是任何链接将搜索要连接的导航网格多边形的最大范围。
Array[RID] map_get_links(map: RID) const 🔗
返回当前分配给请求的导航地图 map
的所有导航链接的 RID。
Array[RID] map_get_obstacles(map: RID) const 🔗
返回当前分配给请求的导航地图 map
的所有导航障碍物的 RID。
PackedVector2Array map_get_path(map: RID, origin: Vector2, destination: Vector2, optimize: bool, navigation_layers: int = 1) const 🔗
返回从原点到达目的地的导航路径。navigation_layers
是被允许在路径中的所有区块导航层的位掩码。
Vector2 map_get_random_point(map: RID, navigation_layers: int, uniformly: bool) const 🔗
返回与 navigation_layers
匹配的所有地图区块多边形中随机挑选的位置。
如果 uniformly
为 true
,则所有地图区块、多边形、面的权重都会根据对应表面调整权重(较慢)。
如果 uniformly
为 false
,则只会简单地随机挑选一个区块和一个多边形(较快)。
Array[RID] map_get_regions(map: RID) const 🔗
返回当前分配给所请求的导航 map
的所有导航区块的 RID。
bool map_get_use_edge_connections(map: RID) const 🔗
返回是否允许导航地图 map
使用边缘连接与位于导航地图边缘连接边距范围内的其他导航区块相连接。
bool map_is_active(map: RID) const 🔗
如果地图处于活动状态,则返回 true。
void map_set_active(map: RID, active: bool) 🔗
设置地图的激活态。
void map_set_cell_size(map: RID, cell_size: float) 🔗
设置用于栅格化导航网格顶点的地图单元格大小。必须与所使用的导航网格单元格大小相匹配。
void map_set_edge_connection_margin(map: RID, margin: float) 🔗
设置用于焊接兼容地区边界的地图边界连接边距。
void map_set_link_connection_radius(map: RID, radius: float) 🔗
设置该地图用于连接链接和导航多边形的链接连接半径。
void map_set_use_edge_connections(map: RID, enabled: bool) 🔗
设置导航地图 map
的边缘连接使用情况。如果 enabled
为 true
,则导航地图允许导航区块使用边缘连接与位于导航地图边缘连接边距范围内的其他导航区块相连接。
新建导航障碍物。
bool obstacle_get_avoidance_enabled(obstacle: RID) const 🔗
如果给定的 obstacle
启用了避障,则返回 true
。
int obstacle_get_avoidance_layers(obstacle: RID) const 🔗
返回指定 obstacle
的 avoidance_layers
位掩码。
RID obstacle_get_map(obstacle: RID) const 🔗
返回请求的障碍物 obstacle
当前分配的导航地图 RID。
bool obstacle_get_paused(obstacle: RID) const 🔗
如果指定的 obstacle
被暂停,则返回 true
。
Vector2 obstacle_get_position(obstacle: RID) const 🔗
返回在世界空间中指定的 obstacle
的位置。
float obstacle_get_radius(obstacle: RID) const 🔗
返回指定的动态 obstacle
的半径。
Vector2 obstacle_get_velocity(obstacle: RID) const 🔗
返回指定的动态 obstacle
的速度。
PackedVector2Array obstacle_get_vertices(obstacle: RID) const 🔗
返回指定的 obstacle
的轮廓顶点。
void obstacle_set_avoidance_enabled(obstacle: RID, enabled: bool) 🔗
如果 enabled
为 true
,则提供的障碍物 obstacle
会影响使用代理的避障。
void obstacle_set_avoidance_layers(obstacle: RID, layers: int) 🔗
设置障碍物的避障层 avoidance_layers
位掩码。
void obstacle_set_map(obstacle: RID, map: RID) 🔗
为障碍物设置导航地图 RID。
void obstacle_set_paused(obstacle: RID, paused: bool) 🔗
如果 paused
为 true,则不会处理指定的障碍物 obstacle
,例如不会影响避障速度。
void obstacle_set_position(obstacle: RID, position: Vector2) 🔗
设置障碍物在世界空间中的位置。
void obstacle_set_radius(obstacle: RID, radius: float) 🔗
设置动态障碍物的半径。
void obstacle_set_velocity(obstacle: RID, velocity: Vector2) 🔗
将动态障碍物 obstacle
的速度设置为 velocity
。能够让其他代理更好地预测该动态障碍物的移动。仅在与障碍物半径一同使用时有效。
void obstacle_set_vertices(obstacle: RID, vertices: PackedVector2Array) 🔗
设置障碍物的轮廓顶点。如果顶点顺时针缠绕,则障碍物会将代理向内部推挤,否则向外推挤。
void parse_source_geometry_data(navigation_polygon: NavigationPolygon, source_geometry_data: NavigationMeshSourceGeometryData2D, root_node: Node, callback: Callable = Callable()) 🔗
根据 navigation_polygon
的属性解析 SceneTree 中的源几何体。会使用解析的结果数据对提供的 source_geometry_data
资源进行更新。后续可以在使用 bake_from_source_geometry_data 烘焙导航网格时使用该资源。解析过程完成后,会调用可选的 callback
。
注意:因为 SceneTree 并不是线程安全的,所以这个函数需要在主线程执行或使用延迟调用。
性能:从 Mesh 资源读取数据数组虽然很方便,但会对帧率造成负面影响。这些数据需要从 GPU 获取,卡住正在处理的 RenderingServer。出于性能考量,请优先使用碰撞形状或在完全在代码中创建数据数组。
void query_path(parameters: NavigationPathQueryParameters2D, result: NavigationPathQueryResult2D) const 🔗
在给定导航地图中查询路径。起点、目标点以及其他参数通过 NavigationPathQueryParameters2D 定义。会使用路径和其他查询中请求的信息更新提供的 NavigationPathQueryResult2D。
创建一个新的地区。
Vector2 region_get_connection_pathway_end(region: RID, connection: int) const 🔗
返回连接门的终点。connection
是一个索引,介于 0 和 region_get_connections_count 的返回值之间。
Vector2 region_get_connection_pathway_start(region: RID, connection: int) const 🔗
返回连接门的起点。connection
是一个索引,介于 0 和 region_get_connections_count 的返回值之间。
int region_get_connections_count(region: RID) const 🔗
返回 region
地区与其他地区在地图上有多少连接。
bool region_get_enabled(region: RID) const 🔗
如果指定的 region
已启用,则返回 true
。
float region_get_enter_cost(region: RID) const 🔗
返回 region
地区的进入消耗。
RID region_get_map(region: RID) const 🔗
返回请求的 region
地区所关联的导航地图的 RID。
int region_get_navigation_layers(region: RID) const 🔗
返回该地区的导航层。
int region_get_owner_id(region: RID) const 🔗
返回管理该地区对象的 ObjectID
。
Vector2 region_get_random_point(region: RID, navigation_layers: int, uniformly: bool) const 🔗
返回与 navigation_layers
匹配的所有区块多边形中随机挑选的位置。
如果 uniformly
为 true
,则所有区块多边形和面的权重都会根据对应表面调整权重(较慢)。
如果 uniformly
为 false
,则只会简单地随机挑选一个多边形和一个面(较快)。
Transform2D region_get_transform(region: RID) const 🔗
返回该 region
的全局变换。
float region_get_travel_cost(region: RID) const 🔗
返回 region
地区的移动消耗。
bool region_get_use_edge_connections(region: RID) const 🔗
返回导航区块 region
是否被设置为使用边缘连接与位于导航地图边缘连接边距范围内的其他导航区块相连接。
bool region_owns_point(region: RID, point: Vector2) const 🔗
如果提供的世界空间中的 point
当前由提供的导航区块 region
拥有,则返回 true
。在这里的上下文中,“拥有”意味着与来自其他导航区块的所有其他导航网格相比,该区块的导航网格多边形面中有一个距离该点最近的可能位置,这些其他导航区块也已在提供的区块的导航地图上注册。
如果有多个导航网格存在符合条件的位置并且距离相等,那么其多边形先被处理的导航区块将赢得所有权。多边形的处理顺序与导航区块在 NavigationServer 上的注册顺序一致。
注意:如果来自不同导航区块的导航网格存在重叠(通常应当避免),可能会得到预料之外的结果。
void region_set_enabled(region: RID, enabled: bool) 🔗
如果 enabled
为 true
,则指定的 region
会在它的当前导航地图中生效。
void region_set_enter_cost(region: RID, enter_cost: float) 🔗
设置 region
地区的进入消耗 enter_cost
。
void region_set_map(region: RID, map: RID) 🔗
设置该地区的地图。
void region_set_navigation_layers(region: RID, navigation_layers: int) 🔗
设置地区的导航层。能够在路径请求中选择地区(使用 map_get_path 时)。
void region_set_navigation_polygon(region: RID, navigation_polygon: NavigationPolygon) 🔗
设置该地区的导航多边形 navigation_polygon
。
void region_set_owner_id(region: RID, owner_id: int) 🔗
设置管理该地区对象的 ObjectID
。
void region_set_transform(region: RID, transform: Transform2D) 🔗
设置该地区的全局变换。
void region_set_travel_cost(region: RID, travel_cost: float) 🔗
设置 region
地区的移动消耗 travel_cost
。
void region_set_use_edge_connections(region: RID, enabled: bool) 🔗
如果 enabled
为 true
,则导航区块 region
将使用边缘连接来与位于导航地图边缘连接边距范围内的其他导航区块相连接。
void set_debug_enabled(enabled: bool) 🔗
如果为 true
,则该 NavigationServer 启用了调试模式。
PackedVector2Array simplify_path(path: PackedVector2Array, epsilon: float) 🔗
返回 path
的简化版本,其中移除了不太重要的路径点。简化量以世界单位表示,由 epsilon
控制。简化使用 Ramer-Douglas-Peucker 算法的变体进行曲线点抽取。
路径简化有助于缓解某些代理类型和脚本行为可能出现的各种路径跟踪问题。例如“转向”代理或“开放场”中的避让。
RID source_geometry_parser_create() 🔗
创建一个新的源几何解析器。如果使用 source_geometry_parser_set_callback 为解析器设置了 Callable,则每当使用 parse_source_geometry_data 时,都会为每个解析的节点调用回调。
void source_geometry_parser_set_callback(parser: RID, callback: Callable) 🔗
为特定源几何体 parser
设置 callback
Callable。Callable 将接收具有以下参数的调用:
navigation_mesh
- 用于定义解析设置的 NavigationPolygon 引用。请勿直接编辑或添加到导航网格。source_geometry_data
- NavigationMeshSourceGeometryData2D 引用。将用于导航网格烘焙的自定义源几何体添加到该对象。node
- 解析的 Node。