Scriptable object as database?

Hi guys,

scriptable objects are a great tool, but one thing I have a hard time with is, how to make them available globally (so for every scene). What I‘m basically talking about is a database of scriptable objects, for example for an inventory (so, that I have always a single point of truth, where I can get all my items from).

What I thought about doing is to implement a static class, which in the static constructor is loading via Resource.Load all the scriptable objects I need.
Another way I thought about is to add a scriptable object for the database, which contains all the information I need, and is then again loaded via Resource.Load in the constructor of my globally accessible static class.
So the only “actual” difference is, that in the former approach the static class itself is the database and loads all the objects and in the second it is more or less only a reference to the database.

But is any of these two options considered a good practice? Is there an even better way?

Thanks for your help! :slight_smile:

Could you elaborate on why you need them available “globally”?

Their power is in the ability to drag and drop references in the inspector.

Hi GroZZleR,

of course: I have a scene before the “main” game scene, in which the user picks some items, that he/she uses in the main scene. In that scene I need to list all items and then the selected items are used int he main game scene (but still are taken from the global db.

Trying to understand that one as well. You have to be more specific.

Scriptable objects are primarily used as assets (of course you can create temporary ones at runtime, but that’s a different topic), and assets do not belong to a specific scene, but can be referenced by scenes. That makes them “available” to all your scenes, just like all the other assets in your project. The only thing you need to do is what @GroZZleR has already pointed out: link them via inspector, or load them at runtime.

1 Like

You can drag and drop reference of SOs in the inspector or you can use the AssetDatabase.FindAssets function to find the asset and load it. See an example here (the green answer): How can I find all instances of a Scriptable Object in the Project (Editor) - Questions & Answers - Unity Discussions

1 Like

Checkout this free asset that does singletons with SO. yaSingleton | Integration | Unity Asset Store

1 Like

Thank you all very much! :slight_smile:

@Suddoha
Let‘s say you have inventory items in your project. Each inventory item is defined as an SO.
For each map/level in that project you have a scene and the “problem” is that you need the list of available inventory items in each scene. Adding the item database as a game object to each map would get old pretty soon and of course you would need to make sure that whenever you add another item that you update the item list in every game object on each scene.
Having the inventory list only initialised once and shared across all the scenes, so making it available globally, seems to me like the best solution.

@
Thanks! But my question is less about how to code it, but more about which approach is considered a good practice in the described scenario.

@tcmeric
Thanks, I will check it out!

Well, Resources.Load is almost always (99.9% of the time) a bad practice, so there is that.

1 Like

That’s achievable in the same way.

Make an SO that serves as database, and create one instance of it. Then, just link all the items to the database SO instance. The only thing you’ll ever need to associate to the accessors of the item database is the database object itself, not each item.
When you need to add new items, you’d just add them to the existing database SO instance, and they’ll be available to everyone who accesses this instance, because they’re not referenced directly, but through that database SO.

You could as well replace the existing database with a duplicate instance that you manipulate instead. That’ll help to preserve the previous version until you no longer need them.

1 Like

@
That‘s what I assumed, but using that was the only solution I could think of.

@Suddoha
Thank you! So, if I get this right, this is what I described as the second option, but without the part of loading the database via Resource.Load in the code and instead assigning it to the script that requires it directly via the inspector, right?

@Suddoha
Thank you! So, if I get this right, this is what I described as the second option, but without the part of loading the database via Resource.Load in the code and instead assigning it to the script that requires it directly via the inspector, right?[/QUOTE]

Yes, it’s similar. But you don’t necessarily need statics.