Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by GlitteringStone · Dec 26, 2012 at 04:09 AM · c#arraynullreferenceexceptionmaze

NullReferenceException - Maze Generator Script

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()
     {
 
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by MarkFinn · Dec 26, 2012 at 05:00 AM

Your array mazeCellArray is 1 item higher and wider than height and width.

  public mazeCell[,] mazeCellArray = new mazeCell[height + 1, width + 1];

When you populate it you only put in height by width mazeCells, so there is a row and column in the array which is empty.

 // 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++)
     {


As soon as your builder loop hits one of the empty cells, it correctly enough has a null ref exception.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GlitteringStone · Dec 26, 2012 at 05:09 AM 0
Share

Just changed that (by removing the +1s), and now it's giving me an IndexOutOfRangeException on these lines (in each case block):

tempCell = mazeCellArray[currentCell.heightCoordinate - 1, currentCell.widthCoordinate]; // Set tempCell to the target cell (above)

It shouldn't be out of range though, because in the If statement right before that, I check whether it's out of range, and if it's out of range, it shouldn't even execute this line.

avatar image MarkFinn · Dec 26, 2012 at 05:22 AM 0
Share

Remember, in all arrays the cells run from 0 to size_of_array - 1.

Change case 3: if to

if (currentCell.widthCoordinate + 1 >= width)
avatar image MarkFinn · Dec 26, 2012 at 05:22 AM 0
Share

(You'll need a few other similar modifications too).

avatar image MarkFinn · Dec 26, 2012 at 05:29 AM 0
Share

After which your code goes into an infinite loop (Unity Editor Freezes).

You need to rethink your end-of-loop conditions.

avatar image GlitteringStone · Dec 26, 2012 at 06:33 AM 0
Share

You're talking about the

while (topVisited == false || bottomVisited == false || rightVisited == false || leftVisited == false)

loop as being the infinite one, right? I can't really think of another way to create that one. I need the loop to cut out only if all four cells (in all four directions) are all visited, otherwise it has to execute the statements in the else block and then cut out of the loop. I'm not sure why it's looping infinitely, the continue statements should just go to the start of the loop and the break statements should end the while loop, right?

Sorry for asking so many questions, this is my first game with Unity, I wanted to do a random maze game to learn the engine.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Array Index Out of Range - Maze Generation Algorithm 1 Answer

A problem with arrays 1 Answer

Picking a Random Order for Levers 1 Answer

Cannot assign assets to variables via inspector: NullReferenceException 3 Answers

NullReferenceException error in an array of objects 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges