A* Pathfinding Project

Trouble finding cell index of a node


#1

I can’t for the life if me find a way to get a nodes graph index.

e.g.
GraphNode node = //code here.
node.Walkable = false;
grid.CalculateConnectionsForCellAndNeighbours(node.MYXINDEX, node.MYXINDEX);

Thanks


#2

I think I’m missing a base concept. I’m simply trying to make nodes unwalkable or simply retag a node and am getting no change. I’ve tried several different methods with no luck.

An example:
public void InternalCost (GraphNode node, SingleNodeBlocker blocker) {
AstarPath.active.AddWorkItem(new AstarWorkItem(() => {
List blockersInNode;
if (!blocked.TryGetValue(node, out blockersInNode)) {
blockersInNode = blocked[node] = ListPool.Claim();
node.Tag = 1;
node.Walkable = false;
// Recalculate the connections for that node as well as its neighbours
var grid = AstarPath.active.data.gridGraph;
Bounds bound = new Bounds();
bound.center = new Vector3(node.position.x, node.position.y, node.position.z);
bound.extents = new Vector3(3, 3, 3);

                List<GraphNode> nodes= grid.GetNodesInRegion(bound);
                for (int i = 0; i < nodes.Count; i++)
                {
                    grid.CalculateConnections( nodes[i] as GridNodeBase);
                }
			}
                       
			blockersInNode.Add(blocker);
		}));
	}

#3

Love to see an example of a performant way to change the Penalty or Walkability of a node through script!


#4

Hi

AstarPath.active.AddWorkItem(new AstarWorkItem(ctx => {
    var gg = AstarPath.active.data.gridGraph;
    int x = 5;
    int z = 7;
    var node = gg.GetNode(x, z);
    node.Penalty = 1000;
    node.Walkable = true;
    gg.CalculateConnectionsForCellAndNeighbours(x, z);
    // or you could use
    gg.CalculateConnectionsForCellAndNeighbours(node.XCoordinateInGrid, node.ZCoordinateInGrid);
}

See https://arongranberg.com/astar/docs/gridnodebase.html#XCoordinateInGrid
https://arongranberg.com/astar/docs/gridgraph.html#CalculateConnectionsForCellAndNeighbours
https://arongranberg.com/astar/docs/graphupdates.html#direct

Note that node positions are stored as Int3s, not Vector3s. These are integer coordinates in millimeters.
You can convert between Int3s and Vector3s by casting them.

Vector3 v3 = (Vector3)node.position;

See https://arongranberg.com/astar/docs/int3.html


#5

Thanks so much very helpful. I’ve read the docs you linked to but I’m still missing something. I have updated the function as you mentioned (see below). I’m passing in the position of a agent as they move around and am simply trying to get a test working where other seekers don’t take the same path using penalty. (I put in walkable as a sanity check)

Other seekers are not reacting at all to the path change though. I’m using the base Seeker script with AILerp. is there something else I’m missing? Long term I just want to allow units to block other units.

    var node = AstarPath.active.GetNearest(position, NNConstraint.None).node;
		    AstarPath.active.AddWorkItem(new AstarWorkItem(() => {
               
                    node.Penalty = 9999999;
                    node.Walkable = false;
                    // Recalculate the connections for that node as well as its neighbours
                    var grid = AstarPath.active.data.gridGraph;
                    GridNodeBase n = node as GridNodeBase;
                    grid.CalculateConnectionsForCellAndNeighbours(n.XCoordinateInGrid, n.ZCoordinateInGrid);   
		    }));

#6

got it working! thanks


#7

Hi

You might also be interested in this page: https://arongranberg.com/astar/docs/turnbased.html


#8

Yup read through that, it was actually what I was trying to hijack originally but I couldn’t figure out how to get the nodes grid position. :slight_smile: That section also left me a bit confused about when you actually need to update the graph as at least at surface level the BlockManager doesn’t call CalculateConnectionsForCell maybe deep under the hood.


#9

Yes, that is the whole point. The BlockManager does not update the graph at all. This makes it easy to make rules like “this unit should be able to traverse this node, but not any other units”. One can do this with tags, but they quickly run out and it’s kinda annoying to have to update the graph all the time to keep them in sync. The BlockManager (or more specifically ITraversalProvider) instead adds special rules for an individual path to account for this.