Can't change constraints on ConstantPath

is there a way to do this?

ConstantPath allPath = ConstantPath.Construct (transform.position, 30000, OnPathComplete);
allPath.nnConstraint = NNConstraint.None;
thisSeeker.StartPath (allPath);

This just returns a normally constrained ConstantPath.

Hi

That should work perfectly fine (checked the sourcecode as well and I cannot see any obvious problems).

But just so you know setting the nnConstraint to NNConstraint.Node will just make it possible for it to start from unwalkable nodes, which isn’t really useful in most cases. Is that really what you are trying to accomplish?

Here’s what I’m trying to do:

Lets say you have a hero sitting on a grid at position [10,4], and he can move 2 squares.

I want to call ConstantPath twice, once to get all the walkable nodes, so i can color the tiles and let the user know where he can walk. (This works fine)
The second time, I want to get ALL the nodes, including the unwalkable ones, then call .Except on the two arrays, and find the unwalkable nodes, so i can see if an enemy is standing there. Then I can color those tiles a different color.

While doing the tests, I’ve run into a crazier problem: When I call ConstantPath twice, the second path isn’t starting from the same node. So for example, If I run the following code:

ConstantPath walkablePath = ConstantPath.Construct (transform.position, 1000, OnPathComplete);
seeker.StartPath (walkablePath);
yield return walkablePath.WaitForPath();

walkablePath = ConstantPath.Construct (transform.position, 1000, OnPathComplete);
walkablePath.nnConstraint.constrainWalkability = true;
walkablePath.nnConstraint.walkable = false;
seeker.StartPath (walkablePath);
yield return walkablePath.WaitForPath();

Just for the sake of this test - I run a 1000 G score, and I get two different outputs:
Graph1 position - [10,4]
Graph2 position - [10,5]
Even though i should just be getting the same tile back (the starting tile).

This happens regardless of wether or not i adjust the constraints, it happens regardless of wether or not i use a different variable and assign/create a 2nd ConstantPath.

Thoughts?

Hi

Hm. Is your unit moving while you do that? Because yield return will wait until the path is complete (which might be a few frames later).

You could create a ConstantPath with a huge range, but there is a better way. You can simply call

var node = AstarPath.active.GetNearest (transform.position, NNConstraint.Default).node;
var allReachableNodes = PathUtilities.GetReachableNodes (node);

See http://arongranberg.com/astar/docs/class_pathfinding_1_1_path_utilities.php#a4b4d32e1cdb83bf4fde98980e16afdc7

[EDIT]
Nvm. That will not give you the unwalkable nodes.
To do that you can do

var allNodes = new List<GraphNode>();
AstarPath.active.astarData.graphs[0].GetNodes(node => {
    allNodes.Add(node);
    return true;
});

The ConstantPath will only traverse walkable nodes regardless of what you do. The NNConstraint is only used for the start and end nodes (this applies to all paths).

[EDIT2]
Also. You are missing a StartCoroutine call when you use WaitForPath.
From the docs:

//In an IEnumerator function
var p = Seeker.StartPath (transform.position, transform.position + Vector3.forward * 10);
yield return StartCoroutine (p.WaitForPath ());
//The path is calculated at this stage

Is your unit moving while you do that?

Nope

var allReachableNodes = PathUtilities.GetReachableNodes (node);

Isn’t that only good for getting the immediately surrounding nodes? (Distance 1000). What if i want to get all the nodes at least 2 tiles away? 3? etc.

var allNodes = new List();
AstarPath.active.astarData.graphs[0].GetNodes(node => {
allNodes.Add(node);
return true;});

Won’t this return all the nodes in the graph? Again the same question - i am just looking to get All the nodes within a certain range

Finally, what is the difference between calling AstarPath.StartPath, and calling SeekerInstance.StartPath ?

Ah, ok. You want to get all nodes, unwalkable or not, within a specified distance. I thought you wanted to get all nodes in the graph.
Unfortunately there is no out of the box way to do that at the moment since no paths will traverse unwalkable nodes (all connections are usually removed as well).

You could try to change all unwalkable nodes to instead use a different tag and make sure that the seeker cannot traverse it. Then the ConstantPath will be able to search those nodes.

The difference beteween AstarPath.StartPath and seeker.StartPath is explained here:
http://arongranberg.com/astar/docs_dev/calling-pathfinding.php

Ok, that sounds fine. The other thought i had was to either:

  • enable the nodes as walkable, call ConstantPath, then disable the nodes again
  • never make the nodes that enemies / other heroes stand in unwalkable, and when you get the ConstantGraph, loop through the returned nodes and check if anything is standing on them.

Yeah. Either of those approaches would work as well. But I think using tags is the fastest approach.

I agree. Started converting all the code yesterday. This also reduces my previous need for multiple graphs to just one graph.

Related feature request: seekers that have a tag on them, so that they automatically update the node they are standing on