Search Unity

Null Reference Error when using Singleton Game Manager

Discussion in 'Scripting' started by VihanAgarwal, Jun 25, 2017.

  1. VihanAgarwal

    VihanAgarwal

    Joined:
    May 18, 2016
    Posts:
    7
    ISSUE DESCRIPTION:
    I am working on making an Angry Birds style game. Currently, I am using a GameManager to keep track of the number of balls available. I check this in my "Hook" script which basically deals with Instantiating a new ball if it's possible. When I try accessing the instance of the game manager (Which is attached to a game object) in the update method everything is fine, but if I try instantiating it in a custom method I get a "Null Reference Error".

    FIXES I HAVE TRIED:
    I tried changing the Script Execution order so that the GameManager Script runs first but this didn't seem to help.

    CODE:
    Game Manager:
    Code (CSharp):
    1. public class GameController : MonoBehaviour {
    2.  
    3.     public static GameController instance = null;
    4.  
    5.     void Awake()
    6.     {
    7.         if(instance == null)
    8.         {
    9.             instance = this;
    10.  
    11.         }
    12.         else if (instance != this)
    13.         {
    14.             Destroy(this);
    15.         }
    16.  
    17.         DontDestroyOnLoad(gameObject);
    18.     }
    19.  
    20.     //How many balls are available
    21.     public int numberOfBalls = 3;
    22.     //How much gold does the player have
    23.     public int gold = 0;
    24.     //What level is the player on
    25.     public int level = 0;
    26.  
    27. }
    Hook Class:
    Code (CSharp):
    1. public class Hook : MonoBehaviour {
    2.  
    3.     //Reference to the ball prefab
    4.     public GameObject ballPrefab;
    5.     //Is there currently a ball in play
    6.     private bool isBallActive;
    7.     //The current ball in play
    8.     private GameObject currentBall;
    9.     //Reference to the Game camera
    10.     [SerializeField]private Camera gameCamera;
    11.  
    12.     //On awake assign a new ball to the hook
    13.     void Awake()
    14.     {
    15.         //Create a new ball
    16.         createNewBall();
    17.     }
    18.  
    19.     //Called every frame
    20.     public void Update()
    21.     {
    22.         //If the currentBall has been destroyed
    23.         if(currentBall == null)
    24.         {
    25.             //No ball is active
    26.             isBallActive = false;
    27.         }
    28.  
    29.         //If no ball is active, and we have more balls
    30.         if (!isBallActive && GameController.instance.numberOfBalls > 0)
    31.         {
    32.             //Create a new ball
    33.             createNewBall();
    34.             //Reduce the number of balls left
    35.             //GameController.instance.numberOfBalls -= 1;
    36.  
    37.         } else if(!isBallActive && GameController.instance.numberOfBalls <0)
    38.         {
    39.             Debug.Log("Out of BALLZ");
    40.         }
    41.     }
    42.    
    43.     //Create a new ball and attach it to the hook
    44.     private void createNewBall()
    45.     {
    46.        
    47.         //Instantiate a new ball
    48.         currentBall = Instantiate(ballPrefab, transform.position, Quaternion.identity);
    49.  
    50.         //Reduce the number of balls left
    51.         GameController.instance.numberOfBalls -= 1;
    52.  
    53.  
    54.         //Make the camera follow new ball
    55.         gameCamera.GetComponent<CameraFollow>().playerToFollow = currentBall;
    56.         //Get the current rigidbody of the hook
    57.         Rigidbody2D rb = GetComponent<Rigidbody2D>();
    58.         //Connect it to the ball
    59.         currentBall.GetComponent<SpringJoint2D>().connectedBody = rb;
    60.         currentBall.GetComponent<Ball>().rb2D_hook = rb;
    61.         //Ball is active
    62.         isBallActive = true;
    63.  
    64.     }
    65. }
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    If you fixed the execution order, I think it should be fine. But, it's possible you have an error elsewhere.

    Like, this line
    Rigidbody2D rb = GetComponent<Rigidbody2D>(); Does the gameobject that the hook script is attached to have a rigidbody2D on it?

    That would be my first question. Then, what line is the error actually pointing to?
     
  3. VihanAgarwal

    VihanAgarwal

    Joined:
    May 18, 2016
    Posts:
    7
    Thanks for the response. The error is actually thrown on Line 51. However, if I move that to Line 35 then I don't get an error. My only guess was that when I have it in createNewBall(), It's called in awake. So I changed the script execution order but no luck
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    You could move createNewBall to start in the hook script (generally the way I do manager type classes). How are you setting up the scripts in the execution order?
     
  5. VihanAgarwal

    VihanAgarwal

    Joined:
    May 18, 2016
    Posts:
    7
    I got it to work! I just had to make sure my Hook class was loaded after the game manager.
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    Glad you got it to work! Usually the execution order will handle this, which is odd that it didn't for you.