寻径和路径跟随

寻径和路径跟随系统是 Gameware Navigation 提供的最高级别的服务。它采用工具箱层提供的许多其他子系统,包括查询系统。

该系统基于 Bot 类及其子组件,以处理为三维游戏中的角色提供寻径时所涉及的许多复杂性,包括:

每个要使用 Gameware Navigation 寻径和路径跟随系统的 NPC 应当有其自己的 Bot 类实例。如果您已执行集成教程(参见将 Navigation 集成到游戏引擎)中的步骤,则说明已编写最少量的代码为您游戏中的角色初始化、更新和销毁人物

寻径和跟随过程

Bot 类的每个实例按以下各节所述寻找和跟随路径。

阶段 1. 获取初始路径

路径跟随系统中的第一步是通过 NavData 计算连接起始点(通常为人物的当前位置)与所需目标的初始路径。该初始路径由 Path 类的实例表示,它是由通过边连接的节点组成的静态不变的结构。

例如,在下图中,黄色人物已经计划了到达屋顶上目标的路径。该路径穿过地面上的 NavMesh,跟随连接地面和屋顶的 NavGraph 边,然后在屋顶上有一个从 NavGraph 边末端到目标的最终线段。

默认情况下,每个 Bot 都有权访问可以计算 Path 的查询(从调用其 NavigationProfile 的对象检索)。如果要计算新路径,可使用 Bot API 请求路径计算,人物将在下一次更新过程中异步执行查询。

有几种不同的方法可用于请求您的 Bot 计算路径;或者您可以为您的 Bot 提供预先计算的路径。有关详细信息,请参见获取静态路径

阶段 2. 创建 LivePath

人物成功计算路径,或插入您自己的路径后,路径跟随系统将分析新路径,并从中构建名为 LivePath 的新结构。LivePath 是一个动态结构,可保留有关路径和人物的路径跟随过程状态的若干重要的上下文信息项,包括可随时浏览以检索路径相关信息的 PathEvent 列表。您可以使用这些 PathEvent 来沿路径扫描即将发生的到不同地形类型、智能对象或无效区域的变换。

例如,在下图中,标志标记 LivePath 中的变换事件:每次路径进入具有不同 NavTag 的区域,以及在 NavGraph 边的起点和终点。

有关这些 PathEvent 以及如何与之交互的详细信息,请参见监视 PathEvent

阶段 3. 跟随 LivePath

在每一帧中,Bot 均会调用一个 Trajectory 对象来确定它在当前帧应该如何移动。Trajectory 负责评估 Bot 及其路径的当前状况,并考虑其他影响,例如可能会产生碰撞的移动障碍物。基于这些因素,以及一组控制角色运动的配置参数,它为角色生成一个用于在当前帧中追赶的建议速度。

默认情况下,Bot 设置为在 Trajectory 类的实例中使用。Trajectory 的这种实现方式可以任意使用以下两种不同的策略之一来计算最终速度:

  • 它可以基于直线捷径(由 ShortcutTrajectory 对象计算出)使用策略。ShortcutTrajectory 在路径上选择一个目标点,可见且位于角色当前位置稍前的位置(默认情况下,最大为前方 10 米),并生成直线走向该目标点的速度。随着不断接近目标点,它定期将目标更新到路径中一个更远的新可见位置。

    例如,在下图中,人物接近角点时,它继续瞄准 LivePath 上最后一个可见点前进。当它足够接近角点,以致可以看到更多的 LivePath 时,它将尽可能将其目标点沿着路径前移。

    此策略为角色提供了一种相对简单且高性能的方式以跳过其初始路径上的急转弯。但是,当新的捷径可用时,它可以允许角色突然改变速度和朝向。

  • 它可以采用基于通道和样条线(由 SplineTrajectory 对象计算得出)的策略。此策略基于通道:在计算路径的同时计算的、初始路径周围的可导航空间的表示形式。SplineTrajectory 检查通道边界即将面临的配置,并计算出一条样条线使角色轨迹不超出那些边界。

    例如,在下图中,您可以看到橙色的通道边界。请注意,在障碍物之间的狭窄缝隙,边界挤压得很近。还请注意,跟随 NavGraph 的路径线段没有通道;第一个通道在 NavGraph 边起点处结束,第二个通道在屋顶开始。与上面的捷径示例一样,在人物沿着路径前进的过程中,会定期计算新的样条线(以红色显示)。

    此策略会在初始路径周围,生成使用更大可用空间的更圆滑的轨迹,代价是寻径阶段(为了生成通道数据)和路径跟随阶段的 CPU 使用率稍高。

您可以在初始化 Bot 时确定使用的轨迹模式,也可以在初始化后随时动态更改。请参见自定义路径跟随

无论 Trajectory 当前在任意给定帧中使用的是哪种策略,它可能都适用下列情况:

  • Bot 位于 NavMesh 的有效区域时,轨迹可以使用动态回避系统生成避免与附近的对象(如移动的障碍物和其他人物)碰撞的轨迹。回避计算机可能会调整移动的方向和/或 Bot 的速度。
  • Bot 穿越 NavGraph 时,轨迹始终会产生一个直通到 NavGraph 中下一个顶点的速度,而无需任何动态回避。

轨迹和动态回避系统中涉及的类包含大量可以针对每个角色进行调整的配置参数。请参见自定义路径跟随

阶段 4. 检索和应用结果

要在每一帧中检索路径跟随系统的最终结果,需要访问 BotOutput,如以下示例所示:

m_velocity = m_navBot->GetBotOutput().m_outputVelocity();

您负责将此速度应用于游戏角色,受动画或物理系统暗含的任何其他限制的约束。

Gameware Navigation 不会做出有关游戏实体在游戏中移动和行进的任何假设。您的角色可以是完全动画驱动的,也可以是完全物理驱动的。因此人物自己不会自动移动;您应解释路径跟随系统生成的建议速度,根据需要调整该速度,并通知人物有关应用到角色的位置和速度的实际更改。

路径跟随系统不希望角色始终位于其预测的位置。以下各项可解释为何您的游戏实体的移动方式可能会有所不同:

  • 离散速度运动模型可能无法密切跟随建议的速度。
  • 物理碰撞、回避或其他特定于游戏玩法的事件可能导致您的角色偏离轨道。

大多数情况下,人物能够透明地跟随路径,而不管路径跟随系统计算的建议速度与实际位置和速度之间的细微差别,或者游戏中使其发生偏离的事件。

但是,如果游戏中出现重大差异(例如角色被推下悬崖),最好在沿路径的每个帧上测试角色前进情况的有效性。如果角色在路径上的位置变得无法到达,并且无法确定新位置,您可能需要重新计算到达目标的新路径。请参见监视路径跟随

监视

在您的角色跟随其路径的过程中,您可能需要响应许多不同类型的事件。您负责留意要响应的事件,并在其出现这些事件时适当地进行处理。

有关详细的讨论,请参见监视路径跟随