How to set a wall that doesn’t occupy a grid

20220110145116

My game is the Topdown genre, and I now use the layered Grid Graph, as shown here, where my paths are stitched together from 1 sized squares, and the walls are placed between the two squares, but don’t occupy the Grid.

I wanted to be able to do this when nodesize is 1, and when the role goes from A to B, the path is ACDB, I tried to set nodesize to 0.25, but that would result in too many grids, the walls also take up the grid, and the characters make lots of turns as they move.

How am I supposed to do that?

Or can I set an edge on a node to be inaccessible? It seems like every node has four edges, right?

For example, when both A and B nodes are set to be inaccessible near the edge of the wall, the shortest path from A to B is acdb.

Is there such an API?

Hi

This is only possible using script access. You can access a node and then disable/enable its connection in particular directions.

var node = AstarPath.active.GetNearest(point).node as GridNode;
// Disable the connection along direction 0
node.SetConnectionInternal(0, false);

See GridNode - A* Pathfinding Project for more details.

Uploading: 微信图片_20220119162630.jpg…

I used “SetConnectionInternal”, which did solve my requirements, but not completely, because there was a serious problem with this method: on some coordinates, it was invalid and irregular.
For example, my wall is always at 0 in coordinates, so I need to destroy the connections between its left (x-0.5) and right (x+0.5), or between its upper (z+0.5) and lower (z-0.5) nodes. But in some places it doesn’t work at all, or only half works, for example only the 1 on the left is closed, but the 3 on the right is not closed, so the normal detour from left to right, but the right to left still ignores the wall.
Is there anything else that might interfere with this approach?
I also tried to use “RemoveConnection”, but this method is completely useless, should I add another method to refresh or write map data?

//I have two roles, using different meshes
 var graphs = AstarPath.active.graphs;
        //mapnodes=Parent node of all walls
        for (int i = 0; i < mapnodes.childCount; i++)
        {
            //Is the current wall horizontal or vertical
            if (mapnodes.GetChild(i).eulerAngles.y == 0)
            {
                
                if (mapnodes.GetChild(i).name.Contains("wall_1"))
                {

                    for (int j = 0; j < graphs.Length; j++)
                    {
                        var node = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z + 0.5f)).node as GridNode;

                        node.SetConnectionInternal(0, false);

                        var node1 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z - 0.5f)).node as GridNode;
                        node1.SetConnectionInternal(2, false);
                        

                    }
                }
                else if (mapnodes.GetChild(i).name.Contains("wall_2"))
                {
                    
                    for (int j = 0; j < graphs.Length; j++)
                    {
                        //upleft
                        var node0 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x - 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z + 0.5f)).node as GridNode;
                        node0.SetConnectionInternal(0, false);

                        //upright
                        var node1 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x + 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z + 0.5f)).node as GridNode;
                        node1.SetConnectionInternal(2, false);

                        //left lower
                        var node2 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x - 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z - 0.5f)).node as GridNode;
                        node2.SetConnectionInternal(0, false);

                        //right lower
                        var node3 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x + 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z - 0.5f)).node as GridNode;
                        node3.SetConnectionInternal(2, false);

                    }
                }
            }
            else
            {
                if (mapnodes.GetChild(i).name.Contains("wall_1"))
                {
                    for (int j = 0; j < graphs.Length; j++)
                    {
                        var node = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x + 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z)).node as GridNode;

                        node.SetConnectionInternal(3, false);


                        var node1 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x - 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z)).node as GridNode;
                        node1.SetConnectionInternal(1, false);

                        
                    }
                }
                else if (mapnodes.GetChild(i).name.Contains("wall_2"))
                {
                    for (int j = 0; j < graphs.Length; j++)
                    {
                        //upleft
                        var node0 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x - 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z + 0.5f)).node as GridNode;
                        node0.SetConnectionInternal(1, false);

                        //upright
                        var node1 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x + 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z + 0.5f)).node as GridNode;
                        node1.SetConnectionInternal(3, false);

                        //left lower
                        var node2 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x - 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z - 0.5f)).node as GridNode;
                        node2.SetConnectionInternal(1, false);

                        //right lower
                        var node3 = graphs[j].GetNearest(new Vector3(mapnodes.GetChild(i).position.x + 0.5f, mapnodes.GetChild(i).position.y, mapnodes.GetChild(i).position.z - 0.5f)).node as GridNode;
                        node3.SetConnectionInternal(3, false);

                    }
                }
            }
        }

Okay, I know what it is. When the game starts, the grid refresh is called somewhere, and then because my “SetConnectionInternal” is a for, some of the disconnections are done before the refresh and some are done after the refresh, which makes some of them work and some of them don’t work, and now I’ve put disconnection at the bottom of the boot order, so That solved the problem. Thank you :+1: :+1:

1 Like