Skip to content

A useful implementation of the singleton pattern for Unity3d

License

Notifications You must be signed in to change notification settings

SteBeeGizmo/Singleton

Repository files navigation

##Singleton

A useful implementation of the singleton pattern for Unity3d

The singleton pattern is a very common way to share data and methods across classes in Unity. This code provides an easy-to-use implementation of this pattern that satisfies three goals:

  • Minimal clutter in singleton classes: All a singleton need do is derive from Singleton rather than MonoBehaviour, and then call base.onAwake() in its Awake() method.
  • Supports both lazy and explicit instantiation: When a singleton is referenced, if it already exists that instance is used; if it doesn't exist, a new instance is created.
  • Supports both global and scene-level singletons: Usually you want your singletons to persist across scene changes, but sometimes you want a singleton to be flushed out of memory when a new scene is loaded. Both options are available with this system.

Usage

  1. Derive your singleton component from Singleton<T> rather than MonoBehaviour. Replace the T with the name of your class.
  2. You must call onAwake() in your component's Awake() method.
  3. [Optional] If you want your component to be destroyed when a new scene is loaded, you must override isGlobalScope to return false. You must also give it an OnDestroy handler: void OnDestroy() { base.onDestroy(); }

As part of the initialization process, every singleton is renamed with an underscore followed by the name of the class. When a singleton is lazily instantiated, it is created as the child of a GameObject at the root named _SingletonManager, and its name is followed with " [autogenerated]".

If an instance of a singleton is explicitly instantiated while another instance already exists, the new instance is destroyed and a warning is reported. It is thus safe to explicitly instantiate singletons in each of your scenes if desired.

Each singleton is accessed via ClassName.Instance. For the convenience your callers, you might want to create static methods and properties of your singletons. Just have such methods reference ClassName.Instance internally. Because of lazy instantiation, this property will never return null, unless something unrecoverably disastrous has happened.

Example

using UnityEngine;
using System.Collections;

public class YourSingletonClass : Singleton<YourSingletonClass>
{
	void Awake()
	{
		// You MUST call the base class onAwake() method
		//	before you exit Awake().
		onAwake();
	}

	public bool SomeOtherClassExistsNow = false;
	
	public float Scale = 0.5f;
	
	public void static SetScale(GameObject target)
	{
	  target.transform.localScale = Vector3.one * YourSingletonClass.Instance.Scale;
	}
}
using UnityEngine;
using System.Collections;

public class SomeOtherClass : MonoBehaviour
{
  void Start()
  {
    YourSingletonClass.Instance.SomeOtherClassExistsNow = true;
    
    YourSingletonClass.SetScale(gameObject);
  }
}

Other Classes

This code includes a couple of existing singletons, both as an example of usage and to provide services that the singleton system itself needs.

  • DebugManager: Wraps access to Unity's Debug.Log() method, to simply string formatting and to allow logging to be disabled in release builds.
  • GlobalsManager: A simple class for storing global variables, such as config settings.

Design & Acknowledgements

The basic trick of this code, the "self-referential generic class", comes from the terrific article, "50 Tips for Working with Unity" by Herman Tulleken.

About

A useful implementation of the singleton pattern for Unity3d

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages