Calculating new paths after UpdateGraphs

I have a simple scene where walls can be placed in a similar style to the Sims. I am using a GridGraph. I’m running UpdateGraphs with a GraphUpdateObject to add bounds for newly created walls. The problem I have is that existing paths are not updated, so I tried to write some code to recall SetPath on all of my actors.

AstarPath.active.UpdateGraphs(new GraphUpdateObject(wall.collider.bounds));

// This is called before UpdateGraphs has updated the GridGraph
var actors = GameObject.FindGameObjectsWithTag("actor");
for (var actor in actors){
    var AI = actor.GetComponent(PathController);
    AI.UpdatePath();
}

The problem I am having is that the actors are recalculating their new paths before UpdateGraphs has finished updating the graphs.

Is it possible for me to know when the graph has finished updating?

Also, is it possible to know if a path will intersect with the newly placed wall?

I was able to solve my first question by disabling “Limit Graph Updates”. I’m now trying to figure out how I can loop through all agents and find ones whose current path will intersect with a new wall.

Hi

The best way to deal with this is to register to a delegate on the AstarPath object.

`
public void OnEnable () {
AstarPath.OnGraphsUpdated += RecalculatePath;
}

public void OnDisable () {
AstarPath.OnGraphsUpdated -= RecalculatePath;
}

public void RecalculatePath () {

seeker.StartPath (…);

}`

http://arongranberg.com/astar/docs/class_astar_path.php#a8c6d31ec81922e83c11aaf8a96f33cb2

I think this callback is working in the latest version, I have been a bit bad at making sure it works in some versions, but I think it should work.

As for testing if a path intersects a wall. On a grid graph, a pretty good test can be done by looping through all nodes in it and testing if they are unwalkable.
for (int i=0;i<path.path.Count;i++) { if (!path.path[i].walkable) { RecalculatePath(); break; } }

Note however that if you remove a wall, this test (and no other test that I can think of), will not be able to see that there is now a shorter path to the target.

Hey Aron,

I am using:

function Start () {
	AstarPath.OnGraphsUpdated += OnGridUpdate;
}

And getting the error:

BCE0051: Operator '+' cannot be used with a left hand side of type 'function(AstarPath): void' and a right hand side of type 'function(): void'.

Any ideas?

Thanks for giving me that loop to test for walkable nodes. I had coded up this:

	// Update all actors
	var actors = GameObject.FindGameObjectsWithTag("actor");
	for (var actor in actors){
		var AI = actor.GetComponent(PathController);
		if(!PathUtilities.IsPathPossible(AI.path.path)){
			Debug.Log("Calculating new path");
			AI.UpdatePath();
		}else{
			Debug.Log("Path is still possible");
		}
	}

Is using IsPathPossible more expensive than your example?

Thanks for your help!

Ah. Sorry, the RecalculatePath method must take an AstarPath parameter, like so:
public void RecalculatePath (AstarPath astar);

Hm, interesting solution, I hadn’t thought of that. Actually, it will work, and be about the same speed as a custom loop. I should start recommending that solution : )

Good to know :slight_smile:

I added the AstarPath parameter but I’m now getting

 BCE0043: Unexpected token: astar.

I also tried:

function OnGridUpdate(astar : AstarPath){

because I’m using Javascript, but that doesnt work either (gives the original error).

I sort-of fixed this by using

AstarPath.OnGraphsUpdated = OnGridUpdate;

Instead of using +=. I know this won’t let me tack on more callbacks in the future, but for now it works. I read that we can’t use C# delegates in javascript, so I’d probably have to write my own delegator in OnGridUpdate if I want more than one callback.