One excellent alternative to the singleton pattern in Unity is the use of ScriptableObjects as a type of global variable. Ryan Hipple from Schell Games gave a presentation at Unite Austin 2017 titled Game Architecture with Scriptable Objects that explains how to implement them and the many advantages over singletons.
Toolbox
The “Toolbox“ concept improves upon the singleton pattern further by offering a different approach that makes them more modular and improves testability.
Introduction
The singleton pattern is a way to ensure a class has only a single globally accessible instance available at all times. Behaving much like a regular static class but with some advantages. This is very useful for making global manager type classes that hold global variables and functions that many other classes need to access. However, the convenience of the pattern can easily lead to misuse and abuse and this has made it somewhat controversial with many critics considered it an anti-pattern that should be avoided. But like any design pattern, singletons can be very useful in certain situations and it’s ultimately up to the developer to decide if it’s right for them.
Advantages
Globally accessible. No need to search for or maintain a reference to the class.
Persistent data. Can be used to maintain data across scenes.
Supports interfaces. Static classes can not implement interfaces.
Supports inheritance. Static classes can not inherent for another class.
The advantage of using singletons in Unity, rather than static parameters and methods, is that static classes are lazy-loaded when they are first referenced, but must have an empty static constructor (or one is generated for you). This means it’s easier to mess up and break code if you’re not careful and know what you’re doing. As for using the Singleton Pattern, you automatically already do lots of neat stuff, such as creating them with a static initialization method and making them immutable.
Disadvantages
Must use the Instance keyword (e.g. .Instance) to access the singleton class.
There can only ever be one instance of the class active at a time.
Tight connections. Modifying the singleton can easily break all other code that depends on it. Requiring a lot of refactoring.
No polymorphism.
Not very testable.
Implementation
The singleton pattern is commonly applied to multiple classes but the implementation is always the same. So creating a singleton base class others can inherit from is ideal because it eliminates the need to recreate the same code over and over again for each class that needs to be a singleton.
Notes:
This script will not prevent non singleton constructors from being used in your derived classes. To prevent this, add a protected constructor to each derived class.
When Unity quits it destroys objects in a random order and this can create issues for singletons. So we prevent access to the singleton instance when the application quits to prevent problems.
///<summary> /// Inherit from this base class to create a singleton. /// e.g. public class MyClassName : Singleton<MyClassName> {} ///</summary> publicclassSingleton<T> : MonoBehaviourwhereT : MonoBehaviour { // Check to see if we're about to be destroyed. privatestaticbool m_ShuttingDown = false; privatestaticobject m_Lock = newobject(); privatestatic T m_Instance;
///<summary> /// Access singleton instance through this propriety. ///</summary> publicstatic T Instance { get { if (m_ShuttingDown) { Debug.LogWarning("[Singleton] Instance '" + typeof(T) + "' already destroyed. Returning null."); returnnull; }
lock (m_Lock) { if (m_Instance == null) { // Search for existing instance. m_Instance = (T)FindObjectOfType(typeof(T));
// Create new instance if one doesn't already exist. if (m_Instance == null) { // Need to create a new GameObject to attach the singleton to. var singletonObject = new GameObject(); m_Instance = singletonObject.AddComponent<T>(); singletonObject.name = typeof(T).ToString() + " (Singleton)";
// Make instance persistent. DontDestroyOnLoad(singletonObject); } }
* The latest version of [CMake](https://cmake.org) (3.16 or greater) * [Ninja](https://ninja-build.org) build system * And a compiled version of the `aseprite-m102` branch of the [Skia library](https://github.com/aseprite/skia#readme). There are [pre-built packages available](https://github.com/aseprite/skia/releases). You can get some extra information in the [*laf* dependencies](https://github.com/aseprite/laf#dependencies) page.
## Windows dependencies
* Windows 10 (we don't support cross-compiling) * [Visual Studio Community 2022](https://visualstudio.microsoft.com/downloads/) (we don't support [MinGW](#mingw)) * The [Desktop development with C++ item + Windows 10.0.18362.0 SDK](https://imgur.com/a/7zs51IT) from the Visual Studio installer
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.