In Unity, whats a good way to create a singleton game manager that can be accessed everywhere as a global class with static variables that will spit the same constant values to every class that pulls those values? And what would be the way to implement it in Unity? Do I have to attach it to a GameObject? Can it just be there in a folder without being in the scene visually?
Generally speaking, a singleton in Unity is a globally accessible class that exists in the scene, but only once. The idea is that any other script can access the singleton, allowing you to easily connect objects to important parts of the game, such as to the player or to other game systems.
Singleton pattern lets you write a class, which can only be instantiated once. Singleton pattern is a very useful, yet it's a very simple design pattern. It restricts instantiation outside the class by making constructor private. public class Singleton : MonoBehaviour{ //create an object of Singleton.
Creating well-defined relationships between classes would naturally decrease the need of having a Singleton. Your design must be coherent as much as possible but we all know that. Regardless of that it still can get messy when the code base is getting bigger.
Like always: it depends. I use singletons of both kinds, components attached to GameObject
and standalone classes not derived from MonoBehaviour
. IMO the overall question is how are instances bound to the lifcycle of scenes, game objects, ... And not to forget sometimes it is more convenient to have a component especially referencing other MonoBehaviour
objects is easier and safer.
Start
is called or have to perform actions in Update
or other methods. Then I implement them as component and attach them to a game object that survives loading new scenes.I designed component based singletons (type 2) with two parts: a persistent GameObject
called Main
, which holds all components and a flat singleton (type 1) called MainComponentManager
for managing it. Some demo code:
public class MainComponentManger { private static MainComponentManger instance; public static void CreateInstance () { if (instance == null) { instance = new MainComponentManger (); GameObject go = GameObject.Find ("Main"); if (go == null) { go = new GameObject ("Main"); instance.main = go; // important: make game object persistent: Object.DontDestroyOnLoad (go); } // trigger instantiation of other singletons Component c = MenuManager.SharedInstance; // ... } } GameObject main; public static MainComponentManger SharedInstance { get { if (instance == null) { CreateInstance (); } return instance; } } public static T AddMainComponent <T> () where T : UnityEngine.Component { T t = SharedInstance.main.GetComponent<T> (); if (t != null) { return t; } return SharedInstance.main.AddComponent <T> (); }
Now other singletons that want to register as Main
component just look like:
public class AudioManager : MonoBehaviour { private static AudioManager instance = null; public static AudioManager SharedInstance { get { if (instance == null) { instance = MainComponentManger.AddMainComponent<AudioManager> (); } return instance; } }
Engineers who are new to Unity often don't notice that
It is meaningless.
All you have in Unity is GameObjects, at, XYZ positions. They can have components attached.
It would be like trying to have "a singleton" or "inheritance" in .... Photoshop or Microsoft Word.
Photoshop file - pixels at XY positions
Text editor file - letters at X positions
Unity file - GameObjects at XYZ positions
It is "just that simple".
So, in a game you will have "general" behaviors where there is only "one" of the thing. (So obviously there is only "one sound effects engine" , "one screen", "one scoring system" and so on.) A normal programmer would think of those as "singletons", but Unity just has nothing to do with singletons and no connection to singletons.
So if you have "a tank" or "a tree" of course it's normal you may have dozens of those things. But "the sound effects engine" or "the networking system" are "general, only-one-of-them" systems.
Hence, trivially, in Unity "the sound effects engine" or "the networking system" very simply sits on a game object, and, you (obviously) just have the one of them.
Those "general, only-one-of-them" items just sit on the preload scene.
You absolutely have to have a preload scene anyway, in every Unity project.
(Simple how-to: https://stackoverflow.com/a/35891919/294884 )
In the future Unity will include a "built-in preload scene" - when that day comes this will finally never be discussed again!
(Note - some of the languages you use to compile Components for Unity of course have OO concepts; but Unity itself has no connection to OO at all. Unity is like photoshop. You have "game objects" each at a certain 3D position.)
(Note - in the early days of Unity you'd see attempts at making code, say c#, which creates a game object on the fly, attempts to keep the game object unique, and "attaches itself" to the game object as a component. Apart from being completely bizarre/pointless, just FWIW it's theoretically not possible to ensure uniqueness (actually not even within a single frame). Again, it's moot because in Unity general behaviors just go on the preload scene.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With