Global state in the Unity engine

In games, it’s often helpful to use “global state”; a design pattern where the state of the game is managed in one or more central system(s) and accessed via a global interface (accessible automatically by all other game systems). I know Godot has a built-in system which allows the user to easily create scriptable globals for their game, but how do I implement this in Unity?
As far as I know, Unity does not support “global” MonoBehaviours, so scripts in a game must request a component MonoBehaviour from a GameObject in the current scene, in order to access its data (this significantly complicates the development workflow, as any “global” object(s) must be manually created for every scene in the game, or hosted in a “common” scene if the global is responsible for managing a specific game state).

Due to the complications regarding global state in Unity, I’m looking for an easier way of implementing it for all the things in my game that have to be global (like a “global” variant of MonoBehaviour that gets attached to the game itself instead of a specific GameObject, or a C# interface that can be implemented in my scripts allowing them to access globals).

And yes, before some of you (you know who you are) rush over to tell me about how “controversial” global state is, and that it’s “bad practice” in programming, I have to say I’m fully aware. I’m only using global state because I believe it’s the solution to my problem (and therefore asking people more experienced with Unity scripting than myself, how to implement it); I’m not asking for you to give me reasons why it’s not.

1 Like

Singleton Patern will do!

All you have to do in Unity/C# to get a Global Variable like in Godot is to add the static keyword before a field or a property.

You can also create a scriptable object asset, and drag-and-drop it into serialized fields on all the components that needs to reference its members. This is a bit more work, but can have some benefits, like the fact that the scriptable object can implement interfaces and be passed to methods as an argument.

If you need these objects to be components in particular, then you can use a singleton that creates an instance on-the-fly the moment that something asks for it for the first time, or a preload scene.