- Home /
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.
Answer by Dave-Carlile · Oct 24, 2013 at 05:59 PM
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.
Oh bugger, I was confining the scope to the constructor. I knew it was going to be something that made me feel like an idiot, totally worth it to get back to making some progress though.
Thanks a ton Dave.
Happy to help - eventually this kind of thing will become obvious, most of the time. I've been coding for 30+ years and still do this occasionally, followed by lots of cursing at myself upon discovering it. Please check this as the accepted answer if it was helpful.
Answer by btb200 · Oct 24, 2013 at 07:04 AM
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);
...
Tried those changes, but no dice, same exception. Thanks for giving it a shot.
I used to have it set up like that, but I figured I'd get in the habit of avoiding the "new" call when possible. That Vector3 ID in the NodeGrid class is only used during the creation of the grid anyway, which completes and tests fine. It's almost certainly something about referencing the Node objects in the array that's throwing the exception.
Your answer
Follow this Question
Related Questions
C# NullRefException accessing static class, array value 1 Answer
Is every Script I drag on a Gameobject an instance? 1 Answer
How to call a new instance of a class in C# 1 Answer
help with creating a static Instance in javascript 2 Answers
C# Inheritance, base class attributes, override and null object 1 Answer