监视路径跟随

关于角色应何时停止路径跟随或何时需要计算通往目标位置的新路径,Gameware Navigation 路径跟随系统不会为您提供高级决策。这些高级决策必须由您决定。一旦请求人物跟随路径,它将尝试一直执行此操作,直到您告知其停止或跟随其他路径。

但是,为了响应角色在跟随路径时出现的情况或事件,路径跟随系统的当前状态将处于打开状态以便供您随时读取。您可以自由决定要响应的事件、检查这些事件的频率(每帧检查、经过一定时间间隔后定期检查等)以及响应的操作。

此页面概述了用于响应事件的一些最常见策略。

与 PathEvent 交互

PathEvent 系统是 Gameware Navigation 路径跟随系统为您提供的主要机制之一,用于监视角色的路径,并响应 NavData 中影响这些路径的动态更改。有关该系统的工作原理以及如何使用该系统的详细信息,请参见监视 PathEvent

访问路径跟随的 BotOutput

您可以使用 Bot::GetBotOutput() 函数读取路径跟随的人物输出(outputVelocityoutputFrontDirectionavoidanceResultUpperBoundType),并访问 IsPathRecomputationNeeded() 函数。

UpperBoundType 有特定值,例如当路径无效时,其值为 UpperBoundType_PathInvalid;当没有路径时,其值为 UpperBoundType_NoPath。在这种情况下,GetUpperBound() 会返回路径的无效位置。

测试轨迹是否可以跟随路径

Trajectory 对象无法再跟随路径时,IsPathRecomputationNeeded() 函数返回的结果为 True。在这种情况下,使用 Trajectory 对象进行路径跟随的人物受到阻滞,因此必须计算得出一条新路径来解决此问题。

if (navBot->GetBotOutput().IsPathRecomputationNeeded())
    navBot->ComputeNewPathToDestination(destination);

测试到达

当您的角色到达其目标点时,您通常会希望停止路径跟随系统以防止不必要的计算。可通过多种方法来检查是否到达目标点;一种简单的方法是调用 Bot::HasReachedPosition() 方法,该方法通过使用给定的半径进行几何测试。

例如:[Tutorial_FirstIntegration.cpp 中的代码]

bool MyGameEntity::HasArrived()
{    
    KyFloat32 arrivalPrecisionRadius = m_navBot->GetConfig().m_pathProgressConfig.m_checkPointRadius;
    if (m_navBot->HasReachedPosition(m_destinationPosition, arrivalPrecisionRadius))
    {
        return true;
    }

    return false;
}

当角色到达后,您可以通过调用 Bot::ClearFollowedPath() 来取消路径跟随。

测试路径计算是否成功

在尝试检索路径跟随系统计算的速度并将其应用于角色之前,您可能希望检查寻径系统是否能够成功找到路径。调用 Bot::GetFollowedPath();如果该方法返回 KY_NULL,则静态路径未成功计算或正在计算中。

例如:

    if (m_navBot->GetFollowedPath() == KY_NULL)
        m_velocity = Kaim::Vec3f::Zero();
    else
        m_velocity = m_navBot->GetBotOutput().m_outputVelocity;

如果路径未能成功计算,您可以通过从寻径查询中检索状态值来获得更多信息。例如,如果使用 AStarQuery,您可以调用 AStarQuery::GetResult()

无论您使用何种查询类型,都可以通过调用以下方法来获得有关过程状态和结果的信息:

m_navBot->GetPathFinderQuery()->m_processStatus;
m_navBot->GetPathFinderQuery()->GetPathFinderResult();

测试整体路径有效性

人物跟随路径时,路径上遇到 NavData 更改可能会阻塞通往目标的整体路线,但不会立即阻止人物继续前往其目标点。例如,动态障碍物或被禁止的 TagVolume 可能会阻塞角色尚未到达的通道。只要您按照上文所述来测试目标点状态,当角色到达阻塞地形且无法沿 LivePath 找到有效目标点时,他们会重新计算路径。但是,您可能希望对之前阻塞的路径做出响应。

要测试到目的地的全程路径是否有效,请检查 Bot::GetBotOutput().GetUpperBoundType() 的结果。对结果的描述如下表所示。

结果 说明
UpperBoundType_NoPath 没有路径,也没有有效的 UpperBound
UpperBoundType_PathInvalid 整个路径无效,且没有有效的 UpperBound
UpperBoundType_Temporary 路径正在验证中,因此当前无法跟进到最后。UpperBound 提供一个临时的限制,但并不表示路径无效。将会在接下来的各个帧中对其进一步验证。
UpperBoundType_PathLastNode UpperBound 是路径的最后一个节点,因此可以跟进到最后。
UpperBoundType_ValidityUpperBound 该路径不能跟进到最后。UpperBound 是沿路径的上限,并非最后一个节点。在这种情况下,您可能希望停止跟随当前路径并尝试重新计算路径。或者,您可能希望从角色的角度假装对地形的了解有限,方法是让角色继续跟随其当前路径,直到到达 UpperBound 位置的某个半径范围内,以便可以看到障碍地形等。