GetRandomReachablePointInRadius

The function NavSystem->GetRandomReachablePointInRadius doesn’t always work as expected. It works fine for me, if I use very small radii around the origin. If I use a larger radius, I get unreachable locations.

My levels and the NavMesh are built procedurally at runtime. At the moment there are often isolated areas. It’s like the destinations I am getting are chosen for a different origin than the one I passed to the function. A typical scenario from my current testing would be this:

  • There are isolated areas A,B,C,D,E
  • origins inside A get destinations inside A (like it should be)
  • origins inside B get destinations inside B (awesum)
  • origins inside C,D and E all get destinations (exclusively!!) inside A, where they can’t go

Is there a reason why this sort of thing would happen??

I double and triple checked all involved locations, origins and destinations, and there is no problem to be seen there. Unless GetRandomReachablePointInRadius requires something other than abolute world-locations, I have no idea what’s going on here, so I’m assuming it’s a bug.

Do I understand the question?

You have 5 different Vectors (A, B, C, D, E) and a function/event/macro to take one of them and finding a Get Reach. Point. in a radius around that point…

Points around A and B work as expected, but C-E all find points around A?

If that is the case, and you have a nav volume large enough to cover all of the areas, the problem is either in the method you are using to Select which vector to use, or in the storage of the vectors themselves.

Not quite. I have 5 (or so…) level-sections that are not connected by the NavMesh. There IS NavMesh there and it’s big enough, but the areas are not connected among each other. There are characters inside each section that randomly choose patrol points every time they reached the previous one, using their current location as origin for the function in question.

In this context I’m getting the described results.

This is really annoying. If I place characters on unreachable roofs and have them patrol random reachable locations, sometimes they will keep patrolling on that roof like they should, and sometimes they will get unreachable destinations. But it seems to depend mostly on what roof they are on, even though there is no obvious difference… The ones that are on the kind of roof that produces unreachable destinations, virtually never get destinations on THAT roof, but always in another (yet always the same) isolated nav-area, as if the origin was in that other area. ONLY IT’S NOT.

Ok, I just posted pictures and explanations, but apparently I have to post it all again, because it’s not here… One more time:

Here are some randomly generated rooms and ramps floating in the air. You can see that the NavMesh looks just fine:

These are some visualized origin-locations (yellow) on isolated roofs and corresponding “random reachable” destinations (cyan) that the NavSystem gave out for them, connected by a green line:

And here you can see the nonsense results for origins on one particular roof (which isn’t really different from the others):

The same thing is happening for many other areas as well. So what the hell is going on there?? It looks like the origin is off and therefore the destinations are from another “area”, but as you can see, that’s rather unlikely.

The different colors/ambience are just a result of a very fast day-night-cycle, by the way.

Sorry I’m so late getting back to this.

Having calls to GetRandomPoint do that sometimes… the specific cause is debatable and the solutions sometimes work, sometimes don’t.

The first(easiest) thing to try is to lift the nav volume for tht platform until it loses contact (no more green with show paths on). That will reset the path calculations when you drop it again.

If that doesn’t help, delete the nav volume for that section and replace it.

Make sure you are testing each nav volume with a random-roam-bot as well as your AI so you can tell which is the source of issues.

I’m not sure yet, but I think it’s possible that I only get this kind of error, when level generation has placed world geometry on top of each other (overlapping), although I don’t see a connection here, since the NavMesh looks good. Not sure, need to test more. Since I want to re-work the whole random level generation approach anyway, I haven’t fixed this overlap issue yet.

I have another (almost related) question though: How do I test, if a location can be reached from a certain origin? Not a random location, but a defined one. I need to check, if a move-order given through a mouse-click can be carried out or not.

My eyes aren’t that great, so I hadn’t seen any overlap in the images, but yes - that will break the navigation.

Nav volumes are searching for a “floor” on which to walk, if you have one floor over within the same volume it will break.

.

If you can make the volume “short” enough not to involve the higher floor it should fix the problem.


Testing to see if a location can be reached from another is pretty simple.

Make a blank Character class, and put something in it so you can see it (a sphere parented to the “Mesh” or similar.)

Attach a pin to BeginPlay → [Ai MoveTo] (the target location).
And click on the inherited Movement and adjust the Max Walk Speed down to 50.

Drop the dummy actor at the starting point and simulate.

If the path is valid it will move to the target.
Otherwise you will need to correct something (almost always the Nav Volume)

Well thanks, but I was rather hoping for some function that instantly tells me, whether a certain actor can reach a certain destination. Think of an RTS game where you order your units to move to the location you clicked on. The only way to perform this check that I currently know of is to order them to move there right away using MoveToLocation(…) and check the result. But then I have already sent them there, and I don’t always want to do that, but instead have them finish whatever important stuff they may already be doing first. So I’d rather just check if the order is valid, but not necessarily carry it out immediately.

I don’t know of a node to test the navigation paths without using them…

But the same test method works for that as well.

Make a character with nothing in it, (no visible components) and set its walk speed to 10,000, and whenever you need to test a path, Set Actor Location (the starting point) and AI MoveTo (the target point) - and test in in 0.2 seconds to see if it arrived.

It does seem there should be a method to test directly though. I’ll look into it and see if I can dig one up.

Code is fine, but building the engine is something I succesfully avoided so far. Good to know it’s been fixed, I will wait for 4.15 then. And that function from the thread was just what I as looking for. Thanks for the reply!

I am also experiencing strange behavior with GetRandomReachablePointInRadius in 4.16 Preview 3. I have a simple nav mesh which is reachable in the X and Y axis without any blocking actors or modifiers (totally plane navigation data).

GetRandomPointInNavigableRadius always returns a valid location, but
GetRandomReachablePointInRadius most of the time returns false even if it should do the same as the former function + check if the location is reachable (and it should be reachable because there is no blocking/collision/no holes in the navmesh).

137940-log.png

This is a code snippet from my a BTTask class:

if (NavigationSystem->GetRandomPointInNavigableRadius(CurrentLocation, 100.f, TargetLocation)) {
	UE_LOG(LogTemp, Warning, TEXT("GetRandomPointInNavigableRadius: %s"), *TargetLocation.Location.ToString());
};

if (NavigationSystem->GetRandomReachablePointInRadius(CurrentLocation, 100.f, TargetLocation)) {
	UE_LOG(LogTemp, Warning, TEXT("GetRandomReachablePointInRadius: %s"), *TargetLocation.Location.ToString());
	return EBTNodeResult::Succeeded;
};

UE_LOG(LogTemp, Error, TEXT("GetRandomReachablePointInRadius failed!"));
return EBTNodeResult::Failed;

I just tested with a larger radius parameter (100.f replaced by 500.f) and it seems the function returns true with high values more often.

If I’m not mistaken, this behaviour is caused by the ARecastNavMesh::GetRandomReachablePointInRadius function using the same radius for both, dtNavMeshQuery::findRandomPointAroundCircle and dtNavMeshQuery::findNearestPoly.

dtNavMeshQuery::findNearestPoly mustn’t be called with a large radius, as this function may (and will) return invalid results if the search range covers more than 128 polygons (see DetourNavMeshQuery.cpp).

Luckily ARecastNavMesh::GetRandomReachablePointInRadius is virtual, so it’s possible to work around this issue in project code, namely by using a custom NavMesh class inheriting from ARecastNavMesh, which then overrides GetRandomReachablePointInRadius and limits the value put into const float Extents[3]. (In order to interact with the navmesh data, one needs to add the module “Navmesh” to the project dependencies.)

Hey Dsine,

I have noticed the issue myself, but unfortunately at this time we are unable to allocate resources to looking into this matter. For the meantime I recommend using a higher radius to prevent the issue from occurring, or calling the function a few times and discarding the undesired results.

Have a great day

Hey Dsine,

I have noticed the issue myself, but unfortunately at this time we are unable to allocate resources to looking into this matter. For the meantime I recommend using a higher radius to prevent the issue from occurring, or calling the function a few times and discarding the undesired results.

Have a great day

Hey Maxpower42 & Looniper,

If you’re looking for a way to test if a point is reachable by a pawn, I’d recommend taking a look at the thread linked below, if you’re working in C++, that is. I don’t know of a way to do this in blueprint at the current time, so I’d definitely recommend giving that solution a try

As far as the function returning invalid values goes, this was a known bug that has been resolved as of 4.15:

If you’re using a source build, you can merge the fix commit in now and it should resolve the issue, but feel free to let me know if it still occurs.

Let me know if that helps and if you have any further questions regarding this.

Hey Maxpower42 & Looniper,

If you’re looking for a way to test if a point is reachable by a pawn, I’d recommend taking a look at the thread linked below, if you’re working in C++, that is. I don’t know of a way to do this in blueprint at the current time, so I’d definitely recommend giving that solution a try

As far as the function returning invalid values goes, this was a known bug that has been resolved as of 4.15:

If you’re using a source build, you can merge the fix commit in now and it should resolve the issue, but feel free to let me know if it still occurs.

Let me know if that helps and if you have any further questions regarding this.