x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Find path up to a max cost

Hi,

Is it possible to somehow pass a "max cost" to FindPathToLocationSynchronously (or some other similar function) so that it cuts off the path once the cost is reached (even if the actual destination hasn't been reached). Basically I m trying to implement action-point style movement and would the path to abort when it reaches character's AP value.

Product Version: UE 4.7
Tags:
more ▼

asked Jul 13 '15 at 04:39 PM in C++ Programming

avatar image

tardygrade
99 8 12 18

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

There's no functionality that will give you what you need out of the box. I suggest just finding paths and then cutting down the result.

Cheers,

--mieszko

more ▼

answered Jul 14 '15 at 09:16 AM

avatar image

MieszkoZ STAFF
7.3k 225 57 413

avatar image tardygrade Jul 14 '15 at 10:23 AM

Thanks for your reply. One more question - i can't just simply cut by percentage , right ? For example - if I find out that leftover AP (let's say 1000) to path cost (let's say 2000) ratio is 50%, I can't just cut the path at its 50% of length, since the cost is not necessarily linear (due to possibly varying area costs along the path length). For example it could be that the first 50% of the path cost only 500 but the remaining 50% of the path cost 1500 due to the area cost. So I 'm gonna have to write some recursive function that keeps adjusting the path end up and down until it reaches the correct value right ? For example - the function would try to first adjust the end to 50% and requery. Then it would realize that only costs 500 AP, but the char had 1000AP and wanted to go further. Then the function would query with end set at 75% of the original path and check that for cost. If the cost is still lower it would query with 87.5% , if higher it would query with 62.5%, and so on until it gets close enough. Is that basically what I'd need to do ?

avatar image MieszkoZ STAFF Jul 14 '15 at 12:37 PM

Yeah, you need to implement this yourself. I'd suggest using a for-loop though, starting from the beginning of the path and summing up subsequent steps' cost. Mind that if you're string-pulling the path (which is the default behavior) you may end up with very long path segments, which would affect your cost calculations, and you'll need to add intermediate points along the path to properly, precisely calculate path's AP cost.

avatar image tardygrade Jul 14 '15 at 03:13 PM

I think I got it. Thanks !

I posted the solution below if anyone has a similar question.

Btw - while on this topic. Any ideas why getpathcost returns 0 sometimes. I did some brief debugging and looks to be returning 0 if the final path is in the same segment or somethign along those lines. What's the reasoning behind that ?

avatar image MieszkoZ STAFF Jul 14 '15 at 04:17 PM

It's a bug I believe has been fixed for 4.8.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

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;
     }
     
more ▼

answered Jul 14 '15 at 03:11 PM

avatar image

tardygrade
99 8 12 18

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question