The Autodesk Navigation path following system does not make high-level decisions for you about when a character should stop following a path, or when a character needs to calculate a new path to its destination. Decisions at that level must come from you. Once you request a Bot to follow a path, it will attempt to keep doing so until it is told to stop or to follow a different path.
However, the current state of the path following system is open for you to read at all times in order to respond to conditions or events that arise as your characters follow their paths. You are free to determine what events you want to respond to, how often you want to check for these events (every frame, periodically after a certain time interval has elapsed, etc.), and what actions you want to take in response.
This page outlines some of the most common strategies for responding to events.
The PathEvent system is one of the key mechanisms that the Autodesk Navigation path following system provides for you to monitor your characters' paths, and to respond to dynamic changes in the NavData that affect those paths. For details on how the system works and how you can use it, see Monitoring PathEvents.
You can use the Bot::GetBotOutput() function to read the Bot output for path following (outputVelocity, outputFrontDirection, avoidanceResult, and UpperBoundType), and to access the IsPathRecomputationNeeded() function.
The UpperBoundType has specific values, such as when the path is invalid (UpperBoundType_PathInvalid), and when there is no path value (UpperBoundType_NoPath). In this case, GetUpperBound() returns an invalid position on the path.
The IsPathRecomputationNeeded() function returns true when the Trajectory object is not able to follow a path anymore. In this case, the bot using the Trajectory object for path following gets stuck and a new path must be computed to resolve this issue.
if (navBot->GetBotOutput().IsPathRecomputationNeeded()) navBot->ComputeAStarQueryAsync(destination);
When your character arrives at its destination point, you typically will want to stop the path following system in order to prevent unnecessary computations. There are many possible ways that you can check for arrival at the destination; one simple way is to call the Bot::HasReachedPosition() method, which conducts a geometric test using a given radius.
For example: [code from 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; }
When the character has arrived, you can cancel path following by calling Bot::ClearFollowedPath().
Before you try to retrieve the velocity calculated by the path following system and apply it to your characters, you may want to check that the path finding system was able to find a path successfully. Call Bot::GetFollowedPath(); if this method returns KY_NULL, the static path has not been successfully computed or is in progress.
For example:
if (m_navBot->GetFollowedPath() == KY_NULL) m_velocity = Kaim::Vec3f::Zero(); else m_velocity = m_navBot->GetBotOutput().m_outputVelocity;
If the path has not been successfully computed, you may be able to get more information by retrieving status values from your pathfinding query. For example, if you use an AStarQuery, you can call AStarQuery::GetResult().
Regardless of the type of query you use, you can obtain information on the process status and result by calling the following methods:
m_navBot->GetPathFinderQuery()->m_processStatus; m_navBot->GetPathFinderQuery()->GetPathFinderResult();
While your Bot is following a path, changes in the NavData crossed by the path may block the overall route to the destination without immediately preventing the Bot from proceeding toward its target point. For example, a dynamic obstacle or a forbidden TagVolume might block a corridor that the character has not yet reached. As long as you test the target point status as described above, your characters will re-calculate a path when they get to the blocking terrain and can no longer find a valid point to target along the LivePath. However, you may want to respond to blocked paths earlier.
To test whether or not the path is valid all the way to the destination, check the result of Bot::GetBotOutput().GetUpperBoundType(). The results are:
UpperBoundType_NoPath
There is no path and no valid UpperBound.
UpperBoundType_PathInvalid
The whole path is invalid and there is no valid UpperBound.
UpperBoundType_Temporary
The path is being validated, so currently it cannot be followed up to the end. The UpperBound gives a temporary limit, but it does not mean that the path is invalid. It will be validated further in the next frames.
UpperBoundType_PathLastNode
UpperBound is the last node of the path, so it can be followed up to the end.
UpperBoundType_ValidityUpperBound
The path cannot be followed up to its end. The UpperBound is the upper limit along the path, which is not the last node. In this case, you might want to stop following the current path and try recalculating the path. Alternatively, you might want to simulate a limited knowledge of the terrain on the part of your character by allowing the character to follow its current path until it gets within a certain radius of the UpperBound position, so it can see the blocking terrain, etc.