Hello
I have a problem, with the AI Task MoveTo within the blackboard AI scripting module.
I think this problem is more universal, not just the problem of the task, but you’re the one who decides it.
I have a basic waypoint system, I place a route on the map, and let the AI move between them.
The problem is, at one certain point( or certain area on my map ), the AI stands on one of the waypoints, and waits.
Seems like the MoveTo does not accept the point, and time-outs after a while, claiming the path is blocked.
Looked into the code, and I am not sure that it’s intentional. Here is how I see it.
I have the waypoint coordinate( at first I used just world coordinates, then changed) projected on the NavMesh.
bool AMyAIRoute::GetPositionOnNavMesh( int32 Index, FVector& Position, AController* Controller ) const
{
if( !GetAbsolutePointPosition( Index, Position ) )
{
return false;
}
UNavigationSystem* NavSys = UNavigationSystem::GetCurrent( GetWorld() );
const FNavAgentProperties& AgentProps = Controller->GetNavAgentPropertiesRef();
FNavLocation ProjectedLocation;
FVector Extent( 200.0f, 200.0f, 200.0f );
if( NavSys && !NavSys->ProjectPointToNavigation( Position, ProjectedLocation, Extent, &AgentProps ) )
{
return false;
}
Position = ProjectedLocation.Location;
return true;
}
Where the Controller is the controller of the pawn trying to move on the way.
After some debugging, I found out that the MoveTo location uses UPathFollowingComponent::HasReached function to check if the destination is reached, which returns false, because the height difference is too big.
const float ZDiff = FMath::Abs(ToGoal.Z);
const float UseHeight = GoalHalfHeight + (AgentHalfHeight * MinAgentHalfHeightPct);
if (ZDiff > UseHeight)
{
return false;
}
The AgentLocation.Z is around 2, the GoalLocation.Z is 35. Agent height is 32, so the half height is 18.
Possible problems:
- When getting the agent position, why does it use the feet location?( HasReached function has this line: const FVector CurrentLocation = MovementComp ? MovementComp->GetActorFeetLocation() : FVector::ZeroVector; ) Of course it will be wrong if the navmesh is higher than the feet of my character.
- Why doesn’t it use the acceptance radius? No matter how high I set it, it always checks the height difference, and returns fail, if it doesn’t meet.
- Also, why is my navmesh is that high? I mean, it’s fine while it’s still within my agent height, but doesn’t really makes sense that it’s at 30 height while my characters feet is at 2…