Unity version: 2021.3.7f1
Unity Design Patterns implementations, to shared across projects as an UPM package. Below you can see which patterns are implemented until here
Unity Singleton Monobehaviour component, that can be attached to Game Objects. You can use SingletonPersistent to persist the instance among scenes
or just Singleton class to use the same instance on the only one scene.
-
Managers that should use the same instance among scripts (e.g GameManager, ScoreManager, InputManager...)
-
When you need use any component that depends of a Game object in the scene (e.g access
AudioSourceinside of an singleton) -
When you need a Singleton with Unity messages like
Start(), and/or access some objects that are only available after the game starts(e.g Audio Middlewares, Third Party packages/libraries...)
Consider use a ScriptableObject instead
Create a script that inherits from Singleton<MyScript> passing the script class by generics:
public class GameManager : Singleton<GameManager> {
...
}In any other script, access the Instance property. The value of this property should be equal from any script:
public class PlayerController : Monobehaviour {
private void Awake() {
// Get the singleton instance
var gameManager = GameManager.Instance;
}
}If you wish a singleton that persists among scenes, you can create a class that inherit from SingletonPersistent:
public class GameManager : SingletonPersistent<GameManager> {
...
}By default, when a new scene is loaded and there is the same game object with the same script component (e.g GameManager above), the previous instance from the previous scene will be destroyed and will remains just one instance under DontDestroyOnload Unity scene.
Optionally, it's possible pass custom configurations to a SingletonPersistent script with SingletonSettings C# attribute:
// Here if the same gameObject with the same script
// exists in another scene, the next one will be
// destroyed and the GameObject reference fields
// will be copied to the previous
[SingletonSettings(CopyFieldsValues = true, DestroyGameObject = PersistentDestroyOrder.NEXT)]
public class GameManager : SingletonPersistent<GameManager> {
...
}For more details, see
Tests/Runtime/Examplesscripts examples
A base Factory Method implementation for Unity. The main use case here is to use this to access a gameObject in the scene that contains a script that implements an C# interface:
// Create a C# interface
public interface IMyComponent
{
}
// Create a MonoBehaviour script that implements the interface above, and attach it to a gameObject in the scene
public class MyScript : MonoBehaviour, IMyComponent
{
}
// Example to access the a gameObject script that implements an interface
using System.Linq;
using UnityEngine;
using UnityPatterns;
public class ExampleScript : MonoBehaviour
{
public GameObject[] rootsFromDontDestroyOnLoad;
void Start()
{
IMyComponent myComponent = FactoryComponent.Get<IMyComponent>();
// (Optional) You can get the all gameObjects with a script that implements an interface
List<IMyComponent> myComponent = FactoryComponent.GetList<IMyComponent>();
Debug.Log($"The component is: {myComponent.GetType().Name}") // Prints: MyScript
}
}Also, it's possible get a ScriptableObject instance from an interface or a class:
// Create a C# interface
public interface IMyScriptable
{
}
// Create a MonoBehaviour script that implements the interface above, and attach it to a gameObject in the scene
[CreateAssetMenu(fileName = "MyScriptable", menuName = "Data/Samples/MyScriptable")]
public class MyScriptable : ScriptableObject, IMyScriptable
{
}
// Example to access the a gameObject script that implements an interface
using System.Linq;
using UnityEngine;
using UnityPatterns;
public class ExampleScript : MonoBehaviour
{
public GameObject[] rootsFromDontDestroyOnLoad;
void Start()
{
// Get a ScriptableObject instance from an interface
IMyScriptable myScriptable = FactoryComponent.Get<IMyScriptable>();
// Get a ScriptableObject instance from a class
MyScriptable myScriptable = FactoryComponent.Get<MyScriptable>();
Debug.Log($"The component is: {myScriptable.GetType().Name}") // Prints: MyScriptable
}
}-
Get singleton managers from all scenes active scenes (including
DontDestroyOnLoadautomatic scene created by Unity). -
Get any gameObject from scenes that contains a script that implements an
C#interface. -
Get a
ScriptableObjectthat implements anC#interface or a from class reference. The last one is great to get an instance that automatically callInit()method.
Under Samples~ folder, this package share some code templates to easily create singleton classes from Unity Editor.
To use that, follow the steps below:
- On Unity Editor, click on
Window=>Package Manager - On the opened window, find the package
Unity Design Patterns...and import the sample: ScriptTemplates - Move the imported folder
ScriptTemplatesto your rootAssetsfolder in your Unity game project. - Restart the Editor
- Openup again, and press right click on any folder of your game project, and check if appears:
Create=>Custom Templates=>UnitySingleton:)
The implementation here was based in this gist above!!