How To Find Adjacent Squares

I have a square and I want to find the adjacent squares.

In a case like that one above, you would just run a loop through all the squares and see where are the 8 closest. But what if there’s a square around it missing? Then it’ll find 7 adjacent squares and then the 8th closest one. There are hundreds of squares so you can’t have a variable for each square with a list of its adjacent squares I can manually assign. Plus squares may appear or disappear all the time. How should I find only the adjacent squares of a square?

Use a 2D array to represent the game world.

–Eric

Sorry, could you explain?

He means a tile map I guess. bi-dimensional array is used to store the location of the tile (X,Y) and value of the variable means what it is, for example -1 are map borders, 0 is floor, 1 is non border obstacle, etc. Then you load a texture for each value (-1,0,1) and applies the texture for each square positioned on the X,Y value of your 2D array.
So your image would be something like this:

int[][] map = new int[3][3];

map[0][0] = -1; map[0][1] = -1; map[0][2] = -1;
map[1][0] = -1; map[1][1] =  0; map[1][2] = -1;
map[2][0] = -1; map[2][1] = -1; map[2][2] = -1;

Meaning only the middle square would be floor (int 0); All the -1 your game already know are map borders

The picture is misleading. There is actually probably 100+ of these tiles so how would that work then?

Well, that is what ppl build 2D map editors for :slight_smile:
While you are drawing your tiles on a map editor, it is building all these values and marking which ones are borders or not.
I think you can’t really build a tile based scene without building a tile map editor first, unless you are building fake 2D like many Unity games, at this case you could build an editor tool to put temporary colliders on each tile, check collision normals, store the tiles that do not return all 4 directions of collisions as borders, than destroy the colliders if not needed anymore… Dunno, I don’t make 2D stuff :wink:

It would work exactly the same way…the size isn’t really relevant. Although by 2D array I meant int[,] rather than int[ ][ ] (jagged arrays), since 2D arrays are easier to work. Jagged arrays do have better performance, but unless you’re accessing them constantly it wouldn’t make any difference.

–Eric

Well maybe if I explained the purpose of this it would be easier to find an answer. This is for a very basic pathfinding system.

Yes, like the one in this. Which uses a 2D array. :wink: (Technically a 1D array masquerading as a 2D array, since Unityscript didn’t have direct access to 2D arrays when I wrote that originally.)

–Eric

Alright sounds good! I’ll post back if I come across any problems.

Edit:

Actually, it wouldn’t work because the tiles are part of the mesh and some are different sizes and they are spread out in no particular pattern throughout the map.

Assuming they are quads you can number the polys as rows and columns using the 2D array method above. To find a method for getting which poly you are at look at this
http://answers.unity3d.com/questions/43415/finding-the-polygonface-youre-currently-looking-at.html

HTH

I was still confused about how to implement the 2D array so what I ended up trying was this:

     int i = 0;
		while(i < 8){
			float closeDis = Mathf.Infinity;
			Transform closest = null;
			int a = 0;
			while(a < nodeList.Count){
				if(nodeList[a] != current){
					float distance = (current.position - nodeList[a].position).magnitude;
					if(distance < closeDis  distance < 20){
						closest = nodeList[a];
						closeDis = distance;
					}
				}
				a++;
			}
			adjacentNodes.Add(closest);
			nodeList.Remove(closest);
			i++;
		}

It should theoretically only find nodes that are adjacent because it would only find nodes a certain distance away but…
I’m not sure why this happening, but when I make the least distance lower than 12 it doesn’t create a complete path and if I make it 12 or above it still finds nodes that aren’t adjacent (if there’s a gap between nodes 1 node wide then it’ll jump it).

I found out that the distance between nodes is only 5, so I’m wondering why the path doesn’t fully complete once the distance is less than 12. The current node is constantly updated so that can’t be the problem and the second node is picked from the while loop, so I’m not sure whats wrong. Maybe I did something wrong earlier in the code:

    public Vector3[] offsets = new Vector3[8];

	public Transform holder;

	public List<Transform> nodes;
	public List<Transform> open;
	public List<Transform> closed;

	public Transform current;
	public Transform finish;

	public Material yellow;
	public Material green;
	public Material red;


	void Start () {

		int i = 0;
		while(i < holder.childCount){
			nodes.Add(holder.GetChild(i));
			i++;
		}
		open = FindAdjacentNodes();
	}

	void Update () {
	
		if(current != finish){
			CheckNode();
		}
	}

	void CheckNode () {

		float lowestF = Mathf.Infinity;
		Transform nextNode = null;

		int a = 0;
		while(a < open.Count){
			if(((current.position - open[a].position).magnitude + (finish.position - open[a].position).magnitude) < lowestF){
				nextNode = open[a];
				lowestF = (current.position - open[a].position).magnitude + (finish.position - open[a].position).magnitude;
			}
			a++;
		}

		if(!closed.Contains(current)){
			closed.Add(current);
		}
		current = nextNode;
		if(!closed.Contains(current)){
			closed.Add(current);
		}
		current.renderer.material = green;
		open = FindAdjacentNodes();
	}

	List<Transform> FindAdjacentNodes () {

		List<Transform> nodeList = new List<Transform>();
		nodeList.AddRange(nodes);
		List<Transform> adjacentNodes = new List<Transform>();

		int i = 0;
		while(i < 8){
			float closeDis = Mathf.Infinity;
			Transform closest = null;
			int a = 0;
			while(a < nodeList.Count){
				if(nodeList[a] != current){
					float distance = (nodeList[a].position - current.position).magnitude;
					if(distance < closeDis  distance < 12){
						closest = nodeList[a];
						closeDis = distance;
					}
				}
				a++;
			}
			adjacentNodes.Add(closest);
			nodeList.Remove(closest);
			i++;
		}
		return adjacentNodes;
	}

I found that in this loop:

while(i < 8){
            float closeDis = Mathf.Infinity;
            Transform closest = null;
            int a = 0;
            while(a < nodeList.Count){
                if(nodeList[a] != current){
                    float distance = (nodeList[a].position - current.position).magnitude;
                    if(distance < closeDis  distance < 12){
                        closest = nodeList[a];
                        closeDis = distance;
                    }
                }
                a++;
            }
            adjacentNodes.Add(closest);
            nodeList.Remove(closest);
            i++;
        }

by decreasing the amount of times the first while loop runs from 8 to 4, it doesn’t skip. Unfortunately though, sometimes it doesn’t create a complete path. Not sure why this is.