AStarQuery 选项

此页面介绍了 AStarQuery 类提供的一些配置选项。

请注意,在使用简化的路径计算 API 时,这些选项不可用或设置为默认值。为了为人物设置这些选项,必须自定义人物使用的 NavigationProfile,或从 NavigationProfile 检索查询,对它进行设置,并在 Bot::ComputeNewPathAsync() 调用中提供它。有关这些备选项的详细信息,请参见获取静态路径

开始或结束 NavGraph 中的查询

大多数情况下,您用于路径计算的起始点和目标点都将位于 NavMesh 边界内的地面上。在此常见情景中,查询将以透明的方式负责查找与您在初始化查询时提供的起始点和目标点相对应的 NavMesh 三角形。

但是,如果您在游戏中广泛地使用 NavGraph 和智能对象,则可能需要允许人物在正穿过位于 NavMesh 边界之外的 NavGraph 时开始路径计算。同样,您可能需要允许人物移动到位于 NavMesh 边界之外的 NavGraph 的顶点或边上的目标。但是,却没有用来将 3D 空间内的任意点与 NavGraph 顶点和边关联的内置空间化系统。

您可以为 AStarQuery 明确设置一个指针,以指向应被用作此查询的起始点或目标点的 NavGraph 顶点或边,从而为这些情况提供支持。使用以下方法:

void AStarQuery::SetStartNavGraphEdgePtr(const NavGraphEdgePtr& startNavGraphEdgePtr, NavGraphEdgeDirection navGraphEdgePathfindMode);
void AStarQuery::SetStartNavGraphVertexPtr(const NavGraphVertexPtr& startNavGraphVertexPtr);
void AStarQuery::SetDestNavGraphEdgePtr(const NavGraphEdgePtr& startNavGraphEdgePtr, NavGraphEdgeDirection navGraphEdgePathfindMode);
void AStarQuery::SetDestNavGraphVertexPtr(const NavGraphVertexPtr& startNavGraphVertexPtr);

例如,如果您的人物正在爬梯子,而您希望重新计算其路径,则可以设置寻径查询,以使用此人物当前正在跟随的 NavGraph 边作为路径计算的起始点。

请注意,设置一条边作为起始点和结束点的方法接受附加枚举值,用于指示指定的边是否可以双向穿越。例如,当人物跟随梯子时,您可以允许新路径的移动方向为沿着起始边的任一方向。这样,此人物就可以在梯子中间改变方向。但是,当人物使用控制跳跃的智能对象时,您可能希望将沿着起始边的移动方向强制为仅一个方向,以避免人物在跳跃到一半时改变方向。

另请注意,如果使用上述方法之一将 NavGraph 顶点或边设置为查询的起始点或目标点,它将替代您为此查询设置的任何起始点或目标位置。

连接到 NavMesh

有时,寻径查询的起始点或目标点可能会在 NavMesh 边界外面一些。例如:

如果 AStarQuery 无法找到有效的 NavMesh 三角形来作为起始点或目标点,它会认为该点位于 NavMesh 边界之外。在这种情况下,它将尝试连接到邻近的 NavMesh。它运行 InsidePosFromOutsidePosQuery,以查找 NavMesh 中最近的有效点,并使用该有效点(及其关联的 NavMesh 三角形)作为路径计算的起始点或目标点。如果通过 NavMesh 的路径计算成功,则会向路径添加一小段,将其从原无效起始点引到第一个路径节点,或从最后一个路径节点引到原无效目标点。

沿 X 轴和 Y 轴从起始点和目标点的最大距离(搜索 NavMesh)由 TraversalParameters::m_fromOutsideNavMeshDistanceTraversalParameters::m_toOutsideNavMeshDistance 进行设置。默认的最大距离为 1.5f 米。该搜索查找与轴平行的围绕起始点和目标点的包围盒内的三角形,在 X 轴和 Y 轴上一半的范围设为 m_fromOutsideNavMeshDistancem_toOutsideNavMeshDistance

还可以通过将这些最大距离值设置为 0.f 米以禁用连接。

性能调节选项

AStarQuery 提供了多个选项,您可以用来提高路径计算的性能。

限制传播

当您使用 A* 算法查找无法从起始点到达目标点的路径时(例如在孤立的岛上或屋顶上),该算法最终将探索整个地形,才能确认不存在指向所请求的目标的路径。在较大的地图上,这类无法满足的路径请求可能会浪费大量的 CPU 时间。

例如,在下图中,左侧的整个大片区域都要经过探索,A* 才可以确定不存在到达较远的水边的可能路径。

若要避免此类可能情况,可将 AStarQuery 的传播约束在一个 2D 框内,其范围由从起始位置和目标之间的直线扩展的一个水平(X,Y)平面确定(以米为单位)。

例如,下图显示了绿色的约束框,其范围由白色箭头表示。此 2D 框外的区域永远不会探索。

  • 默认情况下,框的范围(以上面的白色箭头表示)设置为 200.0f,使整个框的宽度为 400 米。因此,在默认情况下,任何路径都不会偏离起始位置和目标之间的直线超过 200 米。
  • 根据游戏级别的布局和需要计算的路径的长度,您可能需要增加此默认值,以在偏离直线路径较大时成功完成非常绕路或迂回的路径计算。您可以通过调用 AStarQuery::SetPropagationBoxExtent() 配置阈值。

检查直线可达性

有时,从路径计算的起始点可以直接到达目标点。在这种情况下,通常不需要启动 A* 算法、搜索 NavData 和优化静态路径,这样做会浪费 CPU 资源。更为高效的做法是只需立即采用从起始点到目标的直接路径,并完全跳过 A* 计算。

为了处理这类情况,AStarQuery 可以在内部进行 CanGo 查询,以测试到达目标的直接路径是否没有障碍物。如果没有障碍物,AStarQuery 会立即采用直接路径。

但是,可达性测试不是“免费”的;它也需要占用少量 CPU 资源执行检查。因此,虽然此项检查确实能够针对可以从起始点直接到达目标的一部分路径请求提高性能,但在直接路径没有障碍物的情况下,检查本身仍会使用 CPU,而这是不必要的。视您的游戏中直接可达的路径请求数和必须使用 A* 的路径请求数的比率,激活可达性检查可能会提高整体性能,但也可能不会提高。

从路径请求的起始点直接到达目标的可能性越大,可达性检查提高整体寻径性能的可能性相应地也越大。因此,举例来说,在障碍物较少的完全开放的地形中,或者需要频繁计算非常短的路径时(例如在跟随另一个角色时),您可以考虑激活此直线检查。

请注意,如果直线测试成功,就肯定不会启动 A*。因此,任何位于起始点和目标之间的任何 NavGraph 都不会考虑在内。如果您使用自定义成本低于通过 NavMesh 的成本的 NavGraph(例如传送点),则人物不会像由 A* 计算路径时那样优先选择包括这些 NavGraph 的路径。