I keep getting a NullReferenceException on this C# script I’m writing to generate a maze.
Basically how it works is that I have a two-dimensional array of mazeCell objects (each of which contains four walls, and an isVisited member). I think the comments in the code are enough to explain it, but I’m getting this error on any of the four cases in the switch statement (in the line that says “if (tempCell.isVisited == true) // Check if target cell is visited or not”).
Does anyone know why this is happening? This is my code:
using UnityEngine;
using System.Collections;
public class mazeCell
{
public bool isVisited;
public int topWall;
public int bottomWall;
public int rightWall;
public int leftWall;
public int heightCoordinate;
public int widthCoordinate;
public mazeCell()
{
isVisited = false;
topWall = 1;
bottomWall = 1;
rightWall = 1;
leftWall = 1;
}
}
public class mazeGenerateScript : MonoBehaviour
{
// Variables for the wall and position of the wall
public GameObject wallHorizontal;
public GameObject wallVertical;
public int xCoordinate = 0;
public int zCoordinate = 0;
// Master variables for the height and width of the entire maze
public static int height = 15;
public static int width = 20;
// An array of mazeCell objects
public mazeCell[,] mazeCellArray = new mazeCell[height + 1, width + 1];
// The stack that will hold all the visited mazeCell objects and control the backtracking
Stack cellStack = new Stack();
// Total number of cells and number of visited cells
int totalCells = height * width;
int visitedCells = 0;
// Use this for initialization
void Start()
{
// Create a new mazeCell object for each element in the mazeCell[,] array, and set the height and width coordinates accordingly
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
mazeCell tempCell = new mazeCell();
tempCell.heightCoordinate = i;
tempCell.widthCoordinate = j;
mazeCellArray[i, j] = tempCell;
}
}
// Create a random set of height and width coordinates for the starting cell
int startingHeight = Random.Range(0, height);
int startingWidth = Random.Range(0, width);
// Assign starting cell to the default instantiated mazeCell object at the random coordinates generated above
mazeCell currentCell = mazeCellArray[startingHeight, startingWidth];
// Loop that actually generates the maze
while (visitedCells < totalCells)
{
bool topVisited = false;
bool bottomVisited = false;
bool rightVisited = false;
bool leftVisited = false;
while (topVisited == false || bottomVisited == false || rightVisited == false || leftVisited == false)
{
int directionToTest = Random.Range(1, 4); // Creates a random number representing a direction. 1 for up, 2 for down, 3 for right, 4 for left
switch (directionToTest)
{
case 1: // Above current cell
if (currentCell.heightCoordinate - 1 < 0) // If out of range, set topVisited = true and continue looping (generating another random direction)
{
topVisited = true;
continue;
}
else // Not out of range
{
mazeCell tempCell = new mazeCell();
tempCell = mazeCellArray[currentCell.heightCoordinate - 1, currentCell.widthCoordinate]; // Set tempCell to the target cell (above)
if (tempCell.isVisited == true) // Check if target cell is visited or not
{
topVisited = true;
continue;
}
else // Target cell is not visited
{
currentCell.topWall = 0; // Break top wall of current cell
mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
tempCell.bottomWall = 0; // Break bottom wall of tempCell
tempCell.isVisited = true; // Set tempCell to visited
cellStack.Push(currentCell); // Push currentCell to the stack
currentCell = tempCell; // Set currentCell to tempCell
visitedCells++; // Increment the number of visited cells
break;
}
}
case 2: // Below current cell
if (currentCell.heightCoordinate + 1 > height) // If out of range, set bottomVisited = true and continue looping (generating another random direction)
{
bottomVisited = true;
continue;
}
else // Not out of range
{
mazeCell tempCell = new mazeCell();
tempCell = mazeCellArray[currentCell.heightCoordinate + 1, currentCell.widthCoordinate]; // Set tempCell to the target cell (below)
if (tempCell.isVisited == true) // Check if target cell is visited or not
{
bottomVisited = true;
continue;
}
else // Target cell is not visited
{
currentCell.bottomWall = 0; // Break bottom wall of current cell
mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
tempCell.topWall = 0; // Break top wall of tempCell
tempCell.isVisited = true; // Set tempCell to visited
cellStack.Push(currentCell); // Push currentCell to the stack
currentCell = tempCell; // Set currentCell to tempCell
visitedCells++; // Increment the number of visited cells
break;
}
}
case 3: // Right of current cell
if (currentCell.widthCoordinate + 1 > width) // If out of range, set rightVisited = true and continue looping (generating another random direction)
{
rightVisited = true;
continue;
}
else // Not out of range
{
mazeCell tempCell = new mazeCell();
tempCell = mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate + 1]; // Set tempCell to the target cell (right)
if (tempCell.isVisited == true) // Check if target cell is visited or not
{
rightVisited = true;
continue;
}
else // Target cell is not visited
{
currentCell.rightWall = 0; // Break right wall of current cell
mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
tempCell.leftWall = 0; // Break left wall of tempCell
tempCell.isVisited = true; // Set tempCell to visited
cellStack.Push(currentCell); // Push currentCell to the stack
currentCell = tempCell; // Set currentCell to tempCell
visitedCells++; // Increment the number of visited cells
break;
}
}
case 4: // Left of current cell
if (currentCell.widthCoordinate - 1 < 0) // If out of range, set leftVisited = true and continue looping (generating another random direction)
{
leftVisited = true;
continue;
}
else // Not out of range
{
mazeCell tempCell = new mazeCell();
tempCell = mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate - 1]; // Set tempCell to the target cell (above)
if (tempCell.isVisited == true) // Check if target cell is visited or not
{
leftVisited = true;
continue;
}
else // Target cell is not visited
{
currentCell.leftWall = 0; // Break left wall of current cell
mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
tempCell.rightWall = 0; // Break right wall of tempCell
tempCell.isVisited = true; // Set tempCell to visited
cellStack.Push(currentCell); // Push currentCell to the stack
currentCell = tempCell; // Set currentCell to tempCell
visitedCells++; // Increment the number of visited cells
break;
}
}
}
}
// If every surrounding cell is visited, backtrack along the stack
if (topVisited == true && bottomVisited == true && rightVisited == true && leftVisited == true)
currentCell = (mazeCell)cellStack.Pop();
}
for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
mazeCell tempCell = new mazeCell();
tempCell = mazeCellArray[x, y];
if (tempCell.topWall == 0)
Instantiate(wallHorizontal, new Vector3(xCoordinate, 0, zCoordinate), Quaternion.identity);
if (tempCell.bottomWall == 0)
Instantiate(wallHorizontal, new Vector3(xCoordinate, 0, zCoordinate + 16), Quaternion.identity);
if (tempCell.leftWall == 0)
Instantiate(wallVertical, new Vector3(xCoordinate, 0, zCoordinate), Quaternion.identity);
if (tempCell.rightWall == 0)
Instantiate(wallVertical, new Vector3(xCoordinate + 16, 0, zCoordinate), Quaternion.identity);
xCoordinate = xCoordinate + 16;
}
zCoordinate = zCoordinate + 16;
}
}
// Update is called once per frame
void Update()
{
}
}