Find the point on navmesh closest to some FVector (not on navmesh)?

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;
}
1 Like