Ok, I think I got it. Here’s the code if anyone else looks for this):
float GetPathCost(UNavigationPath* path)
{
// in some cases GetPathCost returns 0, so using len if that happens.
float cost = path->GetPathCost();
if (cost == 0)
cost = path->GetPathLength();;
return cost;
}
void GetPathSubpoints(UNavigationPath* path, TArray<FVector>& subPoints)
{
int minStepAmount = 100;
for (int i = 0; i < path->PathPoints.Num() - 1; i++)
{
FVector pathDir = path->PathPoints[i + 1] - path->PathPoints[i];
float len = pathDir.Size();
int numSubPoints = len / minStepAmount;
for (int z = 0; z < numSubPoints; z++)
{
float t = (float)z / (float)numSubPoints;
FVector location = path->PathPoints[i] + pathDir * t;
subPoints.Add(location);
}
}
subPoints.Add(path->PathPoints[path->PathPoints.Num() - 1]);
}
TArray<UNavigationPath*> FindPathAndFitToActionPoints(UWorld* world, const FVector& start, const FVector& end, int ap )
{
TArray<UNavigationPath*> navPathArray;
UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(world);
// get the desired path and store in navPath array.
auto path = NavSys->FindPathToLocationSynchronously(world, start, end);
navPathArray.Add(path);
float cost = GetPathCost(path);
int minStepAmount = 100;
int costUnitsPerAP = 100;
int apForPath = cost / costUnitsPerAP;
// if we already have enough AP then just get out of here
if (ap >= apForPath)
return navPathArray;
float totalPathLen = 0;
TArray<FVector> subPoints;
GetPathSubpoints(path, subPoints);
subPoints.Add(path->PathPoints[path->PathPoints.Num()-1]);
UNavigationPath* prevPath = nullptr;
for (int i = 1; i < subPoints.Num(); i++)
{
path = NavSys->FindPathToLocationSynchronously(world, start, subPoints[i]);
float cost = GetPathCost(path);
if ( (cost / costUnitsPerAP) > ap)
break;
else prevPath = path;
}
navPathArray.Add(prevPath);
return navPathArray;
}