Looking at GetRandomReachablePointInRadius as an example, this should be the best way to do it I think:
FVector AAI_Controller_Human::GetClosestLocationOnNavMesh(const FVector Point)
{
if (AGame::Instance() == nullptr)
return FVector::Zero();
if (ANavigation::Instance()->RecastMesh == nullptr)
return FVector::Zero();
//UNavigationSystemV1* Nav = UNavigationSystemV1::GetCurrent(GetWorld());
const UE::Math::TVector4<double> a = UE::Math::TVector4<double>(Point.X - 1000, Point.Y - 1000, Point.Z - 1000, 0);
const UE::Math::TVector4<double> b = UE::Math::TVector4<double>(Point.X + 1000, Point.Y + 1000, Point.Z + 1000, 0);
const FBox Box = FBox(a, b);
TArray<FNavPoly> Polies;
ANavigation::Instance()->RecastMesh->GetPolysInBox(Box, Polies);
float ClosestLength = std::numeric_limits<double>::max();
FVector ClosestPoint = FVector::Zero();
for (int i = 0; i < Polies.Num(); i++)
{
FVector PointOnPoly;
ANavigation::Instance()->RecastMesh->GetClosestPointOnPoly(Polies[i].Ref, Point, PointOnPoly);
const float Length = (PointOnPoly - Point).SquaredLength();
if (Length < ClosestLength)
{
ClosestLength = Length;
ClosestPoint = PointOnPoly;
}
}
return ClosestPoint;
}