Search Unity

Feeling silly, can't figure out why I get nullpointers

Discussion in 'Scripting' started by HoboMechanistic, Aug 31, 2014.

  1. HoboMechanistic

    HoboMechanistic

    Joined:
    Jan 17, 2013
    Posts:
    20
    I feel like I'm going insane. I swear this was working a minute ago, now I get nullpointers. I took out everything other than what's causing the problem. All this should do is add a gameObject to a list. My scripts are simple:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class OnRoomClick : MonoBehaviour {
    6.  
    7.    private RoomSelectTracker roomList;
    8.    // Use this for initialization
    9.    void Start () {
    10.      roomList = GameObject.Find("Main Camera").GetComponent<RoomSelectTracker>();
    11.      roomList.addRoom(this.gameObject);
    12.    }
    13.  
    14.    // Update is called once per frame
    15.    void Update () {
    16.  
    17.    }
    18.  
    19.    void OnMouseDown() {
    20.  
    21.    }
    22.  
    23.    public void setNoHalo(){
    24.  
    25.    }
    26. }
    27.  
    The next script is the one that holds the List value:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class RoomSelectTracker : MonoBehaviour {
    7.    //Using this class to track which building the user has selected
    8.    //And update the selection visually
    9.    //I dont want to jam this into the Building_Instance class since this is a visual thing
    10.    //and Building_instnace doe sneough as it is in terms of val updates
    11.    private List<GameObject> list;
    12.  
    13.    // Use this for initialization
    14.    void Start () {
    15.      list = new List<GameObject>();
    16.    }
    17.  
    18.    // Update is called once per frame
    19.    void Update () {
    20.    
    21.    }
    22.  
    23.    public void addRoom(GameObject x){
    24.      list.Add(x);
    25.      Debug.Log("room added to the list");
    26.    }
    27.  
    28.    public void setUnselectedVisual(){
    29.    
    30.    }
    31. }
    Am I missing something? I get a nullpointer for the addRoom, for each room that tries to get added to the list:

    NullReferenceException: Object reference not set to an instance of an object
    RoomSelectTracker.addRoom (UnityEngine.GameObject x) (at Assets/Scripts/UIScripts/RoomSelectTracker.cs:24)
    OnRoomClick.Start () (at Assets/Scripts/OnRoomClick.cs:10)
     
  2. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    Maybe OnRoomClick is running before RoomSelectTracker. Try assigning the list in Awake or where the variable is declared.

    Code (csharp):
    1. private List<GameObject> list = new List<GameObject>();
     
  3. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Because roomList is null. You assigned it a type but didn't create an instance. Change your Start method to this:
    Code (csharp):
    1.  
    2. void Start () {
    3.      roomList = new RoomSelectTracker(); //Added this line.
    4.      roomList = GameObject.Find("Main Camera").GetComponent<RoomSelectTracker>();
    5.      roomList.addRoom(this.gameObject);
    6.    }
    7.  
    Now I noticed that RoomSelectTracker is a MonoBehavior. Have you assigned it in the inspector? Is that behavior attached to anything?
     
  4. HoboMechanistic

    HoboMechanistic

    Joined:
    Jan 17, 2013
    Posts:
    20
    Thanks for taking the time to help me out guys!

    OnRoomClick was infact running before RoomSelectTracker. Initialising the RoomSelectTracker in the Awake() fixed this problem :)

    I have the RoomSelectTracker assigned to the camera, this is probably not the best way to go about doing things. I tend to attach scripts to the camera when I just need to attach them to some type of gameobject but not a specific one. I didnt know there was any other way of doing things in Unity.

    I'll have a read up on MonoBehavior a bit more now. I would like to be able to control what script runs before which. If I were to get rid of MonoBehavior atm I'd have to restructure my code a bit according to the console output I just saw :x
     
  5. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Well there are other things you can do... You don't know that the camera has been initialized before your object that's trying to access the RoomSelectTracker. Looking at your code, unless you've stripped stuff out, I don't see that you're doing anything in Update or Fixed Update, etc. So my first question is whether or not you even need a MonoBehavior. It appears to me that you're just doing it that way and attaching it to the camera for ease of use.

    Now, that being said, your RoomSelectTracker could just be a regular class and not inherit from MonoBehavior at all. In fact, it looks like you may only ever need once instance of it so you could look at using the Singleton pattern and access it statically via a helper class.
     
  6. HoboMechanistic

    HoboMechanistic

    Joined:
    Jan 17, 2013
    Posts:
    20
    This makes a lot of sense to me as I only need one instace of this class. :D Thanks, I'll try and use Singleton design from this point onwards. I didnt know about Singleton design until you mentoined it, it seems to be perfectly suited to this case. Well I probably did in theory but unless I use something I forget about it :x This will probably make things easier to keep track of as I'm not relying on game objects as much.
     
    Last edited: Sep 1, 2014
  7. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    the thing to keep in mind with singleton is that you'll need to manage state between scenes.. Make sure things get cleaned up and or reset if needed. If you are only using it in one scene but you have a lot of scenes then the gameobject scenario makes sense so you're not keeping things in memory that you dont need. Then again, you can create a simple manager class that is your singleton or static and then create or destroy your collection class as needed. There are lots of different approaches. Just choose the one that makes most sense for your game.