NullReferenceExeption Error that makes no sense..

Hello Guys,

I am workin on a random dungeon generator but I got stuck here with the NullReferenceExeption Error(Line : 56) and I can’t find a solution, because the error make’s no sense for me:/

I hope you can help me :slight_smile:

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

public class Roo_Controller : MonoBehaviour {
    private Rooms[] RoomPrevious;
    private Rooms[] RoomArr;
    public GameObject PreFab;
    public GameObject Parent;
    public int TotalRooms;
    public int RoomsA;
    public int width;
    public int height;
    const float perc = .8f;
    public int minA;

   
    // Use this for initialization
    void Start () {
        RoomArr = new Rooms[TotalRooms];
        RoomPrevious = new Rooms[TotalRooms];
        RoomArr[0] = new Rooms(0, 0, 0, 0);
        GenerateRooms(width, height, TotalRooms, 1);
       // Debug.Log(RoomArr);
        PlaceRooms();
    }
   
    // Update is called once per frame
    void Update () {
       
    }

    void GenerateRooms(int w, int h, int tamount,int amount)
    {
        RoomPrevious[0] = RoomArr[0];
        for (int s = 0; s < tamount; s++)
        {
            int wd = Random.Range(3, 6);
            int ht = Random.Range(3, 6);
            int PosX = Random.Range(0, w - wd);
            int PosY = Random.Range(0, h - ht);
           

            if (wd * ht > minA && PlaceFree(s))
                {

                    RoomArr[s] = new Rooms(wd, ht, PosX, PosY);
                    //Debug.Log(RoomArr[s]);
                    RoomPrevious[s] = new Rooms(wd, ht, PosX, PosY);
            }
           
         
        }
    }

    public bool PlaceFree(int d) //-------Here is the error--------
    {
        for (int h = 0; h < d; h++)
        {
            int i = d;
            //The Variable Declaration for the IF statment
            int xP = RoomPrevious[i].PosX;
            int yP = RoomPrevious[i].PosY;
            int xEndP = xP + RoomPrevious[i].width;
            int yEndP = yP + RoomPrevious[i].height; ;
            int x = RoomArr[i].PosX;
            int y = RoomArr[i].PosY;
            int xEnd = x + RoomArr[i].width;
            int yEnd = y + RoomArr[i].height;

            if (xP != x && yP != y && xEndP != xEnd && yEndP != yEnd)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
           
       
    }
    void PlaceRooms()
    {

        for (int i = 0; i < TotalRooms; i++)
        {
            GenerateRoomObject(RoomArr[i]);
        }

    }

    void GenerateRoomObject(Rooms A)
    {
        for (int i = 0; i < A.height; i++)
        {
            for (int j = 0; j < A.width; j++)
            {
                Instantiate(PreFab, new Vector3(A.PosX + j, 0, A.PosY + i), transform.rotation);
               
            }
        }
    }
    [System.Serializable]
    public class Rooms
    {
        public int width;
        public int height;
        public int PosX;
        public int PosY;

        public Rooms(int a, int b, int c, int d)
        {
            width = a;
            height = b;
            PosX = c;
            PosY = d;
        }
    }
}

hmm…Well, there isn’t a way for that line to be null. Can you post the entire error with the stack trace and all?

NullReferenceException: Object reference not set to an instance of an object
Roo_Controller.GenerateRoomObject (.Rooms A) (at Assets/Roo_Controller.cs:80)
Roo_Controller.placeRooms () (at Assets/Roo_Controller.cs:73)
Roo_Controller.Start () (at Assets/Roo_Controller.cs:24)

It looks like the loop in PlaceFree() only ever runs once. It either returns true or false after the first iteration.

And how could I solve this problem ? :confused:

As @orb said, the PlaceFree will return t/f on the first pass. That doesn’t explain your null exception on either line that you mentioned.

Are you sure you saved the script after making changes? Those line numbers in the stack trace don’t really match up correctly. (assuming this is your entire script)

Ah I think the For loop is the problem

The script as presented doesn’t even compile for me, so you’re looking at error messages from a previous version of it.

So this is the newest version

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

public class Roo_Controller : MonoBehaviour {
    private Rooms[] RoomPrevious;
    private Rooms[] RoomArr;
    public GameObject PreFab;
    public GameObject Parent;
    public int TotalRooms;
    public int RoomsA;
    public int width;
    public int height;
    const float perc = .8f;
    public int minA;

   
    // Use this for initialization
    void Start () {
        RoomArr = new Rooms[TotalRooms];
        RoomPrevious = new Rooms[TotalRooms];
        RoomArr[0] = new Rooms(0, 0, 0, 0);
        GenerateRooms(width, height, TotalRooms, 1);
       // Debug.Log(RoomArr);
        PlaceRooms();
    }
   
