Areas and Gridgraph updates

Hi,
I am creating a grid graph programmatically from an existing grid representation like this:
`
AstarData data = AstarPath.active.astarData;
GridGraph gg = data.AddGraph(typeof(GridGraph)) as GridGraph;
gg.width = (int)levelSize.x ;
gg.depth = (int)levelSize.y;
gg.nodeSize = 0.64f;
gg.center = new Vector3 (((levelSize.x/2)*0.64f)-0.32f,((levelSize.y/2)*0.64f)-0.32f,0);
gg.rotation = new Vector3(-90,0,0);
gg.collision.collisionCheck = false;
gg.collision.heightCheck = false;
gg.maxClimb=0.0f;
gg.neighbours = NumNeighbours.Four;
gg.UpdateSizeFromWidthDepth();
gg.GenerateMatrix();
gg.SetUpOffsetsAndCosts();

            AstarPath.active.Scan();
    
	AstarPath.RegisterSafeUpdate (delegate (){
			var gridg = AstarPath.active.astarData.gridGraph;
			for ( int z = 0; z < gridg.depth; z++ ) {
				for ( int x = 0; x < gridg.width; x++ ) {
						
						TileData tile = GameManager.Instance.MapData.GetTile(x,z);
						gridg.nodes[z*gridg.width + x].Walkable = tile.passible; 
						gridg.nodes[z*gridg.width + x].Penalty = (uint)tile.movementModifier;
                                   }
           		       }
	              },true);
            AstarPath.active.FlushThreadSafeCallbacks ();
	AstarPath.active.FloodFill();
}

`

Then when the user places a new tile i update it like this:
`
AstarPath.RegisterSafeUpdate (delegate () {

				var graph = AstarPath.active.astarData.gridGraph;
				GridNode node = graph.nodes[(int)gridPos.y*graph.width + (int)gridPos.x];
				
				node.Walkable = false;
				node.RecalculateConnectionCosts();
			},true);
			// Make sure the above callback is run directly
			AstarPath.active.FlushThreadSafeCallbacks ();
                            AstarPath.active.FloodFill()

`

This updates the node to non walkable and updates the connections correctly. I do however have 2 issues.

1.The areas are never updated ( I have set Min Area Size to 0). The entire grid is marked as a single area so I cant return early from pathfinding checks if an object is unreachable.

  1. I have set the numofconnections to 4. I had to do that as units would regulary path between two tiles that meet diagonally. I would like to keep the 8 connections but prevent units pathing between diagonal tiles ( Its a top down tile based game).
    eg.
    0X
    X0
    unit will path from 0 to 0 across the corner.

I am not using colliders at the moment nor any physics.

Any ideas on how to fix this would be appreciated, especially the area calculation, I can live with the 4 direction issue.

Cheers
Dave

No one have any ideas? Aaron?

Hi

The reason is that you are not recalculating the connections of the nodes.
This is why I usually recommend using or subclassing the GraphUpdateObject class.

You need to call GridGraph.CalculateConnections (node) on every node whose connections could have changed, so usually.

GridNode node = ...; GridGraph.CalculateConnections (node); node.GetConnections (delegate (GraphNode node) { GridNode gnode = node as gnode; if (gnode != null) GridGraph.CalculateConnections (gnode); });

If you subclass the the GraphUpdateObject class, it will do this for you automatically.

(note: just writing in the browser, I haven’t tested the code below)
class MyGUO : GraphUpdateObject { public override void Apply ( GraphNode node ) { GridGraph gg = AstarData.GetGraph (node) as GridGraph; GridNode gnode = node as GridNode; int index = node.NodeInGridIndex; int x = index % gg.width; int z = index / gg.width; TileData tile = GameManager.Instance.MapData.GetTile(x,z); gnode.Walkable = tile.passible; gnode.Penalty = (uint)tile.movementModifier; } }

var guo = new MyGUO (someBounds);

// Necessary, otherwise the penalty will be reset
// Enabling it is also a lot slower
guo.updatePhysics = false;

AstarPath.UpdateGraphs (guo);
`

1 Like

This is exactly about the problem that I’m having. Tried out the CalculateConnections(GridNode) function, but it is still just one big area. Any way this function is buggy?´There is a note above it that indicates it is untested:

\todo Test this function, should work ok, but you never know

@FearBeard

Are you also calling AstarPath.active.FloodFill() after you have updated the region?
As mentioned in http://arongranberg.com/astar/docs/graph-updates.php#direct you will need to call that method to recalculate the area information.

No I didn’t. Tried it and it works now.

Wow, very quick response. Thank you, still loving your product! :smile: