Branch: Binary
Build Version: 4.7.6-2513093
Description:
The ai seems to move towards the edge of nav meshes when their destination is on another unconnected nav mesh. Also if the destination is not on any nav mesh then the ai won’t move at all. This behavior seems inconsistent.
Repro Steps:
- Create project new project “PatialPathTest” from the “Top Down” template with no starter content
- In the level move the “NavigationMeshBoundsVolume” to y=2130
- Create a new “Nav Mesh Bounds Volume” instance named “NavMeshBoundsVolume” and place it in (x,y,z)=(-490,-1590,220)
- Create a new “Empty Actor” instance named “Target” and place it in (x,y,z)=(-490,-1590,120)
- Create a new “TopDownCharacter” instance named “TopDownCharacter2” and place it in (x,y,z)=(-490,240,216)
- Open “TopDownCharacter” blueprint to make following changes:
- Create new variable “TargetActor” of type “Actor”
- Make “TargetActor” variable “Editable” and “Expose on Spawn”
- Close “TopDownCharacter” blueprint
- On the level, set the “TargetActor” varible of the “TopDownCharacter2” instance to “Target”
- Create new “TopDownAIController” blueprint that subclasses the “AIController” blueprint
- Create graph in “TopDownAIController”:
- Close “TopDownAIController” blueprint
- On the level, set the “AI Controller Class” variable of the “TopDownCharacter2” instance to “TopDownAIController”
- Play Game
- Notice how “TopDownCharacter2” moves towards the left even though there is no possible path to get to “Target”
- Stop Game
- Move “Target” to (x,y,z)=(-180,-1590,120)
- Play Game
- Notice how “TopDownCharacter2” does not move because there is no possible path to get to “Target”
- Stop Game
- Move “Target” back to to (x,y,z)=(-490,-1590,120)
- Scale Cube2 to XScale=100 to make a wall along the entire walkable floor
- Play Game
- Notice how “TopDownCharacter2” moves towards the left even though there is no possible path to get to “Target” and there is now an impassable wall
Notes:
-
I looked into the source and found in cause of this behavior in AIController
-
AIController.cpp lines: (source version that comes with 4.7.6)
683: FPathFindingResult PathResult = NavSys->FindPathSync(Query);
684: if (PathResult.Result != ENavigationQueryResult::Error)
685: {
…
696: RequestID = RequestMove(PathResult.Path, Goal, AcceptanceRadius, bStopOnOverlap, CustomData);
697: } -
FindPathSync will find path with “DT_PARTIAL_RESULT” aka partial path and FindPathSync will return ENavigationQueryResult::Fail based on the code below. But request move will be made as long as PathResult is not Error, regardless of if it’s Success or Fail. So “TopDownCharacter2” will move.
-
Conversion from Detour path status to ENavigationQueryResult:
dtStatusSucceed(Status) ? (dtStatusDetail(Status, DT_PARTIAL_RESULT) ?
ENavigationQueryResult::Fail
: ENavigationQueryResult::Success)
: (dtStatusDetail(Status, DT_INVALID_PARAM) ?
ENavigationQueryResult::Error
: ENavigationQueryResult::Fail);