Detect blocked path for multiple graph sizes

I have dynamic building which does graph updates at runtime and I have 3 different graphs for different sizes of enemies.

For detecting blocked paths I’m using IsPathPossible, eg:

GraphNode node1 = AstarPath.active.GetNearest(point1, NNConstraint.Default).node;
GraphNode node2 = AstarPath.active.GetNearest(point2, NNConstraint.Default).node;

if (PathUtilities.IsPathPossible(node1, node2)) {
    // Yay, there is a path between those two nodes
}

That works for small enemies when their path is completely blocked. But for larger enemies they get blocked by there only being small gaps. This seems to pass the IsPathPossible check despite the agent not having wide enough gaps in their graph to get through.

For example, this shows the agent has stopped short of the target (the little truck) and shows then having ReachedEndOfPath. The navmesh showing is for the smaller size enemies.

The large agent’s RichAI:

This is what the large agent graph looks like, clearly there is no path to the target (little truck).

How can I detect blocked paths for different size agents on different recast graphs?

Also, why is the large agent showing as ReachedEndOfPath when they are still far from their target?

Hi

You will have to do the IsPathPossible check for each graph.
The NNConstraint has a graphMask that you can use to specify which graph you are interested in.

for (int i =0 ; i < 2; i++) {
    var nn = NNConstraint.Default;
    nn.graphMask = 1 << i; // Only search the ith graph
    GraphNode node1 = AstarPath.active.GetNearest(point1, nn).node;
    GraphNode node2 = AstarPath.active.GetNearest(point2, nn).node;
    if (!PathUtilities.IsPathPossible(node1, node2)) {
        // ...
    }
}

So I had this working fine but then I had to clean up an issue where I needed to navmeshcut around the target object.

For example, my enemies are running up to a truck to do melee attacks.
I was using a single endReachedDistance before but that doesn’t look right as the enemies stop in a circle around a rectangular target, when they instead need to get up close on all sides. So I added a navmesh graph update around my truck, that works fine.
But now my IsPathPossible checks all fail because they can’t make it all the way to the truck transform position. That makes sense but is there any way to add a distance buffer to the end target for IsPathPossible?

I guess I was assuming GetNearest would at least return the nearest node that is valid, closest to the target transform.
I do see some distance properties in NNConstraint but it isn’t clear to me if they will do what I’m looking for.

The enemies stop on the edge of the navmesh closest to the target as expected, and will only have reachedEndOfPath, not reachedDestination which is also fine.

Is the only way to solve this to add target points around my truck that will actually be on the navmesh, and have enemies target those for moveTo targets?
Something like this?
image

Hi

You can do:

    var nn = NNConstraint.Default;
    nn.graphMask = 1 << i; // Only search the ith graph
    GraphNode node1 = AstarPath.active.GetNearest(point1, nn).node;
    nn.constrainArea = true;
    nn.area = node1.Area;
    GraphNode node2 = AstarPath.active.GetNearest(point2, nn).node;

This will constrain node2 to be reachable from node1.
Currently, it looks like your vehicle has a navmesh inside of it, so node2 will be inside the vehicle, and the IsPathPossible check will fail. If you use the beta version, and you attach a convex collider to the vehicle, and you are rasterizing colliders in the recast graph, then the collider will be treated as solid and no navmesh will be generated inside of it.

I’m not sure that’s doing what I need.

First, yes I was using rasterize mesh on the graph mainly just because that was the default setting, but I’ve changed over to using colliders to eliminate that internal mesh/navmesh problem.

If I change my code over to use the constraint you suggested IsPathPossible never fails (at least in my tests so far) which isn’t right.

Here’s my code with the constraint:

                GraphNode node1 = AstarPath.active.GetNearest(enemy.cachedTransform.position, nn).node;
                nn.constrainArea = true;
                nn.area = (int)node1.Area;
                GraphNode node2 = AstarPath.active.GetNearest(roverCheckPoint.position, nn).node;

In this example I’ve built walls around the truck, the navmesh looks to be cut correctly with no interior mesh.

So I think for now I’ll drop using the constraint because IsPathPossible seems to work better now that I’m using colliders for the graph updates.

Is there an easy way to tell what index a particular tile is in the scene? I’m just wondering how I could visualize the node tile indexes that IsPathPossible is using.

1 Like

It’s not exposed, but

var tileIndex = ((node as TriangleMeshNode).v0 >>  NavmeshBase.TileIndexOffset) & NavmeshBase.TileIndexMask;

should do it, I think.