I don’t understand when I should use Scriptable Objects. they seem to complicate things in any scenario.
on top of all, scriptable objects would be great for storing data that would be used later in the game, such as player stats, card game data or pokemons information.
however in all these cases, I find it much more simpler and clear to open a starting script and creating new objects from there.
lets take the pokemon example,
I could make a scriptable object for a pokemon with hp, name, sprite and lets say attack moves.
I would make 200 instances of the scriptable object and load it in code later. in this way, I will deal with the data through the Unity Editor, in a special directory for pokemons.
this relies heavily on the editor folders and forces me to use Unity to manage the pokemons.
an alternative I beleive would be better is to just have one script, where I would use some kind of pokemon Builder to use c# beautiful syntax and just have all pokemons appear in one code. this would allow me to ctrl+f.
the pros would be that everything is orginized in one file, which I can vibe-code some website that can edit it or use different IDE’s to manage the “pokemon codebase”
also in code, I could add extra behaviour to each pokemon object, when in scriptable objects it seems like you usually don’t add functions to the object itself.
the cons would be that in the Unity editor, I could drag sprites and visual objects to the inspector and easily view the different items, but even than I could just paste all of these under some resources folder and load them at once on game start.
I am having a hard time finding a good use for scriptable objects, would love to see a good usage of this!
For small projects or those developed by a solo game developer, it’s true that ScriptableObjects can often be replaced with other structures without significantly affecting the workflow. In these cases, it’s mostly a matter of personal preference.
However, in large projects with multiple team members, ScriptableObjects become indispensable for several reasons. Consider a scenario where you have a character that needs stats. You could store those stats in either an SO or a plain old C# object (POCO), but ScriptableObjects offer key advantages:
No need to recompile the codebase. With SOs, you can simply drag and drop different assets within the Unity Editor. If you’re using a class that gets injected through code, any change requires modifying the code and triggering a recompilation, which can be time-consuming in large projects.
One of the main points in Ryan Hipple’s video on ScriptableObjects is that they allow game designers to tweak values and behaviors without touching the code. This minimizes the risk of breaking something and removes the dependency on programmers for every small change. SO’s are non-programmer friendly.
They improve QA workflow. Similarly, you don’t want QA testers or other non-programmers editing code or needing help from developers every time a change is required. With SOs, you can create multiple configurations with different stats or behaviors that can be easily swapped via drag and drop in Unity.
SO’s are also good for testing. I also don’t like switching to Unity when I’m coding, but when I playtest the game, is very useful and considerably faster to have SO’s with different data and behaviors, some of them acting as data containers and others as mediators that point to different behaviors to test different aspects of the game without having to leave Unity and change the code in my IDE.
In my experience, these are the main scenarios where ScriptableObjects outperform other solutions and POCO’s. They enable quick, engine-integrated changes, which is especially valuable in large projects or when your code is used by non-programmers.
I’m sure others will have additional use cases to share that I haven’t mentioned here.
I mean, if you don’t like it then don’t use it. But, your non-programming designers might not be nearly so keen to crack open Visual Studio and mess around with a syntax they don’t understand and constantly make typing mistakes while having zero context or guidelines on what to do and how to do it. Some people like the idea of code as data. Others do not. It really comes down to your team and the workflow that you’ve agreed upon to use for the project. Of course, the best way to decide that is to investigate various options during pre-production so I’ve linked a video below that shows a pretty good example.
The biggest and most obvious benefit is the one you already mentioned: That it automatically just works with Unity’s inspector and serialization system. Don’t discount how convenient it is to just be able to drag a new SO asset into a field in an inspector and just instantly see the effects. It also means you can make live changes while playing which is super nice. Something you can’t always do with code unless you want to try hot reloading which comes with its own set of issues that need to be strictly managed and accounted for at all times.
Another factor is that with your single-file system, everything is fine until multiple people try to get in there and edit something and then commit the changes - chaos ensues and suddenly you’re all back at the meeting room deciding on a new workflow. No one wants to go back to the dark ages of passing an actual, physical hat around the room that signifies which person is currently editing a specific file This can still happen with SOs or really any kind of file-based system. But at least the damage and merge issues can usually be discovered and isolated before it goes beyond a single data entry.
the only thing that bugs me about SO is that any changes in value in the editor stick but outside, dont.. so in my mind it can make testing things much harder..
I’ve been using Unity for years and I’ve never used Scriptable Objects. But that’s probably because I mostly do procedural stuff and so my data isn’t created by me. If I were to create some kind of Pokemon game then the characters would be generated by a script.
Taking from this that scriptable objects are great solutions when working with team members who doesn’t touch the code.
at this point if it was up to me, I would probably create a special manager platform for them to edit the data even though Unity gives a pretty good start for such thing.
for me working by myself now, scriptable objects are probably just not for me…
Working solo I still use scriptable objects a ton. It’s still a lot quicker to author data through assets than to have everything hard coded. Not to mention how much faster your iteration is when you can play around with values even during play mode.
Combined with [SerializeReference], they make for great pluggable behaviour.
All of my games use a system built around SOs. It allows me to define any action a character can take. It’s also tied to my inventory system so items can be defined in terms of what they do.
So if I have a character that is swinging a sword and I want to change the speed of it, or the damage, or the hit window I can just edit the SO. But I can also swap to a different item entirely just by dragging a new asset. Or I can add entirely new effects. Maybe I want a different sound to play? Or to spawn some particles? Or I want the sword to shoot a laser beam when I swing it? Or chain with a combo attack? Or perform an air dash? Or change my move speed? Or kill the player? Or grant invincibility? Or cause a massive explosion when equipped? Or transform into a completely different item when it lands a hit? I can test out any of these things without ever leaving play mode much less having to edit some textfiles, wait for a recompile, and then load up the scenario again.
Another nice thing is that if you can have a lot of common data that is shared by many instances. Lots of my NPCs use the same weapons but most of that data only exists as one instance in memory.
He’s talking about modifying them in the editor while play mode is active since changes to them don’t reset once you stop play mode. That said like @meredoth mentioned earlier there’s a video about using them at runtime as an architecture storing your game data in ScriptableObjects making it easy to modify and link them to where they need to be. Just keep in mind if you watch the video the example given isn’t a complete one. You would want more than he’s showing to make good use of it.
There’s a lot of valuable presentations from the older Unites before the company started chasing the latest trends like AI, and in many cases because the scripting system hasn’t really changed it’s often almost if not directly usable despite the age.
SOs are useful whenever you want to separate data from implementation.
E.g. I’m using several SO types for defining generators of ambiance fish swarms.
One SO configures the spawning conditions of a new swarm. Another one the type of fish (since they are particles, not prefab instances). Another configures the lifetime and fish-independent behavior of the swarm itself.
Technically I could do that in prefabs with monobehaviors but that simply feels like it has less of the necessary abstraction.
Despite being a solo dev, it helps me to keep data separate (at most having sanitizing or convenient data access methods on the SO).
Configuring via a custom filetype or text, json etc. on the other hand feels like total overkill and I’d give up the possibility to have a meaningful mask with tooltips etc. in the editor.
While you can host the same data that a ScriptableObject holds and make it available globally by adding that data to a MonoBehaviour whose object is put in DontDestroyOnLoad, the SO still is preferable:
MonoBehaviour Data
add it to GameObject
mark the GameObject DDOL
add this object to a scene
make sure you add this object to a scene that never, ever gets loaded again or you will duplicate the object
make the GameObject a singleton, and a non-defective one (any singleton that calls Destroy on itself is defective!)
edit the data on the Component inspector
if you need per-scene or per-object customization of that data:
if you need to edit that data but since the object is in a different scene, ups … okay, well, you could make that object a prefab asset ..
ScriptableObject Data
create the ScriptableObject instance
edit the data in the SO Inspector
assign a reference to the SO to any component that needs it
if you need per-scene or per-object customization of that data, you’d just create, edit and assign a variant of that SO
no need to prevent DDOL object duplication
no need to make a singleton
no need to switch scenes for editing respectively:
no need to apply prefab changes
So yeah, f… MonoBehaviour components that carry data! I probably forgot one or more nuisances and complications of having that data stored in the scene or in a prefab. For instance, it can be helpful to be able to apply mass changes, or just a custom editor. With editor scripting you can work with SO assets naturally, while working with scene-bound or prefab objects through editor scripting is just
The benefit of SOs will vary considerably with the way developers currently work. Not comparing it at all but we can see that people here often make things public that can benefit by being private. They access object references repeatedly in loops when the references cannot have changed.
It isn’t as dramatic of course but solutions are still based upon how developers develop.
Someone correct me if I’m wrong but I view SOs as “an intelligent asset”. We (for instance) have images that we access in code. What if you could attach code to that image? From simple Boolean properties like isIcon to something like preferred size. Now what if you could add methods to the image so it could resize to (say) one of 3 preferred sizes or convert to a monochrome version.
The examples are purely made up but SOs add programmability to what is essentially data. They can be subclassed as well which make them handier still.
Don’t go down the thought path of everything should be an SO. Everything needn’t be a data dictionary or a linked list but they are useful when the problem benefits from using them as a solution.
You’re not wrong but “attaching code to data” isn’t exclusive to ScriptableObject types. You can add both code and data to MonoBehaviour or System.Object types too.
The problem with MB is however that you’re going to carry a whole lot of functionality around that isn’t strictly necessary, including the ability to attach it to any GameObject and accessing the GameObject and Transform instances and so forth - whether it needs it or not. Whereas a plain C# class/struct is sometimes too barebones ie for anything where you need a subclass of UnityEngine.Object.
ScriptableObject hits that middle ground. It’s an asset, a first class citizen in the engine, but doesn’t carry all the behaviour inherited from the UnityEngine.Object=>Component=>Behaviour=>MonoBehaviour class hierarchy. That’s three levels of subclassing that you would want to avoid if you don’t need it AND you can’t just make it an asset without wrapping it in a GameObject turned prefab.
I also have not been convinced to use scriptable objects in my projects yet, though not for the same reason.
For me, making a repository prefab which contains child game objects, each having a component (or multiple) that stores the required data is an approach I like better.
First of all this way, I just have the single repository prefab asset, instead of multiple scriptable object assets for each item in the repository, which I prefer so there’s less items in my project search results etc.
I can also very quickly create a new item instance by just duplicating a game object and changing its script data. I don’t have to drag the new object anywhere. The repository items are automatically found and cached in a dictionary on game initialization using GetComponentsInChildren.
Another advantage is each repository item can easily have multiple different component scripts depending on its functionality. For example, for my item repository, some of my items have a consumable component, some have an equipable component etc. With scriptable objects I think this functionality would add complexity as it’d require using inheritance, which is a limitation compared to a component system where any item can have any number of components.
I know that using my prefab system means more unnecessary game object, transform, and component data in memory, and I also know that scriptable objects are more convenient in the sense that you can easily modify their data at runtime and have it affect the asset as well, but this is not really important to me.
Seeing as everyone always seems to talk about scriptable objects as if they’re the most amazing thing ever, it could be that I’m still missing something about what makes them so good, but again I have not seen any convincing arguments to use them yet.
I mean you’re openly admitting to abusing prefabs for something they’re not intended for (which is what you’re doing, admit it), but then saying you’re not convinced to used scriptable objects for something for which they’d be objectively better suited for. That kind of reasoning doesn’t make any sense.
Hahaha sure I’ll admit it, but that doesn’t change the fact that to me prefabs do the job even better than scriptable objects? Again unless I’m missing something?