Update just ONE graph during runtime?

I have three different kinds of graphs in play (two custom, one gridgraph). I have added code to update the graphs whenever I place a structure on my terrain, via this code:

AstarPath.active.UpdateGraphs (collider.bounds);

The problem I am having is that this is very aggressive. It updates all my graphs, and one of them is never ever meant to be updated via a scan (manually updated as needed). It is causing extremely screwed up graphs to exist (all nodes connecting to all other nodes in one of my graphs)

How can I tell the library to ā€œJust update the grid graph with these boundsā€? I was unable to find a graph specific method that took bounds as a parameter.

Hi

If you create a GraphUpdateObject and pass that to the UpdateGraphs method you can set the graphMask field.

var guo = new GraphUpdateObject(someBounds);
guo.nnConstraint.graphMask = 1 << 2; // Update only the third graph (index 2)
AstarPath.active.UpdateGraphs(guo);

See

Works like a charm. Thank you!

Might I suggest for a future version that you add an ā€œUpdateGraph()ā€ method that wraps this? That would be a cool addition.

1 Like

I actually spoke to soon. While the graph is updating correctly now, the eseocnd I do this I start to get path errors when going to the location. This is what it looks like:

https://i.imgur.com/xTZOkED.png

And the error I get is:

Couldnā€™t find a close node to the end point

This is for agents trying to pathfind to the location where the object has been placed; and it happens right after I run the update. I have Max Nearest Node Distance set to 100, and this grid resolution is 2 meters. I am confused regarding why this is happening now.

I am having such a hard time with this. This is my code to update the graph, and I am constantly getting exceptions thrown, and weird graphs:

// update the graph
            GraphUpdateObject guo = new GraphUpdateObject(collider.bounds);
            guo.nnConstraint.graphMask = 1 << 1; // Update only the grid graph (index 1)
            guo.updateErosion = false;
            AstarPath.active.UpdateGraphs(guo);

            // connect entrance nodes
            AstarPath.active.AddWorkItem (new AstarPath.AstarWorkItem (
                () => {
                    // Called once, right before the
                    // first call to the method below
                },
                force => {
                    // GRID
                    NNConstraint nnc = new NNConstraint();
                    nnc.graphMask = 1 << 1; // 1 is currently the gridgraph index
                    NNInfo nni = AstarPath.active.GetNearest(entrance.position, nnc);

                    GridNode enode = new GridNode(AstarPath.active);
                    nni.node.AddConnection(enode, 100);
                    enode.AddConnection(nni.node, 100);   
                    return true;
                }
            ));

I am simply trying to update the graph so that agents do not walk through obstacles, while connecting a point I define as the ā€œentranceā€ to the grid graph.

The update is not very precise (there are still connections that go through the obstacle), and the connection I am trying to add seems to never get created. I get this exception almost everytime I place an obstacle:

Exception while updating graphs:
System.NullReferenceException: Object reference not set to an instance of an object
  at Pathfinding.GridNode.FloodFill (System.Collections.Generic.Stack`1 stack, UInt32 region) [0x0000c] in E:\Programming\Unity\Doge\Assets\ThirdParty\AstarPathfindingProject\Generators\NodeClasses\GridNode.cs:263 
  at AstarPath+<FloodFill>c__AnonStorey2E.<>m__19 (Pathfinding.GraphNode node) [0x0012f] in E:\Programming\Unity\Doge\Assets\ThirdParty\AstarPathfindingProject\Core\AstarPath.cs:1863 
  at Pathfinding.PointGraph.GetNodes (Pathfinding.GraphNodeDelegateCancelable del) [0x00013] in E:\Programming\Unity\Doge\Assets\ThirdParty\AstarPathfindingProject\Generators\PointGenerator.cs:189 
  at AstarPath.FloodFill () [0x000ef] in E:\Programming\Unity\Doge\Assets\ThirdParty\AstarPathfindingProject\Core\AstarPath.cs:1873 
  at AstarPath.ProcessGraphUpdatesAsync (System.Object _astar) [0x00099] in E:\Programming\Unity\Doge\Assets\ThirdParty\AstarPathfindingProject\Core\AstarPath.cs:1356

Hi

You cannot simply create a new grid node like that. That node is not attached to any graph and will, as you have noticed, cause a bunch of errors. If you want to create new nodes at runtime, you can use the PointGraph.AddNode method (you will need to have a point graph in your scene as well), there is however currently no support for deleting nodes from a point graph.

Also. Since you change connections, I would recommend that you call

AstarPath.instance.QueueWorkItemFloodFill()

To make sure that the necessary graph information is updated.

Hmā€¦ yes I am not sure why that is happening. Was your code for creating new grid nodes active then as well?

Hi Aron. thanks for the feedback. Yes that makes sense; I should be actualyl adding that node to a gridā€¦ haha. Iā€™m tired todayā€¦

As for the original issue with the max nearest node; now this code was not in place. I actually started doing this to get around that problem. I do need to know why that happens though because I will eventually need some agents to move off grid a little bit.

I have had another manifestation of this error when an agent gets pushed too far outside of the grid (about 5 meters), where it can no longer find ANY nodes.

Any suggestions for what I should look at to resolve that?

PointGraph.AddNode() breaks:

InvalidCastException: Cannot cast from source type to destination type.
Doge.Placeables.Structure.<OnAfterPlacement>m__9 (Boolean force) (at Assets/Doge/Placeables/Scripts/Structure.cs:138)
AstarPath.ProcessWorkItems (Boolean force) (at Assets/ThirdParty/AstarPathfindingProject/Core/AstarPath.cs:1021)

Code:

PointNode enode = new PointNode(AstarPath.active);
                    ((PointGraph)(AstarPath.active.graphs[1])).AddNode(enode, (Int3)entrance.position);
                    nni.node.AddConnection(enode, 100);
                    enode.AddConnection(nni.node, 100);

This is probably because it is a GridGraphā€¦ but there is no AddNode method for GridGraph. How do I add to a grid graph? Is that even possible? Should I make a separate graph for these arbitrary points?

Hi

You can add a new point graph in the graphs list.

Also. Why do you need these new nodes?

Well, the main reason right now is that I was getting path errors trying to get agents to the center of the obstacles.

The ultimate reason though is that I am placing buildings that agents should be able to walk up to, and ā€œenterā€. So I have a transform set that defines where the front door is, and the agents are directed to go to that point when they go to the structure. I donā€™t have artwork for it right now, but it is where the front door would be.

Actually, I just realize it is unnecessary to add this additional pointgraphā€¦

maybe I should chug a gallon of coffeeā€¦

Really this stems from that nearest node issue.

So I removed my code for adding extra nodes because really, an agent should be able to go to a point that is inbetween grid points right?

I still am getting the couldnā€™t find close node to the end point error for something as simple as this:

Red dot indicates the point we were trying to pathfind to. To also illustrates how it still has nodes that go though the obstacle.

Hi

Yeah I am not sure why you are getting that nearest node issue.
Are you sure your Max Nearest Node Distance is set to 100?
You are requesting a path from some point to this white cube, right? Not from the white cube to some other point?

Also, you can try enabling Full Get Nearest Node Search. I donā€™t think it should help, but on the other hand I am not so sure what the cause is soā€¦

It looks like your cube that you have placed is not marked as an obstacle, it is just treated as terrain. You might want to change the layer of it to make it be treated as an obstacle as you probably do not want nodes on top of it (as you can see it has now).
If you for some reason would want to have nodes on top of it, you might want to use a thick raycast to make sure that nodes very close to the wall will be placed on top of it and not on the terrain to avoid those connections that pass through the object.

Yes positive it is set to 100.

Yes the red point is where they are supposed to go. the grid graph has a penalty of something like 3000, and the road graph (point graph) for the road in the image has a penalty of 1000. The road graph and the grid graph have connections to eachother.

I tried enabling full get nearest node search and my one test dd not have nay errors, but at the same time when i tested with it off I got the error about half the time.

I just changed the layer of obstacles to default, as it was set to none, but this is not solving the immediate issue.

Itā€™s very frustrating because sometimes they can get to these node, and sometimes they canā€™t Her is an image where they could get to the one in the background, but the one in the foreground they are unable to get to:
https://i.imgur.com/PFxHAdu.jpg

I also made sure to get my relevant settings in the screen cap. So what the hell is wrong? The only thing I have been able to do is add a helper point graph that explicitly links these points to the grid graph, but that is a bit overkill I think.

EDIT: and this is the other settings that you may need to see:
https://i.imgur.com/egKsvJO.png

EDIT 2: full nearest node setting does alleviate the issue, but it seems to degrade their pathfinding. they will go to a node somewhere near the end point, but not always actually get there.

EDIT 3: Here is some output when I turned on heavy debug logging:

Path Failed : Computation Time 0.000 ms Searched Nodes 0
Error: Couldnā€™t find a close node to the end point
Path Number 755 (unique id)

Why is it searching no nodes?

Hi

I really have no idea why this is happening. Would it be possible for you to share your project with me so I could take a look and help you debug the issue?

Try disabling ā€˜Prioritize Graphsā€™. I donā€™t think that should be the cause, but I cannot think of anything else at the moment.

Because it couldnā€™t find a node close to the end point, so it does not know where the goal should be.

Hey Aron,

I would love some help with this, because it is mystifying me too. I canā€™t really share the entire project unfortunately. Would you be willing to schedule a teamviewer session with me? I could demonstrate the problem that way. Would that work?

I noticed that if I turn on Full Get Node Search, it happens FAR less often, but it still does happen occasionally. I also did turn off prioritize graphs, but it made no difference.

I have a suspicion this may have to do with my road graph. I am going to run a test with my AI and no roads for an hour or so to see if the error occurs, then again with a road. if it happens with a road at least I have it narrowed down, and can show you that class in case I am doing something bad.