Null Reference Error when using Singleton Game Manager

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:

public class GameController : MonoBehaviour {

    public static GameController instance = null;

    void Awake()
    {
        if(instance == null)
        {
            instance = this;

        }
        else if (instance != this)
        {
            Destroy(this);
        }

        DontDestroyOnLoad(gameObject);
    }

    //How many balls are available
    public int numberOfBalls = 3;
    //How much gold does the player have
    public int gold = 0;
    //What level is the player on
    public int level = 0;

}

Hook Class:

public class Hook : MonoBehaviour {

    //Reference to the ball prefab
    public GameObject ballPrefab;
    //Is there currently a ball in play
    private bool isBallActive;
    //The current ball in play
    private GameObject currentBall;
    //Reference to the Game camera
    [SerializeField]private Camera gameCamera;

    //On awake assign a new ball to the hook
    void Awake()
    {
        //Create a new ball
        createNewBall();
    }

    //Called every frame
    public void Update()
    {
        //If the currentBall has been destroyed
        if(currentBall == null)
        {
            //No ball is active
            isBallActive = false;
        }

        //If no ball is active, and we have more balls
        if (!isBallActive && GameController.instance.numberOfBalls > 0)
        {
            //Create a new ball
            createNewBall();
            //Reduce the number of balls left
            //GameController.instance.numberOfBalls -= 1;

        } else if(!isBallActive && GameController.instance.numberOfBalls <0)
        {
            Debug.Log("Out of BALLZ");
        }
    }
   
    //Create a new ball and attach it to the hook
    private void createNewBall()
    {
       
        //Instantiate a new ball
        currentBall = Instantiate(ballPrefab, transform.position, Quaternion.identity);

        //Reduce the number of balls left
        GameController.instance.numberOfBalls -= 1;


        //Make the camera follow new ball
        gameCamera.GetComponent<CameraFollow>().playerToFollow = currentBall;
        //Get the current rigidbody of the hook
        Rigidbody2D rb = GetComponent<Rigidbody2D>();
        //Connect it to the ball
        currentBall.GetComponent<SpringJoint2D>().connectedBody = rb;
        currentBall.GetComponent<Ball>().rb2D_hook = rb;
        //Ball is active
        isBallActive = true;

    }
}

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(); 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?

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

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?

I got it to work! I just had to make sure my Hook class was loaded after the game manager.

Glad you got it to work! Usually the execution order will handle this, which is odd that it didn’t for you.