NullReferenceException: Object reference not set to an instance of an object

I seem to have an issue that several others have had but each situation seems to be somewhat unique in it’s solving and thus, as of yet I have been unable to ascertain the issue. Basically, when I run my P2P_guide.cs script, it kicks out this error in the debug console:

NullReferenceException: Object reference not set to an instance of an object
Grid_Manager.NodeFromWorldPoint (Vector3 worldPosition) (at Assets/Pathfinding_Resources/Grid_Manager.cs:65)
Pathfinding.FindPath (Vector3 startPos, Vector3 targetPos) (at Assets/Pathfinding_Resources/Pathfinding.cs:21)
P2P_guide.amble () (at Assets/Pathfinding_Resources/P2P_guide.cs:25)
P2P_guide.Start () (at Assets/Pathfinding_Resources/P2P_guide.cs:20)

As you can see, this is quite a complex error and seeing as I have not been programming in c# for too long and thus am relatively inexperienced I have spent ages trying to find the problem but no luck and so I was wondering if a fresh set of eyes could shed some light on the situation? Here are the scripts I am running:

This one is attached to a player object:

P2P_guide

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

public class P2P_guide : MonoBehaviour {

	GameObject pathobj;
	Grid_Manager grid;
	public List<Node_Manager> path;
	Pathfinding pathfinder;
	public Transform Destination;
	public List<Vector3> pathcoords;
	public Transform Player;


	void Start() {
		pathobj = GameObject.Find ("A*");
		grid = pathobj.GetComponent<Grid_Manager> ();
		pathfinder = pathobj.GetComponent<Pathfinding> ();
		amble ();

	}
	void amble() {
		
		pathfinder.FindPath (Player.position, Destination.position);
		path = grid.path;
		pathcoords = new List<Vector3>();
		foreach (Node_Manager node in path) {
			pathcoords.Add (grid.WorldPointFromNode (node));
		}

		transform.LookAt (pathcoords [1]);
	
	}
}

and then these three are attached to a game object called “A*” in the middle of the map:

Pathfinding

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

public class Pathfinding : MonoBehaviour {

	public Transform seeker, target;

	Grid_Manager grid;

	void Awake() {
		grid = GetComponent<Grid_Manager> ();
	}
		

/*	void Update() {
		FindPath (seeker.position, target.position);
	}
*/
	public void FindPath(Vector3 startPos, Vector3 targetPos) {
		Node_Manager startNode = grid.NodeFromWorldPoint (startPos);
		Node_Manager targetNode = grid.NodeFromWorldPoint (targetPos);

		List<Node_Manager> openSet = new List<Node_Manager> ();
		HashSet<Node_Manager> closedSet = new HashSet<Node_Manager> ();
		openSet.Add (startNode);

		while (openSet.Count > 0) {
			Node_Manager currentNode = openSet [0];
			for (int i = 1; i < openSet.Count; i ++) {

				if (openSet <em>.fCost < currentNode.fCost || openSet_.fCost == currentNode.fCost && openSet*.hCost < currentNode.hCost) {*_</em>

_ currentNode = openSet ;
* }*_

* }*

* openSet.Remove (currentNode);*
* closedSet.Add (currentNode);*

* if (currentNode == targetNode) {*
* RetracePath (startNode, targetNode);*
* return;*
* }*

* foreach (Node_Manager neighbour in grid.GetNeighbours(currentNode)) {
_ if (!neighbour.walkable || closedSet.Contains (neighbour)) {
continue;
}*_

* int newMovementCostToNeighbour = currentNode.gCost + GetDistance (currentNode, neighbour);*
* if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains (neighbour)) {*
* neighbour.gCost = newMovementCostToNeighbour;*
* neighbour.hCost = GetDistance (neighbour, targetNode);*
* neighbour.parent = currentNode;*

* if (!openSet.Contains (neighbour)) {*
* openSet.Add (neighbour);*
* }*
* }*

* }*
* }*
* }*

* void RetracePath (Node_Manager startNode, Node_Manager endNode) {
List<Node_Manager> path = new List<Node_Manager> ();
Node_Manager currentNode = endNode;*

* while (currentNode != startNode) {*
* path.Add (currentNode);*
* currentNode = currentNode.parent;*
* }*
* path.Reverse ();*

* grid.path = path;*

* }*

* int GetDistance(Node_Manager nodeA, Node_Manager nodeB) {
_ int distX = Mathf.Abs (nodeA.gridX - nodeB.gridX);
int distY = Mathf.Abs (nodeA.gridY - nodeB.gridY);*_

* if (distX > distY) {*
_ return 14 * distY + 10 * (distX - distY);
* }*_

* else {*
_ return 14 * distX + 10 * (distY - distX);
* }
}
}*_

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

