[Solved] Can't make UpdateGraphsNoBlock to work the way i need

I know that this question has been asked before, but i’ve been searching for hours now both here and on google with no results.

I have the same issue as the person in this post UpdateGraphsNoBlock not working? but his solution didn’t help.

What happens is that the UpdateGraphsNoBlock prevents your from building any more towers after you already blocked the path. What i want it to do is prevent you before you actually block the path.

The code is pretty much copy/paste from the documentation

guo = new GraphUpdateObject(wallPrefab.GetComponent<BoxCollider2D>().bounds);
            GraphNode startNode = AstarPath.active.GetNearest(startPos.transform.position, NNConstraint.Default).node;
            GraphNode endNode = AstarPath.active.GetNearest(endPos.transform.position, NNConstraint.Default).node;
            if (GraphUpdateUtilities.UpdateGraphsNoBlock(guo, startNode, endNode, true))
            {
                Debug.Log("VALID POSSITION");
                wall = Instantiate(wallPrefab, transform.position, Quaternion.identity) as GameObject;
                AstarPath.active.UpdateGraphs(wall.GetComponent<BoxCollider2D>().bounds);

            }
            else {
                Debug.Log("INVALID POSSITION");
               
            }

Any help will be more than appropriated.

Thanks in advance.

Hi

Can you elaborate a bit on what exactly does not work? Is the final graph update working? Are you seeing any blocked nodes at all? Have you verified that the start node and end node are the correct nodes?

I see one very big potential error.
You are using the collider of a prefab not an actual object. That means that your UpdateGraphsNoBlock call is will not really change the graph at all because nothing has changed (you didn’t place an obstacle).

You may want to set ‘updatePhysics’ on the GraphUpdateObject to false and instead use the ‘modifyWalkability’ and ‘setWalkability’ fields to control if nodes are made walkable or unwalkable.

See http://arongranberg.com/astar/docs/class_pathfinding_1_1_graph_update_object.php

1 Like

Thanks for your reply.

The final graph is updating (the nodes turn red) meaning that those nodes are blocked. Also, the start and end node are the correct ones.

The UpdateGraphsNoBlock does change the graph and it recognizes the newly placed obstacles. What i need (or i assume i need to be honest, it’s my first time) is the graph to sort of “predict” that if you are about to place an obstacle to the last walkable node it shouldn’t allow you to do so.

Hopefully checking the pictures below will help you understand better what i mean:


Hi

The easiest fix for you is to instantiate the object BEFORE the UpdateGraphsNoBlock call, and use the bounds of that instantiated collider for the GraphUpdateObject. Then if it turns out that you could not place it there, simply delete the instantiated object. This will not interfere with pathfinding because the UpdateGraphsNoBlock method will ensure that no path are calculated while the obstacle is blocking anything.

1 Like

Ok, i will try it and write back if it worked for me or not.

EDIT:
Ok actually it worked.

In case someone else is interested this is the new code:

      wall = Instantiate(wallPrefab, transform.position, Quaternion.identity) as GameObject;
       AstarPath.active.UpdateGraphs(wall.GetComponent<BoxCollider2D>().bounds);
                guo = new GraphUpdateObject(wall.GetComponent<BoxCollider2D>().bounds);
                GraphNode startNode = AstarPath.active.GetNearest(startPos.transform.position, NNConstraint.Default).node;
                GraphNode endNode = AstarPath.active.GetNearest(endPos.transform.position, NNConstraint.Default).node;
                if (GraphUpdateUtilities.UpdateGraphsNoBlock(guo, startNode, endNode, true))
                {
                    Debug.Log("VALID POSITION");
                }
                else {
                    Debug.Log("INVALID POSITION");
                    DestroyImmediate(wall);
                    AstarPath.active.Scan();
                }

I know that DestroyImmediate and AstarPath.active.Scan(); are not optimized at all and shouldn’t be used this way, i just needed something to see if it will actually work. I will fix those now.

Thanks a lot for your help!

Hi

I did not mean that you should also move the second UpdateGraphs outside the IF. Actually you can set the last parameter of the UpdateGraphsNoBlock method to false and completely skip the other UpdateGraphs call. UpdateGraphsNoBlock will update the graphs first, then check if that resulted in the path from the start node to the end node being blocked and if so, revert it. If it was not blocked it will revert the change IF the last parameter is true. So you can actually just do something like

GraphNode startNode = AstarPath.active.GetNearest(startPos.transform.position, NNConstraint.Default).node;
GraphNode endNode = AstarPath.active.GetNearest(endPos.transform.position, NNConstraint.Default).node;
wall = Instantiate(wallPrefab, transform.position, Quaternion.identity) as GameObject;
var guo = new GraphUpdateObject(wallPrefab.GetComponent<BoxCollider2D>().bounds);

// Check if the path becomes blocked by the obstacle
// if yes, then revert the change (UpdateGraphsNoBlock will do this) and delete the obstacle
if (!GraphUpdateUtilities.UpdateGraphsNoBlock(guo, startNode, endNode, false)) {
    Destroy(wall);
}

I think that should do what you want

1 Like

That’s actually better, thanks again.

Thought i have a new problem now, if i can near the end node i can build around it (blocking the path) without destroying the last wall to leave some free space and it always returns as valid position to build.

Should i call for path checks the opposite way around too? (if thats possible)

I don’t quite follow. Could you elaborate?

1 Like

Some pictures should help:

I can block the path if i build far from it. That’s what i understand it’s happening. So my question was if i should do some kind of an opposite check for the path. Like start checking from the endNode to the startNode.

Hi

The check is bidirectional (assuming no one-way edges, but there are none in this case).
Are you sure the end node is correctly set?

1 Like

Actually you were right. I used the prefab endNode on the prefab ground that’s why it allowed me to build in front of it and block the path. I now used the endNode object in the game scene on the ground objects that exist on the scene and it’s perfect, i can’t block it anymore.

1 Like

Great that it is working :smile:

1 Like

Thanks a lot for helping, even though i don’t own the Pro version.

Will keep it in mind though.