Remove or Disable GridGraph Node

Hello Pathfinders,

So I am looking remove / disable / set unwalkable some nodes on my grid graph.

I am using this code, but not getting any results:

	// Loop through tile objects and trim path
	for (int level = 0; level < tileObjects.GetLength(0); level++)
	{
		for (int row = 0; row < tileObjects.GetLength(1); row++)
		{
			for (int column = 0; column < tileObjects.GetLength(2); column++)
			{
				TileProp tile = tileObjects[level, row, column].GetComponent<TileProp>();

				// If tile should be avoided
				if (tile.AvoidPathfinding())
				{
					GridNode node = activePath.GetNearest(tile.transform.position).node as GridNode;
					node.Walkable = false;
				}
			}
		}
	}

Is there something I am missing?

Hi

I’m not sure why that wouldn’t work. It should work.

It does miss a few steps however. I recommend that you take a look at the ‘Using direct access to graph data’ section on this page: https://arongranberg.com/astar/documentation/dev_4_1_6_17dee0ac/graph-updates.php#direct

It has some example code which is very similar to what you want to do.

1 Like

Using this code from your documentation doesn’t actually compile?

AstarPath.active.AddWorkItem(new AstarWorkItem(ctx => {
        var node = AstarPath.active.GetNearest(transform.position).node;
        node.Walkable = false;
        ctx.QueueFloodFill();
    }));

As is I get this errror:

Error CS0246 The type or namespace name 'AstarWorkItem' could not be found (are you missing a using directive or an assembly reference?) remote

If I correct the struct reference to : AstarPath.AstarWorkItem I get this error:

Error CS1643 Not all code paths return a value in lambda expression of type 'Func<bool, bool>' remote C:\Users\tomdo\Documents\Work\Unity\Remote\remote\Assets\Scripts\Generation\Map.cs 171 Active

if I add a “return true” I get this error:

Error CS1061 'bool' does not contain a definition for 'QueueWorkItemFloodFill' and no extension method 'QueueWorkItemFloodFill' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) remote

Is this the correct way the AddWorkItem? Commenting out the ctx.QueueFloodFill() results in the function not working, as before.

:confused:

Hi

Which version are you using?
That code should work in all versions above 3.7.4 I think.

I am on version 3.8.10.

It looks like it ctx needs to be a IWorkItemContext type, but I have no idea how to set it to that type?

I would have thought it would infer that from it not returning anything, but you can try

 AstarPath.active.AddWorkItem(new AstarWorkItem((IWorkItemContext ctx) => {
    var node = AstarPath.active.GetNearest(transform.position).node;
    node.Walkable = false;
    ctx.QueueFloodFill();
}));

That doesn’t compile as well. Also, I can’t find any reference to IWorkItemContext or WorkItemContext in the your plugin at all.

I don’t merge the examples scenes when I import, would that be the problem?

Aah. I see. Version 3.7.4 that I mentioned earlier was a beta version, not a public release.
The IWorkItemContext doesn’t exist in a non-beta version until 4.x.
I think this code will work in your version:

AstarPath.active.AddWorkItem(new AstarPath.AstarWorkItem(force => {
    var node = AstarPath.active.GetNearest(transform.position).node;
    node.Walkable = false;
    AstarPath.active.QueueWorkItemFloodFill();
    return true;
}));

That still doesn’t appear to work.

I’m printing out a debug log for each node I am disabling and the node is coming back as disabled, but the graph debug mesh isn’t showing the node as disabled.

Perhaps its just the debug gizmos that aren’t being updated and the data is correct? Either that, or the graph update / flood fill isn’t being properly called.

That’s odd. The debug gizmos should always be up to date. Are you doing any other graph updates at the same time?

I was doing a scan afterwards, yeah, as I originally thought I needed to do with to update the graphs.

Commenting that out seems to fix the problem. :smiley:

Actually, sorry, I am now getting some errors.

NullReferenceException: Object reference not set to an instance of an object
Map+<TrimPathfinding>c__AnonStorey1.<>m__0 (Boolean force) (at Assets/Scripts/Generation/Map.cs:164)
AstarPath.ProcessWorkItems (Boolean force) (at Assets/Addons/AstarPathfindingProject/Core/AstarPath.cs:1052)

Am I trying to disable nodes that I have already disabled?

That errors comes from your code so I’m not completely sure, but I would guess that the GetNearest call returns that it didn’t find any node at all (so ‘node’ will be null).
The range of the GetNearest call is limited by A* Inspector -> Settings -> Max Nearest Node Distance. Are you sure you are querying for nodes on the graph and that the graph has been scanned earlier (otherwise the graph will not contain any nodes)?

The graph has only just been created, I am trying to instantly trim any nodes that aren’t needed.

Is there a process I need to do after creating a graph to make sure it is ready to set the nodes as not walkable?

Did you create it from code? Newly created graphs are not scanned when they are created, you will need to call AstarPath.active.Scan() to make sure you have something to start from.

If I do that then the node.Walkable = false stops working.

Scan the graph before you run that code.

I am scanning before I run that code, it still seems to affect the walkable flag.

That said, time.timeScale = 0 at this point. Would that be a problem?

You aren’t scanning the graph for every node you try to make unwalkable by any chance?

The time scale shouldn’t be a problem.

Well, I’ve running that example code for each tile that I want to remove, yeah.

Do I need to move the floodfill to outside the loop of setting the unwalkable tiles?