0
\$\begingroup\$

I have spent a long time (4-5 hours) digging around as to why my version of the Breakout Unity Tutorial was not working. There where repeated errors of

NullReferenceException: Object reference not set to an instance of an object xxxxxxx

when running the game and calling Game Manager scripts from other scripts in the game.

After much reading up on vaguely useful questions and answers on here I know well enough what the error text means, but the answers on here that describe the error in detail do not reference how to solve this issue on an instance of a singleton.
Elsewhere I found a solution, and want to show this solution as I figure that can help a lot of other people searching for why this issue occurs:

Qualifier:
There is an inconsistency with the Breakout Tutorial

see the instantiation of the Game Manager class:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GM : MonoBehaviour {

    public int lives = 3;
    public int bricks = 20;
    public float resetDelay = 1f;
    public Text livesText;
    public GameObject gameOver;
    public GameObject youWon;
    public GameObject bricksPrefab;
    public GameObject paddle;
    public GameObject deathParticles;


    /***
     * The below sets the Game Manager Class (GManager) as an instance so is a 
     * static variable. This means its accessed via the class rather than via 
     * an instance of the class. 
     * This means Game Manager can be reached from other scripts with code 
     * `GManager.instance.xxx = whatever`  
     * So only one GManager instance will be running. This is a singleton pattern. 
     ***/
    public static GM instance = null;


    private GameObject clonePaddle;

    // Use this for initialization
    void Awake () 
    {
        if (instance == null)
            instance = this;
        else if (instance != this)
            Destroy (gameObject);

        Setup();

    }

    public void Setup()
    {
       ...
    }

Please read my solution below:

\$\endgroup\$
0
\$\begingroup\$

November 2016 - How to set up a singleton to avoid NullReferenceErrors.

Solution working with Unity 5.4.2f2

As detailed by this very good post by Clear Cut Games, we need to check not only for if instance = this but also if instance = null and if so then destroy and regenerate the instance of the class.

So the above Awake code should be rewritten as:

void Awake () {
    /***
     * Enforce Singleton Pattern described above. 
     ***/
    if(instance != this && instance != null)
    {
        Destroy(gameObject);
    }
    instance = this;
    Setup();

}

public void Setup()
{
   ....
}

It seems the tutorial made some assumptions about the instance value on awake and didn't check both values. This really confused me so to go over what changed:

If the instance is set (loaded) and is not this instance, then it is destroyed . This enforces singleton pattern.

If the instance is not null , so it is set, and yet is not this then the instance is destroyed.

After this, the instance becomes the current one defined as this.


There may well be variations on this rearrangement which work better for class calls that may have potentially more than one instantiation (unlike in this referenced tutorial), so please feel free to add a complete answer for other logics.

For that reason this is a community wiki :). Please improve my answer!!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.