Checking if a destination is on the Grid Graph

Hi So I’m pretty new to AStar and have a couple of questions - I did search a bit through the forums but didn’t see the answers there.

So I have a simple AI Wander behavior setup so that my entity will wander within a circle, picking a random point, moving there, pausing, and repeating that.

Something like:
void Start()
{
basePosition = transform.position;
ChooseNextDestination();
}

void ChooseNextDestination()
{
    Vector2 randOffset = Random.insideUnitCircle * wanderRadius;
    nextDestination = basePosition + new Vector3(randOffset.x, transform.position.y, randOffset.y);
}

I’m looking to incorporate this into AStar, so that I can check if nextDestination is actually on the Grid Graph, if it isn’t I will recheck until it is.

I’d also like to know how to check (if “nextDestination” is infact on the Grid Graph) - how long the path distance would be to get there. This is in case the mob is by a wall or something and picks a point on the other side of the wall which is pathable, but would take a long time to get there, in that case I’d run ChooseNextDestination() again.

If this has been answered somewhere I apologize in advance :slight_smile:

It sounds like you simply want to know how long it would take to get to a given point.
That can be got easily by the totalPathLength (I think it was called that, see docs) on the Path class. So when you get the path back, you simply check if the length was short enough, if it wasn’t, you repick the point, otherwise start following the path.

Thanks, that answers the path length question! What happens if the point is generated off the grid graph? for example the Red dot on the image?

Oh hmm… maybe if it was off the Grid it would make vectorPath null and GetTotalLength is positive infinity? If that’s the case then I guess that solves that problem too!

float GetTotalLength ( )
Total Length of the path.

Calculates the total length of the vectorPath. Cache this rather than call this function every time since it will calculate the length every time, not just return a cached value.

Returns
Total length of vectorPath, if vectorPath is null positive infinity is returned.

http://arongranberg.com/astar/docs/class_pathfinding_1_1_path.php#a1076ed6812e2b4f98dca64b74dabae5d

What if I wanted a separate function that returns true or false when given a Vector3 point as to weather or not that point is on a grid?

I also noticed that even though the destination point is off the grid, I still somehow don’t get positive infinite when using GetTotalLength().

For some distances, it will choose the closest valid node on the graph it can find. You can set the exact distance in A* Inspector -> Settings -> Pathfinding -> Max Nearest Node Distance. If the distance to the closest node is greater than that, the path will fail and GetTotalLength will return positive infinity (also mypath.vectorPath will be null).

To check if a specific point is outside the graph (or more correctly, within the above mentioned distance to the graph). You can use the GetNearest function.
NNConstraint nn = NNConstraint.None; nn.constrainDistance = true; if (AstarPath.active.GetNearest(somePosition, nn).node != null) { //In range }
The above will only check distance to the graph. But maybe it is more relevant to check the distance to the closest ‘valid’ node on the graph (i.e, the node must also be walkable).
if (AstarPath.active.GetNearest(somePosition, NNConstraint.Default).node != null) { // In range }

I have a similar goal I’m trying to accomplish with the grid graph. I’m procedurally generating my isometric tilemaps and then manually updating the grid graph based on the walkable tiles in the tilemap. As the player moves new chunks of the map are rendered and the grid graph is updated correspondingly. Upon the grid graph being updated I fire a callback to which the enemy spawner subscribes. I’m trying to disable any enemies outside of the grid graph, but the code above doesn’t seem to do the trick. Here’s my implementation:

            for (int i = 0; i < activeEnemies.Count(); i++)
            {
                var enemy = activeEnemies[i];

                NNConstraint constraint = NNConstraint.None;
                //constraint.constrainWalkability = true;
                constraint.constrainDistance = true;
                var node = graph.GetNearest(enemy.transform.position, constraint).node;

                if (node == null || Vector3.Distance(enemy.transform.position, (Vector3) node.position) > 0.05f)
                {
                    enemy.SetActive(false);
                    activeEnemies.Remove(enemy);
                }
             }

Unfortunately, most of the enemies who are no longer on the grid graph are not being removed. Any tips for another approach to check whether a vector3 is inside the grid graph?

Note: I also set the max nearest node distance to .001.

Hi

Hmm, that code should be working. A more robust and efficient implementation is:

for (int i = activeEnemies.Count - 1; i >= 0; i--) {
    var enemy = activeEnemies[i];
    var nn = graph.GetNearest(enemy.transform.position, NNConstraint.None);
    if (nn.node == null || (nn.position - enemy.transform.position).sqrMagnitude > 0.1*0.1) {
        enemy.SetActive(false);
        activeEnemies.RemoveAt(i);
     }
}