In this lesson, you will learn how to shift heavy pathfinding calculations away from the Game Thread by implementing asynchronous pathfinding requests to keep your frame rates steady.
The Problem with Synchronous Pathfinding
When an AI agent requests a path using standard functions like FindPathToLocationSynchronously, the game engine halts execution on the main thread until the path is fully computed. In large, open worlds or with dozens of agents querying simultaneously, this causes "hiccups" or frame drops. If the NavMesh is complex or the distance is significant, this blocking behavior becomes a bottleneck that destroys smooth player experience.
Moving to Asynchronous Requests
To maintain performance, we utilize the UNavigationSystemV1::FindPathAsync method. Instead of waiting for a result, we fire a request and provide a callback (a delegate) that triggers once the pathing calculation is finished on a background thread.
Here is a simplified example of how you would structure an asynchronous request in your AI Controller:
void AMyAIController::RequestAsyncPath(FVector Destination)
{
UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
FAISystem::FDescribePathRequest Request;
Request.PathQuery.StartLocation = GetPawn()->GetActorLocation();
Request.PathQuery.EndLocation = Destination;
// Bind the callback function
NavSys->FindPathAsync(NavData, Request, FNavPathQueryDelegate::CreateUObject(this, &AMyAIController::OnPathFound));
}
void AMyAIController::OnPathFound(uint32 PathID, ENavigationQueryResult::Type Result, FNavPathSharedPtr Path)
{
if (Result == ENavigationQueryResult::Success)
{
// Proceed with movement using the successfully calculated path
MoveAlongPath(Path);
}
}
By decoupling the request from the response, the Game Thread remains free to process input, rendering, and gameplay logic while the Navigation System handles the geometry heavy-lifting in the background. Note that because this is asynchronous, your AI must be prepared to handle "waiting" states, such as playing a "thinking" animation or patrol idle, until the OnPathFound delegate is fired.
Key Takeaway: Always prefer asynchronous navigation queries over synchronous calls when dealing with long-distance paths or high agent counts to prevent stalling the main game loop.