UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
dtPathCorridor Class Reference

#include <DetourPathCorridor.h>

Public Member Functions

NAVMESH_API dtPathCorridor ()
 
NAVMESH_API ~dtPathCorridor ()
 
NAVMESH_API bool init (const int maxPath)
 
NAVMESH_API void reset (dtPolyRef ref, const dtReal *pos)
 
NAVMESH_API int findCorners (dtReal *cornerVerts, unsigned char *cornerFlags, dtPolyRef *cornerPolys, const int maxCorners, dtNavMeshQuery *navquery, const dtQueryFilter *filter, dtReal pathOffsetDistance, dtReal earlyReachDistance, bool bAllowEarlyReach=true)
 
NAVMESH_API bool optimizePathVisibility (const dtReal *next, const dtReal pathOptimizationRange, dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API bool optimizePathTopology (dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API bool moveOverOffmeshConnection (dtPolyRef offMeshConRef, dtPolyRef *refs, const dtReal *agentPos, dtReal *startPos, dtReal *endPos, dtNavMeshQuery *navquery)
 
NAVMESH_API bool canMoveOverOffmeshConnection (dtPolyRef offMeshConRef, dtPolyRef *refs, const dtReal *agentPos, dtReal *startPos, dtReal *endPos, dtNavMeshQuery *navquery) const
 [UE] check if offmesh connection can be traversed, but don't modify corridor yet
 
NAVMESH_API void pruneOffmeshConenction (dtPolyRef offMeshConRef)
 [UE] remove offmesh connection from corridor
 
NAVMESH_API bool fixPathStart (dtPolyRef safeRef, const dtReal *safePos)
 
NAVMESH_API bool trimInvalidPath (dtPolyRef safeRef, const dtReal *safePos, dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API bool isValid (const int maxLookAhead, dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API bool movePosition (const dtReal *npos, dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API void moveTargetPosition (const dtReal *npos, dtNavMeshQuery *navquery, const dtQueryFilter *filter)
 
NAVMESH_API void setCorridor (const dtReal *target, const dtPolyRef *polys, const int npath)
 
const dtRealgetPos () const
 
const dtRealgetTarget () const
 
dtPolyRef getFirstPoly () const
 
dtPolyRef getLastPoly () const
 
const dtPolyRefgetPath () const
 
int getPathCount () const
 
void setEarlyReachTest (bool enable)
 
dtReal getSegmentAngle () const
 
const dtRealgetNextFixedCorner () const
 
const dtRealgetNextFixedCorner2 () const
 
bool hasNextFixedCorner () const
 
bool hasNextFixedCorner2 () const
 

Detailed Description

Represents a dynamic polygon corridor used to plan agent movement. ,

The corridor is loaded with a path, usually obtained from a dtNavMeshQuery::findPath() query. The corridor is then used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate agent locomotion.

Example of a common use case:

  1. Construct the corridor object and call init() to allocate its path buffer.
  2. Obtain a path from a dtNavMeshQuery object.
  3. Use reset() to set the agent's current position. (At the beginning of the path.)
  4. Use setCorridor() to load the path and target.
  5. Use findCorners() to plan movement. (This handles dynamic path straightening.)
  6. Use movePosition() to feed agent movement back into the corridor. (The corridor will automatically adjust as needed.)
  7. If the target is moving, use moveTargetPosition() to update the end of the corridor. (The corridor will automatically adjust as needed.)
  8. Repeat the previous 3 steps to continue to move the agent.

The corridor position and target are always constrained to the navigation mesh.

One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path. This class uses local mesh queries to detect and update the corridor as needed to handle these types of issues.

The fact that local mesh queries are used to move the position and target locations results in two beahviors that need to be considered:

Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further the target is moved from its original location, and the further the position is moved outside the original corridor, the more likely the path will become non-optimal. This issue can be addressed by periodically running the optimizePathTopology() and optimizePathVisibility() methods.

All local mesh queries have distance limitations. (Review the dtNavMeshQuery methods for details.) So the most accurate use case is to move the position and target in small increments. If a large increment is used, then the corridor may not be able to accurately find the new location. Because of this limiation, if a position is moved in a large increment, then compare the desired and resulting polygon references. If the two do not match, then path replanning may be needed. E.g. If you move the target, check getLastPoly() to see if it is the expected polygon.

Constructor & Destructor Documentation

◆ dtPathCorridor()

dtPathCorridor::dtPathCorridor ( )

◆ ~dtPathCorridor()

dtPathCorridor::~dtPathCorridor ( )

Member Function Documentation

◆ canMoveOverOffmeshConnection()

bool dtPathCorridor::canMoveOverOffmeshConnection ( dtPolyRef  offMeshConRef,
dtPolyRef refs,
const dtReal agentPos,
dtReal startPos,
dtReal endPos,
dtNavMeshQuery navquery 
) const

[UE] check if offmesh connection can be traversed, but don't modify corridor yet

◆ findCorners()

int dtPathCorridor::findCorners ( dtReal cornerVerts,
unsigned char cornerFlags,
dtPolyRef cornerPolys,
const int  maxCorners,
dtNavMeshQuery navquery,
const dtQueryFilter filter,
dtReal  pathOffsetDistance,
dtReal  earlyReachDistance,
bool  bAllowEarlyReach = true 
)

Finds the corners in the corridor from the position toward the target. (The straightened path.)

Parameters
[out]cornerVertsThe corner vertices. [(x, y, z) * cornerCount] [Size: <= maxCorners]
[out]cornerFlagsThe flag for each corner. [(flag) * cornerCount] [Size: <= maxCorners]
[out]cornerPolysThe polygon reference for each corner. [(polyRef) * cornerCount] [Size: <= maxCorners]
[in]maxCornersThe maximum number of corners the buffers can hold.
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.
[in]pathOffsetDistance[UE] Radius for path offsetting
[in]earlyReachDistance[UE] Radius for early reach detection
[in]bAllowEarlyReach[UE] Check if corner skipping for EarlyReachTest is available now
Returns
The number of corners returned in the corner buffers. [0 <= value <= maxCorners]

This is the function used to plan local movement within the corridor. One or more corners can be detected in order to plan movement. It performs essentially the same function as dtNavMeshQuery::findStraightPath.

Due to internal optimizations, the maximum number of corners returned will be (maxCorners - 1) For example: If the buffers are sized to hold 10 corners, the function will never return more than 9 corners. So if 10 corners are needed, the buffers should be sized for 11 corners.

If the target is within range, it will be the last corner and have a polygon reference id of zero.

◆ fixPathStart()

bool dtPathCorridor::fixPathStart ( dtPolyRef  safeRef,
const dtReal safePos 
)

◆ getFirstPoly()

dtPolyRef dtPathCorridor::getFirstPoly ( ) const
inline

The polygon reference id of the first polygon in the corridor, the polygon containing the position.

Returns
The polygon reference id of the first polygon in the corridor. (Or zero if there is no path.)

◆ getLastPoly()

dtPolyRef dtPathCorridor::getLastPoly ( ) const
inline

The polygon reference id of the last polygon in the corridor, the polygon containing the target.

Returns
The polygon reference id of the last polygon in the corridor. (Or zero if there is no path.)

◆ getNextFixedCorner()

const dtReal * dtPathCorridor::getNextFixedCorner ( ) const
inline

◆ getNextFixedCorner2()

const dtReal * dtPathCorridor::getNextFixedCorner2 ( ) const
inline

◆ getPath()

const dtPolyRef * dtPathCorridor::getPath ( ) const
inline

The corridor's path.

Returns
The corridor's path. [(polyRef) * getPathCount()]

◆ getPathCount()

int dtPathCorridor::getPathCount ( ) const
inline

The number of polygons in the current corridor path.

Returns
The number of polygons in the current corridor path.

◆ getPos()

const dtReal * dtPathCorridor::getPos ( ) const
inline

Gets the current position within the corridor. (In the first polygon.)

Returns
The current position within the corridor.

◆ getSegmentAngle()

dtReal dtPathCorridor::getSegmentAngle ( ) const
inline

◆ getTarget()

const dtReal * dtPathCorridor::getTarget ( ) const
inline

Gets the current target within the corridor. (In the last polygon.)

Returns
The current target within the corridor.

◆ hasNextFixedCorner()

bool dtPathCorridor::hasNextFixedCorner ( ) const
inline

◆ hasNextFixedCorner2()

bool dtPathCorridor::hasNextFixedCorner2 ( ) const
inline

◆ init()

bool dtPathCorridor::init ( const int  maxPath)

Allocates the corridor's path buffer.

Parameters
[in]maxPathThe maximum path size the corridor can handle.
Returns
True if the initialization succeeded.
Warning
Cannot be called more than once.

◆ isValid()

bool dtPathCorridor::isValid ( const int  maxLookAhead,
dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

Checks the current corridor path to see if its polygon references remain valid.

Parameters
[in]maxLookAheadThe number of polygons from the beginning of the corridor to search.
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.

The path can be invalidated if there are structural changes to the underlying navigation mesh, or the state of a polygon within the path changes resulting in it being filtered out. (E.g. An exclusion or inclusion flag changes.)

◆ moveOverOffmeshConnection()

bool dtPathCorridor::moveOverOffmeshConnection ( dtPolyRef  offMeshConRef,
dtPolyRef refs,
const dtReal agentPos,
dtReal startPos,
dtReal endPos,
dtNavMeshQuery navquery 
)

◆ movePosition()

bool dtPathCorridor::movePosition ( const dtReal npos,
dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

Moves the position from the current location to the desired location, adjusting the corridor as needed to reflect the change.

Parameters
[in]nposThe desired new position. [(x, y, z)]
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.

Behavior:

  • The movement is constrained to the surface of the navigation mesh.
  • The corridor is automatically adjusted (shorted or lengthened) in order to remain valid.
  • The new position will be located in the adjusted corridor's first polygon.

The expected use case is that the desired position will be 'near' the current corridor. What is considered 'near' depends on local polygon density, query search extents, etc.

The resulting position will differ from the desired position if the desired position is not on the navigation mesh, or it can't be reached using a local search.

◆ moveTargetPosition()

void dtPathCorridor::moveTargetPosition ( const dtReal npos,
dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

Moves the target from the curent location to the desired location, adjusting the corridor as needed to reflect the change.

Parameters
[in]nposThe desired new target position. [(x, y, z)]
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.

Behavior:

  • The movement is constrained to the surface of the navigation mesh.
  • The corridor is automatically adjusted (shorted or lengthened) in order to remain valid.
  • The new target will be located in the adjusted corridor's last polygon.

The expected use case is that the desired target will be 'near' the current corridor. What is considered 'near' depends on local polygon density, query search extents, etc.

The resulting target will differ from the desired target if the desired target is not on the navigation mesh, or it can't be reached using a local search.

◆ optimizePathTopology()

bool dtPathCorridor::optimizePathTopology ( dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

Attempts to optimize the path using a local area search. (Partial replanning.)

Parameters
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.

Inaccurate locomotion or dynamic obstacle avoidance can force the agent position significantly outside the original corridor. Over time this can result in the formation of a non-optimal corridor. This function will use a local area path search to try to re-optimize the corridor.

The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of the call to match the needs to the agent.

◆ optimizePathVisibility()

bool dtPathCorridor::optimizePathVisibility ( const dtReal next,
const dtReal  pathOptimizationRange,
dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

Attempts to optimize the path if the specified point is visible from the current position.

Parameters
[in]nextThe point to search toward. [(x, y, z])
[in]pathOptimizationRangeThe maximum range to search. [Limit: > 0]
[in]navqueryThe query object used to build the corridor.
[in]filterThe filter to apply to the operation.

Inaccurate locomotion or dynamic obstacle avoidance can force the argent position significantly outside the original corridor. Over time this can result in the formation of a non-optimal corridor. Non-optimal paths can also form near the corners of tiles.

This function uses an efficient local visibility search to try to optimize the corridor between the current position and next.

The corridor will change only if next is visible from the current position and moving directly toward the point is better than following the existing path.

The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of the call to match the needs to the agent.

This function is not suitable for long distance searches.

◆ pruneOffmeshConenction()

void dtPathCorridor::pruneOffmeshConenction ( dtPolyRef  offMeshConRef)

[UE] remove offmesh connection from corridor

◆ reset()

void dtPathCorridor::reset ( dtPolyRef  ref,
const dtReal pos 
)

Resets the path corridor to the specified position.

Parameters
[in]refThe polygon reference containing the position.
[in]posThe new position in the corridor. [(x, y, z)]

Essentially, the corridor is set of one polygon in size with the target equal to the position.

◆ setCorridor()

void dtPathCorridor::setCorridor ( const dtReal target,
const dtPolyRef path,
const int  npath 
)

Loads a new path and target into the corridor.

Parameters
[in]targetThe target location within the last polygon of the path. [(x, y, z)]
[in]pathThe path corridor. [(polyRef) * npolys]
[in]npathThe number of polygons in the path.

The current corridor position is expected to be within the first polygon in the path. The target is expected to be in the last polygon.

Warning
The size of the path must not exceed the size of corridor's path buffer set during init().

◆ setEarlyReachTest()

void dtPathCorridor::setEarlyReachTest ( bool  enable)
inline

◆ trimInvalidPath()

bool dtPathCorridor::trimInvalidPath ( dtPolyRef  safeRef,
const dtReal safePos,
dtNavMeshQuery navquery,
const dtQueryFilter filter 
)

The documentation for this class was generated from the following files: