Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have seen several videos and tutorials for creating singleton objects in Unity, mainly for a GameManager, that appear to use different approaches to instantiating and validating a singleton.

Is there a correct, or rather, preferred approach to this?

The two main examples I have encountered are:

First

public class GameManager
{
    private static GameManager _instance;

    public static GameManager Instance
    {
        get
        {
            if(_instance == null)
            {
                _instance = GameObject.FindObjectOfType<GameManager>();
            }

            return _instance;
        }
    }

    void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }
}

Second

public class GameManager
{
    private static GameManager _instance;

    public static GameManager Instance
    {
        get
        {
            if(_instance == null)
            {
                instance = new GameObject("Game Manager");
                instance.AddComponent<GameManager>();
            }

            return _instance;
        }
    }

    void Awake()
    {
        _instance = this;
    }
}

The main difference I can see between the two is:

The first approach will attempt to navigate the game object stack to find an instance of the GameManager which even though this only happens (or should only happen) once seems like it could be very unoptimised as scenes grow in size during development.

Also, the first approach marks the object to not be deleted when the application changes scene, which ensures that the object is persisted between scenes. The second approach doesn't appear to adhere to this.

The second approach seems odd as in the case where the instance is null in the getter, it will create a new GameObject and assign a GameManger component to it. However, this cannot run without first having this GameManager component already attached to an object in the scene, so this is causing me some confusion.

Are there any other approaches that would be recommended, or a hybrid of the two above? There are plenty of videos and tutorials regarding singletons but they all differ so much it is hard to drawn any comparisons between the two and thus, a conclusion as to which one is the best/preferred approach.

share|improve this question
    
What is said GameManager supposed to do? Does it have to be a GameObject? – bummzack Feb 2 at 14:27
    
It's not really a question of what the GameManager should do, rather how to ensure there are only ever one instance of the object and the best way to enforce that. – CaptainRedmuff Feb 2 at 15:01
up vote 6 down vote accepted

It depends, but usually I use a third method. The problem with the methods that you used is that in the event that the object is included to begin with, it will not remove them from the tree, and they can still be created by instantiating too many calls, which could make things really confusing.

public class SomeClass : MonoBehavior {
    private static SomeClass _instance;

    public static SomeClass Instance { get { return _instance; } }


    private void Awake()
    {
        if (_instance != null && _instance != this)
        {
            Destroy(this.gameObject);
        } else {
            _instance = this;
        }
    }
}

The problem with both of your implementations is that they do not destroy an object that is created later. It could work, but one could throw a monkey wrench into the works that could result in a very difficult to debug error down the line. Make sure to check in Awake if there is an instance already, and if so, destroying the new instance.

share|improve this answer
1  
You might also want OnDestroy() { if (this == _instance) { _instance = null; } }, if you want to have a different instance in each scene. – Dietrich Epp Feb 3 at 0:34

Here's a quick summary:

                 Create object   Removes scene   Global    Keep across
               if not in scene?   duplicates?    access?   Scene loads?

Method 1              No              No           Yes        Yes

Method 2              Yes             No           Yes        No

PearsonArtPhoto       No              Yes          Yes        No
Method 3

So if all you care about is global access, all three get you what you need. Use of the Singleton pattern can be a bit ambiguous about whether we want lazy instantiation, enforced uniqueness, or global access so be sure to think carefully about why you're reaching for the singleton, and choose an implementation that gets those features right, rather than using a standard for all three when you only need one.

(eg. if my game will always have a GameManager, maybe I don't care about lazy instantiation - maybe it's only global access with guaranteed existence & uniqueness I care about - in which case a static class gets me exactly those features very concisely, with no scene loading considerations)

...but definitely don't use Method 1 as written. The Find can be skipped more easily with Method2/3's Awake() approach, and if we're keeping the manager across scenes then we very likely want duplicate-killing, in case we ever load between two scenes with a manager already in them.

share|improve this answer
    
Note: it should be possible to combine all three methods to create a 4th method that has all four features. – Draco18s Feb 2 at 18:09
    
My answer below is Yes, Yes, Yes, Yes. – Evorlor Feb 6 at 20:38

I'd just like to add that it may be useful to call DontDestroyOnLoad if you want your singleton to persist across scenes.

public class Singleton : MonoBehavior 
{ 
    private static Singleton _instance;

    public static Singleton Instance 
    { 
        get { return _instance; } 
    } 

    private void Awake() 
    { 
        if (_instance != null && _instance != this) 
        { 
            Destroy(this.gameObject); 
        } 
        else 
        { 
            _instance = this;
            DontDestroyOnLoad(this.GameObject);
        } 
    } 
}
share|improve this answer
    
That's very handy. I was just about to post a comment on @PearsonArtPhoto's response to ask this exact question :] – CaptainRedmuff Feb 2 at 15:32

Another option might be to split the class into two parts: a regular static class for the Singleton component, and a MonoBehaviour that acts as a controller for the singleton instance. This way you have full control over the singleton's construction, and it will persist across scenes. This also lets you add controllers to any object that might need the singleton's data, instead of having to dig through the scene to find a particular component.

public class Singleton{
    private Singleton(){
        //Class initialization goes here.
    }

    public void someSingletonMethod(){
        //Some method that acts on the Singleton.
    }

    private static Singleton _instance;
    public static Singleton Instance 
    { 
        get { 
            if (_instance == null)
                _instance = new Singleton();
            return _instance; 
        }
    } 
}

public class SingletonController: MonoBehaviour{
   //Create a local reference so that the editor can read it.
   public Singleton instance;
   void Awake(){
       instance = Singleton.Instance;
   }
   //You can reference the singleton instance directly, but it might be better to just reflect its methods in the controller.
   public void someMethod(){
       instance.someSingletonMethod();
   }
} 
share|improve this answer
    
This is very nice! – CaptainRedmuff Feb 2 at 20:09

I wrote a singleton class that makes easy to create singleton objects. Its is a MonoBehaviour script, so you can use the Coroutines. Its based on this Unity Wiki article, and I will add option to create it from Prefab later.

So you don't need to write the Singleton codes. Just download this Singleton.cs Base Class, add it to your project, and create your singleton extending it:

public class MySingleton : Singleton<MySingleton> {
  protected MySingleton () {} // Protect the constructor!

  public string globalVar;

  void Awake () {
      Debug.Log("Awoke Singleton Instance: " + gameObject.GetInstanceID());
  }
}

Now your MySingleton class is a singleton, and you can call it by Instance:

MySingleton.Instance.globalVar = "A";
Debug.Log ("globalVar: " + MySingleton.Instance.globalVar);

Here is a complete tutorial: http://www.bivis.com.br/2016/05/04/unity-reusable-singleton-tutorial/

share|improve this answer

I'll throw my singleton into the mix. It checks off all four of DMGregory's criteria (see his answer). This has a lot of stuff that may not make sense. It is just covering Unity specific corner cases, and persists between scenes. It is tried and tested, and the most current version can be found on my Github. Enjoy!

Usage is by having your script extend this class and pass itself as the generic type. Example:

public class MySingleton : ManagerBehaviour<MySingleton>{}

Here is the class itself, and bonus points if you can decipher the class signature!

using UnityEngine;

/// <summary>
/// Extending this class creates a MonoBehaviour which may only have on instance and will not be destroyed between scenes.  When extending, the type of the inheriting class must be passed.
/// </summary>
public abstract class ManagerBehaviour<ManagerType> : MonoBehaviour where ManagerType : ManagerBehaviour<ManagerType>
{
    private const string ManagerName = "Manager";

    private static ManagerType instance;

    /// <summary>
    /// Gets the singleton instance of the Manager
    /// </summary>
    public static ManagerType Instance
    {
        get
        {
            if (!instance)
            {
                instance = FindObjectOfType<ManagerType>();
                if (!instance)
                {
                    var instanceGameObject = GameObjectFactory.GetOrAddGameObject(ManagerName);
                    instance = instanceGameObject.AddComponent<ManagerType>();
                }
            }
            return instance;
        }
    }

    protected virtual void Awake()
    {
        DestroyDuplicateManagers();
        DontDestroyOnLoad(gameObject);
    }

    private void DestroyDuplicateManagers()
    {
        var managers = FindObjectsOfType<ManagerType>();
        foreach (var manager in managers)
        {
            if (!manager)
            {
                continue;
            }
            if (Instance != manager)
            {
                if (Instance.gameObject == manager.gameObject || manager.transform.childCount > 0)
                {
                    Destroy(manager);
                }
                else
                {
                    Destroy(manager.gameObject);
                }
            }
        }
    }
}
share|improve this answer

I will trow my implementation too for future generations .

void Awake()
    {
        if (instance == null)
            instance = this;
        else if (instance != this)
            Destroy(gameObject.GetComponent(instance.GetType()));
        DontDestroyOnLoad(gameObject);
    }

For me this line Destroy(gameObject.GetComponent(instance.GetType())); is very important because once I had left a singleton script on another gameObject in a scene and the whole game object was being deleted. This will only Destroy the component if it already exists.

share|improve this answer

There is actually a pseudo official way to use Singleton in Unity. Here is the explanation, basically create a Singleton class and make your scripts inherit from that class.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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