public class Grid_Manager : MonoBehaviour {

* public Transform player;*
* public LayerMask unwalkableMask;*
* public Vector2 gridWorldSize;*
* public float nodeRadius;*
* Node_Manager[,] grid;
_ public Vector3 worldBottomLeft;*_

* float nodeDiameter;*
* int gridSizeX, gridSizeY;*

* void Start() {*
_ nodeDiameter = nodeRadius * 2;
* gridSizeX = Mathf.RoundToInt (gridWorldSize.x / nodeDiameter);
gridSizeY = Mathf.RoundToInt (gridWorldSize.y / nodeDiameter);
CreateGrid ();
}*_

* void CreateGrid() {*
* grid = new Node_Manager[gridSizeX,gridSizeY];*
_ worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x/2 - Vector3.forward * gridWorldSize.y/2;_

* for (int x = 0; x < gridSizeX; x ++) {*
* for (int y = 0; y < gridSizeY; y ++) {*
_ Vector3 worldPoint = worldBottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.forward * (y * nodeDiameter + nodeRadius);
* bool walkable = !(Physics.CheckSphere(worldPoint,nodeRadius,unwalkableMask));_
grid[x,y] = new Node_Manager(walkable,worldPoint,x,y);
_ }
}
}*_

* public List<Node_Manager> GetNeighbours(Node_Manager node) {
List<Node_Manager> neighbours = new List<Node_Manager> ();*

* for (int x = -1; x <= 1; x++) {*
* for (int y = -1; y <= 1; y++) {*
* if (x == 0 && y == 0) {*
* continue;*
* }*
* int checkX = node.gridX + x;*
* int checkY = node.gridY + y;*

* if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeY) {*
* neighbours.Add (grid [checkX, checkY]);*
* }*
* }*
* }*

* return neighbours;*
* }*

* public Node_Manager 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];
}*_

* public Vector3 WorldPointFromNode(Node_Manager node) {
Node_Manager Node = node;
_ int x = Node.gridX;
int y = Node.gridY;
int roundrad = Mathf.RoundToInt (nodeRadius);
int posx = Mathf.RoundToInt (worldBottomLeft.x) + (xroundrad);

int posy = Mathf.RoundToInt (worldBottomLeft.y) + (yroundrad);
Vector3 pos = new Vector3(posx,0,posy);
return pos;
}*_

* public List<Node_Manager> path;*

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

* if (grid != null) {*
* Node_Manager playerNode = NodeFromWorldPoint (player.position);
foreach (Node_Manager n in grid) {*

* Gizmos.color = (n.walkable) ? Color.white : Color.red;*
* if (playerNode == n) {*
* Gizmos.color = Color.blue;*
* }*
* if (path != null)*
* if (path.Contains (n))*
* Gizmos.color = Color.black;*
_ Gizmos.DrawCube (n.worldPosition, Vector3.one * (nodeDiameter - .1f));
* }
}
}
}*_

Node_Manager
using UnityEngine;
using System.Collections;

public class Node_Manager {

* public bool walkable;*
* public Vector3 worldPosition;*
* public int gridX;*
* public int gridY;*

* public int gCost;*
* public int hCost;*
* public Node_Manager parent;*

* public Node_Manager(bool _walkable, Vector3 _worldPos, int _gridX, int _gridY) {
walkable = _walkable;
worldPosition = _worldPos;
gridX = gridX;
gridY = gridY;*
* }*

* public int fCost {*
* get {*
* return gCost + hCost;*
* }*
* }*
}

Anyway, thanks in advance and I hope to hear from someone soon!
:slight_smile:

The error is saying that “grid” doesn’t exist yet.

This might be a problem with script execution order.

You are calling CreateGrid() in the Start method of your GridManager class, but it’s possible that the NodeFromWorldPoint method is getting called first, since it is called from the Start method of P2P_Guide.

Try changing this

void Start() {
         nodeDiameter = nodeRadius * 2;
         gridSizeX = Mathf.RoundToInt (gridWorldSize.x / nodeDiameter);
         gridSizeY = Mathf.RoundToInt (gridWorldSize.y / nodeDiameter);
         CreateGrid ();
     }

to this:

void Awake() {
         nodeDiameter = nodeRadius * 2;
         gridSizeX = Mathf.RoundToInt (gridWorldSize.x / nodeDiameter);
         gridSizeY = Mathf.RoundToInt (gridWorldSize.y / nodeDiameter);
         CreateGrid ();
     }

Otherwise, you can control the order that Unity runs scripts using Script Execution Order settings: