Unity Design Patterns
Provides well-tested implementations of common design patterns as reusable components for Unity projects. Includes Singleton and SingletonPersistent for manager classes, Factory Method patterns, and full source code with runtime examples. Distributed as a UPM package compatible with Unity 2021.3.7f1 and later.
com.mfdeveloper.unitypatterns 
Install via UPM
Add to Unity Package Manager using this URL
https://www.pkglnk.dev/unitypatterns.git README Markdown
Copy this to your project's README.md
## Installation
Add **Unity Design Patterns** to your Unity project via Package Manager:
1. Open **Window > Package Manager**
2. Click **+** > **Add package from git URL**
3. Enter:
```
https://www.pkglnk.dev/unitypatterns.git
```
[](https://www.pkglnk.dev/pkg/unitypatterns)Dependencies (3)
README
Unity Patterns
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
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.
Main use cases
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
Getting started
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;
}
}
Persistent Singleton
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.
Persistent Singleton: Optional settings
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
Unity: Factory Method
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
}
}
Main use cases
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.
Code templates
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:)
References
The implementation here was based in this gist above!!
No comments yet. Be the first!