by

ScriptableObject architecture series – ScriptableSingletons

In an ideal dev environment, we want to be able to drag any object into an empty scene, press play, and be able to test it by itself. Characters, UI, everything.

Turning Monobehaviours into singletons makes that dream unachievable. Countless times playing an empty scene with a simple character spits out a null reference because there’s no Gamecontroller.Instance.StartingHealth.

Inspired by Richard Fine’s GDC talk, a great way around this is to keep all this stuff on a scriptable object.

Here’s a simple GameSettings script, which inherits from our magic ScriptableSingleton class:

On it, we keep normal, basic information we need across our game.

The magic is in the base class:

Here, we are inheriting from ScriptableObject instead of Monobehaviour so we can create a .asset file from the right-click menu. The  where T: ScriptableObject is something we must have when creating a generic class. Info here. In this case, we’re just saying that children inheriting from this class are also ScriptableObjects but this could be anything else e.g. implements an interface.

The getter for the instance variable is not much different to classic Monobehaviour singletons. On line 10, if there’s no instance already, instead of instantiating one, we load an object of type <T> from the Resources folder in our Unity project and on line 12, we’re logging an error to remind ourselves to create one because we still couldn’t find one.

As long as we’ve created a GameSettings.asset in the Resources folder, we can call  GameSettings.Instance.IsDebugMode  even from an empty scene, and values changed during play mode are saved.

Write a Comment

Comment