Why create Singletons that extend ScriptableObjects?

Trying to get my head wrapped around ScriptableObjects by watching this Unite 16 talk

At one point (25:00) Richard talks about ‘Reload Proof Singletons’.
But I am still confused.
Why would you want to extend ScriptableObject when creating Singletons?

What would be the advantage(s)?
Can anyone provide some specific examples?

recently i’ve been using a ScriptableObject singleton to create a AssetDatabase for my games. So any script can get a sprite, prefab, sound etc by calling SPAssetDatabse.instance.GetAsset (someAssetID)

makes inspectors a little bit cleaner :slight_smile:

in his example it was merely so that the data gathered into the singleton in play persists to the next play session (iirc he shows an example of this in one of the tanks games examples in that talk)

Usually, when you want a singleton, you want to access a specific instance. you don’t want to worry if that instance doesn’t exist yet. and you usually want all your classes to access that same instance. Thats why when the typical game dev needs to write a manager, they write it as a singleton, just so that everything uses the same instance. but in reality singletons is just a shallow means to an end. Most classes only need to use the same instance, they don’t need to use singletons. Injecting ScriptableObjects solves both of the issues singletons are used to fix.

  • You can create them in the editor mode so they will always already exist before any script would try to use it (eliminating any worry of race conditions).
  • As an Asset you can easily have the classes that would need that manager simply have an exposed field and then you can “inject” that manager into the script via the inspector, thus allowing all classes needing the manager to all use the same instance.

… But without all the headaches Singletons come with on larger, more complex projects (such as high coupling, no polymorphism, and problematic unit testing)

and thats what scriptable objects are great for. you create that scriptableobject and then via the inspector you “inject” that same instance to all your classes that need it. it allows for polymorphic managers. the injection makes unit testing a ton easier. and coupling is drastically reduced (can be reduced even further via extension methods and interfaces).

3 Likes

scriptableObjects provide persistence since they are “project level” assets not “scene level” objects/components.
singleton pattern is to ensure there is only ever one instance of that object.

So why would you have a singleton scriptableObject… zip to 47:50 and you’ll see examples in that project. The gamestate is a “reload proof singleton”. There is going to only ever be one gamestate, The current gamestate. Then there is also settings which is also a reload proof singleton, there is only going to ever be one settings asset. Being scriptableObjects they’ll retain their values between plays of the game.

I’ve never thought of using scriptable objects that way! Fantastic idea! You should write up a blog post or something about it with a typical “lazy gamedev singleton manager” being switched for a scriptable object instead :slight_smile: Or do you maybe have a reference to point to which already exists?

EDIT: When I talk about “lazy game dev” here I mean myself of course :wink:

1 Like

Creating a singleton is not that difficult but effectively it is always same patterns we have to write again and again.

In this video, there is also an interesting delegate objects pattern example, used for reusability. Reusablity is something really missing in Unity. My GameRules extension really focus on that point. You just have to create a logic rule BoostHealth increasing the health, and this logic rule can then been reused in any Monobehaviour Flow or State Machine rule. Same thing for any other rule type. After, the rule assembly just pick correct rule (version, inheritance, …) and generates contextual code.

Like the video everyone has referenced in this thread? :slight_smile:

4 Likes

I’ll check it out ASAP :slight_smile: I was under the impression that @JoshuaMcKenzie was talking about a different approach than the video so didn’t look into the video. I may have been wrong though.