A* Pathfinding Project

Block a node connection


#1

Hi There,

I am trying to create a grid based turn based tactics game with a LayerdGrid.
Movement will be strictly centre of node to center of node (E.g. XCOM).

In the below image, the grey grid are the tiles, and the yellow lines are the node connections generated by A* which are in the center of each tile.

If there a way I can make a thin wall (white wall in the image) to block a node connection so the player cant move through it? I have indicated the connections I dont want with red arrows.
Currently Node size is 1, player diameter 1.


#2

Hi

Blocking movement on grid graphs is primarily done by making nodes unwalkable, so doing what you are asking is not possible out of the box. Since you cannot increase the graph resolution to make the wall lie on a node, you would need to modify the grid graph a bit.
More specifically in the LayerGridGraphGenerator.cs script, inside the CalculateConnections method you would have to change this line (around line 815)

if (other != null && other.Walkable) {

To add a check for if it is possible to move from ‘node’ to ‘other’. Probably you want to use Physics.Linecast to do this something like

if (other != null && other.Walkable && Physics.Linecast((Vector3)node.position, (Vector3)other.position, /* ...layer masks and other settings */)) {

#3

Thanks Aron,

Ill try that. I was thinking of removing them after they were created but your method makes more sense!


#4

Hi Aron,

I am running into some trouble.

If I add the following code at line 811 (just above the line you suggest I change), it SHOULD do nothing at all, but I am getting an error when I click Scan. When I remove the linecast there are no problems.

                bool pathBlocked = false;

                if(Physics.Linecast((Vector3)node.position, (Vector3)other.position, collision.mask))
                {
                    pathBlocked = false;
                }   
                
                if (other != null && other.Walkable && !pathBlocked) { `

#5

Hi

What error are you getting?


#6


#7

Ah. I think the variable ‘other’ is null.

You see the if statement below checks specifically for if ‘other’ is not null, but you are trying to access the position field of it before you have checked if it is null or not.


#8

Ahh right. Ok ill separate the check and put it after your if statement.


#9

Well that was easy…
Just wrapped the if statement in if(other != null) hehe

Success!

`

                bool pathBlocked = false;

                if (other != null)
                {
                    if (Physics.Linecast((Vector3)node.position, (Vector3)other.position, collision.mask))
                    {
                        pathBlocked = true;
                    }
                }
                
                if (other != null && other.Walkable && !pathBlocked) {                    
                //if (other != null && other.Walkable) {`

#11

In case someone is looking for an equivalent for a simple grid graph, here it is:
GridGenerator.cs, line 1131 (using v3.8.6)

		public virtual bool IsValidConnection (GridNode n1, GridNode n2) {
			if (!n1.Walkable || !n2.Walkable) {
				return false;
			}

			if (Physics.Linecast((Vector3)n1.position, (Vector3)n2.position, collision.mask))
			{
				return false;
			}

			return maxClimb <= 0 || System.Math.Abs(n1.position[maxClimbAxis] - n2.position[maxClimbAxis]) <= maxClimb*Int3.Precision;
		}