Null reference when trying to return an object

I’ve been trying to break apart a simple pathfinder I built earlier into a few smaller classes in separate script files from one big file. However, I keep running into this null reference exception and can’t figure out what’s causing it for the life of me.

I have a Node class which stores basic information about position and whether the node can be traveled:

public class Node
{
	public Vector3 ID;
	public int cost = 0, heuristic = 0, total = 0;
	public bool walkable;
	
	public Node (Vector3 ID, bool walkable)
	{
		this.ID = ID;
		this.walkable = walkable;
	}

	public void SetWalkable (bool walkable) {
		this.walkable = walkable;
	}
}

And a NodeGrid class which has a simple constructor to build a 2D array of Nodes and some methods for returning a specific node.

public class NodeGrid
{
	private Node[,] grid;

	public NodeGrid (int width, int height) {
		bool walkable = true;
		Vector3 ID;

		Node[,] grid = new Node[width, height];
		
		for (int i=0; i < width; i++)
		{
			for (int j=0; j < height; j++)
			{				
				ID.x = i;
				ID.y = 0;
				ID.z = j;
				grid[i,j] = new Node(ID, walkable);
			}
		}

		Debug.Log(width.ToString() + ", " + height.ToString() + " grid created.");
        Debug.Log(grid[5,5].ID.x.ToString());
	}

	public Node GetNode (Vector3 ID) {
		return grid[(int)ID.x, (int)ID.z]; 
	}

	public Node GetNode (int i, int j) {
		return grid[i,j]; 
	}
}

And I have a small script attached to an empty gameobject for testing this grid of nodes. It creates a new 10x10 NodeGrid and then tries to get the node at 5,5 and instead I get a null reference exception when trying to use the GetNode method.

public class NodeGridTester : MonoBehaviour {

	private NodeGrid nodeGrid;
	private int width = 10, height = 10;

	void OnGUI ()
	{
		if(GUI.Button( new Rect( 10, 10, 100, 30 ), "Create Grid")) {
			nodeGrid = new NodeGrid(width, height);
		}

		if(GUI.Button( new Rect( 10, 45, 100, 30 ), "Display Grid" )) {
			Node node = nodeGrid.GetNode(5,5);
		}
	}
}

There are no errors on compile. The runtime error message:

NullReferenceException: Object reference not set to an instance of an object
NodeGrid.GetNode (Int32 i, Int32 j) (at Assets/_TBS Assets/Scripts/NodeGrid.cs:33)

The line reference is

return grid[i,j];

from the GetNode method.

The grid appears to build just fine when using the Create Grid button, the debug text I have inserted at the end of the grid building loops shows exactly what it should.

10, 10 grid created.
UnityEngine.Debug:Log(Object)
NodeGrid:.ctor(Int32, Int32) (at Assets/_TBS Assets/Scripts/NodeGrid.cs:25)
NodeGridTester:OnGUI() (at Assets/_TBS Assets/Scripts/NodeGridTester.cs:12)

And the second debug line displays 5, reading the x of the Vector3 ID of the Node instance exactly as expected.

5
UnityEngine.Debug:Log(Object)
NodeGrid:.ctor(Int32, Int32) (at Assets/_TBS Assets/Scripts/NodeGrid.cs:26)
NodeGridTester:OnGUI() (at Assets/_TBS Assets/Scripts/NodeGridTester.cs:12)

However, pressing the Display Grid button results in the null reference.

Clearly I’m doing something wrong when it comes to creating or handling or reading from classes in C# or Unity (or maybe in general?). I looked up a bunch of topics on null reference exceptions but it’s such a broad error that nothing I found was relevant or had any effect. Any help would be greatly appreciated.

The problem is in this line in the NodeGrid constructor…

Node[,] grid = new Node[width, height];

You’re creating a local version of the variable since you’re specifying the type, so the class member grid is left as null. Just change it to this…

grid = new Node[width, height];

That will access the grid variable at the class scope and you should be good to go.

You have to create your Vector3 ID object…

public NodeGrid (int width, int height) {
       bool walkable = true;
       Vector3 ID = Vector3.zero;
...

or

...

ID = new Vector3(i,0,j);
grid[i,j] = new Node(ID, walkable);

...