    // Update is called once per frame
    void Update () {
       
    }

    void GenerateRooms(int w, int h, int tamount,int amount)
    {
        RoomPrevious[0] = RoomArr[0];
        for (int s = 0; s < tamount; s++)
        {
            int wd = Random.Range(3, 6);
            int ht = Random.Range(3, 6);
            int PosX = Random.Range(0, w - wd);
            int PosY = Random.Range(0, h - ht);
           

            if (wd * ht > minA && PlaceFree(s))
                {

                    RoomArr[s] = new Rooms(wd, ht, PosX, PosY);
                    //Debug.Log(RoomArr[s]);
                    RoomPrevious[s] = new Rooms(wd, ht, PosX, PosY);
            }
           
         
        }
    }

    public bool PlaceFree(int d) //Here it tells me
    {
        for (int h = 0; h < d; h++)
        {
            int i = d;
            //The Variable Declaration for the IF statment
            int xP = RoomPrevious[i].PosX;
            int yP = RoomPrevious[i].PosY;
            int xEndP = xP + RoomPrevious[i].width;
            int yEndP = yP + RoomPrevious[i].height; ;
            int x = RoomArr[i].PosX;
            int y = RoomArr[i].PosY;
            int xEnd = x + RoomArr[i].width;

            int yEnd = y + RoomArr[i].height;

            if (xP != x && yP != y && xEndP != xEnd && yEndP != yEnd)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
           
       
    }
    void PlaceRooms()
    {

        for (int i = 0; i < TotalRooms; i++)
        {
            GenerateRoomObject(RoomArr[i]);
        }

    }

    void GenerateRoomObject(Rooms A)
    {
        for (int i = 0; i < A.height; i++)
        {
            for (int j = 0; j < A.width; j++)
            {
                Instantiate(PreFab, new Vector3(A.PosX + j, 0, A.PosY + i), transform.rotation);
               
            }
        }
    }
    [System.Serializable]
    public class Rooms
    {
        public int width;
        public int height;
        public int PosX;
        public int PosY;

        public Rooms(int a, int b, int c, int d)
        {
            width = a;
            height = b;
            PosX = c;
            PosY = d;
        }
    }
}

The int d in the PlaceFree bool is equal to the amount of rooms the bool has to check and so the first time it has to check 2 rooms, the second time 3 and so on.

Ok, so if this is your new version of the script. What is the error you are getting with the stack trace? Because if the error you copied and pasted references this script…line 80 is an empty line.

NullReferenceException: Object reference not set to an instance of an object
Roo_Controller.GenerateRoomObject (.Rooms A) (at Assets/Roo_Controller.cs:107)
Roo_Controller.PlaceRooms () (at Assets/Roo_Controller.cs:100)
Roo_Controller.Start () (at Assets/Roo_Controller.cs:24)

hmm…Ok, the line numbers still don’t match up, however, it looks like your instantiate call is returning null.

Do you have something assigned to the Prefab variable?

a cube

Assets/Roo_Controller.cs(59,17): error CS0161: `Roo_Controller.PlaceFree(int)': not all code paths return a value

Keep in mind if you are mixing Windows and MacOSX line endings, then the line number of the crash can be misreported.

This error is because your for loop may not run. Thus, if you don’t enter your for loop, you will not return anything.

So you need to return false after the for loop. Even if you never hit that point and always enter your for loop, you still have to declare a return.