# A* GetNearest() implementation

I'm trying to implement pathfinding in my platformer and I'm having trouble coming up with a way to find the nearest node to a world point.

I tried this:

public Node GetNodeFromPoint(Vector2 point)
{
int xGridPoint = Mathf.RoundToInt(point.x / gridWorldSize.x);
int yGridPoint = Mathf.RoundToInt(point.y / gridWorldSize.y);

Debug.Log(xGridPoint + " " + yGridPoint);

return grid[xGridPoint, yGridPoint];
}


But it always gave me [0,0].

This is my "NavGrid" class it creates the grid and is going to set up the links between nodes:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NavGrid : MonoBehaviour {

public Vector2 gridWorldSize;
public float nodeSize;

Node[,] grid;

int gridSizeX;
int gridSizeY;

float nodeDiameter;

// Use this for initialization
void Start () {
nodeDiameter = nodeSize * 2;
gridSizeX = Mathf.RoundToInt(gridWorldSize.x / nodeDiameter);
gridSizeY = Mathf.RoundToInt(gridWorldSize.y / nodeDiameter);
CreateGrid();
}

private void CreateGrid()
{
grid = new Node[gridSizeX, gridSizeY];
Vector2 worldBottomLeft = transform.position - (Vector3)Vector2.left * gridWorldSize.x / 2 - (Vector3)Vector2.down * gridWorldSize.y / 2;

for(int x = 0; x < gridSizeX; x++)
{
for(int y = 0; y < gridSizeY; y++)
{
Vector2 worldPoint = worldBottomLeft + Vector2.left * (x * nodeDiameter + nodeSize) + Vector2.down * (y * nodeDiameter + nodeSize);

bool iswalkable = false;

if (!Physics2D.CircleCast(worldPoint, nodeSize, Vector2.down, nodeSize/2, unWalkableMask))
{
if (Physics2D.Raycast(new Vector2(worldPoint.x, worldPoint.y - nodeSize), Vector2.down, nodeDiameter, unWalkableMask))
{
iswalkable = true;
}
}

Node node = new Node(iswalkable, worldPoint);

grid[x, y] = node;
}
}
}

{
for(int x = 0; x < gridSizeX; x++)
{
for(int y = 0; y < gridSizeY; y++)
{
Node node = grid[x, y];
if (!node.isWalkable) continue;

if(!grid[x+1,y].isWalkable && !grid[x+1,y-1].isWalkable)
{
Vector2 fallPoint = grid[x + 1, y].worldPosition;

if(hit.collider != null)
{
continue;
}
}

if (!grid[x - 1, y].isWalkable && !grid[x - 1, y - 1].isWalkable)
{
Vector2 fallPoint = grid[x - 1, y].worldPosition;

if (hit.collider != null)
{
continue;
}
}
}
}
}

public Node GetNodeFromPoint(Vector2 point)
{
int xGridPoint = Mathf.RoundToInt(point.x / nodeSize);
int yGridPoint = Mathf.RoundToInt(point.y / nodeSize);

Debug.Log(xGridPoint + " " + yGridPoint);

return grid[xGridPoint, yGridPoint];
}

public void OnDrawGizmos()
{
Gizmos.DrawWireCube(transform.position, new Vector3(gridWorldSize.x, gridWorldSize.y, 1));

if (grid != null)
{
foreach (Node n in grid)
{
if (n.isWalkable)
{
Gizmos.color = Color.red;
Gizmos.DrawRay(new Vector2(n.worldPosition.x, n.worldPosition.y - nodeSize), new Vector2(0, -nodeDiameter));
Gizmos.color = Color.cyan;
Gizmos.DrawCube(n.worldPosition, Vector3.one * (nodeDiameter * 0.9f));
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(n.worldPosition, nodeSize / 2);
}

{
Gizmos.color = Color.blue;
}
}
}
}
}


I tried coldSteel's answer but it gave me a array index out of range error because it world return a negative number.

This is the node class:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Node {

public bool isWalkable = false;
public Vector2 worldPosition;

public Node(bool isWalkable, Vector2 worldPosition)
{
this.isWalkable = isWalkable;
this.worldPosition = worldPosition;
}
}

• To help you with this, we'll need to know the range of your point argument and the value of gridWorldSize - it sounds like they're not in compatible units, causing their quotient to always be so small it rounds to zero. – DMGregory May 15 '19 at 22:45
• gridWorldSize is the "area" the grid covers in world space. – ThePumkinMelon May 15 '19 at 23:10
• Wait, the size of the entire grid, not the size of one cell? That sounds like your problem. – DMGregory May 15 '19 at 23:13
• I tried it with the node size and that didn't work either. – ThePumkinMelon May 16 '19 at 0:56
• "Didn't work" isn't enough for us to diagnose the problem. Can you update your question to include a minimal, complete, verifiable example of the issue that we can reproduce in a new project? – DMGregory May 16 '19 at 1:37

You are dividing a point by a grid size - thus you get a 0,0 because I assume that grid size is much larger than a point.

What you want to do is: To take your point in World coordinates and divide it by a GridCellSize.

XCoord = 6/3 = 2

YCoord = 0/3 = 0

In This tutorial there is a good way of doing it.

public Node NodeFromWorldPoint(Vector3 worldPosition) {
float percentX = (worldPosition.x + gridWorldSize.x/2) / gridWorldSize.x;
float percentY = (worldPosition.z + gridWorldSize.y/2) / gridWorldSize.y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);

int x = Mathf.RoundToInt((gridSizeX-1) * percentX);
int y = Mathf.RoundToInt((gridSizeY-1) * percentY);
return grid[x,y];
}


It's explained here nicely.