Scriptable Objects workflow

In this thread I want to discuss how we would work with ScriptableObjects and create architectures using them.

If you don’t know what ScriptableObject is, here’s short introduction:

With this cool blog-post attached!

Me and guys are working on Scriptable State Machine in [this thread]( State Machine page-2).

Leave all your thoughts in there, especially if you’ve had trouble with SO in the past.
I’d love to research common usaged of them and establish best workflow for everyone!

How can we leave out one of the most watched videos on the Unity YouTube channel? (and for a reason)

What do you think of this talk?

1 Like

Because it’s already in blog-post I’ve linked :smile:

I feel like what they’ve made in not completely right way to go, but fundaments are great!

What there is mostly missing is nice editor support for SO organization, debugging and easier inspection.
Like for example, ability to attach Variables to the scriptable object asset:
6381072--710967--upload_2020-10-4_21-10-30.png
That’s the one I’m working on right now :slight_smile:

Modular data-driven architecture is the future!

SO make sense for data but not for all types of events. In terms of this project it will also be tough to see source-control changes and figure out what exactly happened (code is much cleaner is this aspect).

From different thread about SO events Scene Loading System :
I dislike this approach a lot but who knows, maybe I don’t know something.

  1. How do you find references in project to a ScriptableObject event?
  2. Can you modify respond to an event (adding/removing listeners) without modifying a scene? (in case where there’s GameObject on a scene that uses ScriptableObject).
    (…)
    I dislike SO events in general, tried them in my project and they were terrible. I would only use them if I had 9 designers and 1 programmer in a team.

With other approaches you can quickly see all references/listeners/raisers.

In this example wrappers can be made to let designers use them in editor (for ex. ButtonLoadMenu) and they give more context than very generic “GameEvent”.

2 Likes

[quote=“Kamyker, post:4, topic: 811307, username:Kamyker”]
In terms of this project it will also be tough to see source-control changes and figure out what exactly happened (code is much cleaner is this aspect).
[/quote]Simple example from current scene loading solution. Main menu scene has Start button with GameEvent_LoadNextLevelWithProgress SO event attached in inspector, let’s say someone wants to change it to different one. Here’s what git will show:

Well, what can I say, have fun deciphering that. Feel free to use SO events and learn how bad they are the hard way, especially when project gets bigger.

I found using prefabs as a data containers, as a ScriptableObject replacement, is so much more powerful in the long term!

1 Like

I don’t think you would look at the data itself outside of the editor (why would you?)

As a programmer, I very much hate boilerplate delegates hardly written in code.
They’re much harder to keep track of, like with singletons but worse.
And it’s not very scalable, ether modular.

With SO events you always know why error is caused: it’s a problem with behaviour tree or a missing data component.

As a designer, I love to simply drag objects here and there and just change the game logic like that, it helps to came up with a new ideas really easily

You just look at the GO that references some data/event, why would you need all of the references at once?
If you’d want to, it’s not so hard to write editor window for that.

I didn’t get that. GO listeners should live only in the scene, aren’t they?

It’s an intresting feature request.
But I totally dislike usage of Prefabs as data containers. (it’s an abuse of concept!)
ScriptableObjects are easy to reference, share, and edit. They’re beautiful data containers with logic support.
I would love not to break that ecosystem ever.

We can have “Variants” support just by extending Variable Objects concept.

Also, it would be dope to have “Add Component” in the SO inspector that just adds sub-asset of specific type :slight_smile:

[quote=“Neonage, post:7, topic: 811307, username:Neonage”]
I don’t think you would look at the data itself outside of the editor (why would you?)
[/quote] Github

[quote=“Neonage, post:7, topic: 811307, username:Neonage”]
They’re much harder to keep track of, like with singletons but worse.
And it’s not very scalable, ether modular.
[/quote]Not sure what you mean but even singletons can be modular and testable if properly made (default implementation).

[quote=“Neonage, post:7, topic: 811307, username:Neonage”]
You just look at the GO that references some data/event, why would you need all of the references at once?
[/quote]Usually you don’t know what GO references an event, you also don’t know in what scene/prefab that GO is. Sometimes it’s trivial to find and sometimes it’s not (for ex. GO that was just destroyed in playmode). Much slower then “Find All References” in VS that takes 3 seconds.

[quote=“Neonage, post:7, topic: 811307, username:Neonage”]
If you’d want to, it’s not so hard to write editor window for that.
[/quote]Yes, there are tools for that already but they get slow quickly with project size and complexity.

@cirocontinisio is it really mandatory to review guid meta data outside of Unity?

That’s the point, we’ll need to make some “Event Logger” window for that.

Then they writen not smartly

[quote=“Neonage, post:10, topic: 811307, username:Neonage”]
@cirocontinisio is it really mandatory to review guid meta data outside of Unity?
[/quote] It’s about reviewing PRs without having to open Unity, the less meta data changes, the better.

Case A

You:

  1. Don’t know what changed.
  2. Don’t know on what object the change occurred, could scroll up to see GO name but it’s so far I couldn’t fit it in one screenshot:



Well, now you know the name but you still don’t know what it is exactly.
3. After finding GO in Unity, now you have to review event listeners - would have to use 3rd party tools to find them or guess.

Case B:

  1. You know what changed.
  2. Still don’t know on what object change occurred but now it’s a lot simpler to find it.
  3. F9 on LoadNextWithProgress to find all listeners.

So, you are saying that you don’t like abuse Prefabs workflow, but you literally recreating Prefabs functionality using scriptable objects, lol.

Do you know what really cool about using Prefabs over ScriptableObjects?

I think if we are going to abuse ScriptableObjects then it’s better to abuse Prefabs (and add some editor scripts to protect such Prefabs from being instantiated and misused. It’s simpler than recreate the whole system)

Anyway, this project is community-driven so there is definitely a lack of communication between all of us cuz we are not working in the same company/office/workspace. Let’s just use a standard way of doing things.
I think it’s better to allow designers to do their job - create content and level design.
Developers will do the rest.

6381786--711078--upload_2020-10-5_2-8-14.png

Uninstanced Prefab seem more like recreation of ScriptableObject :slight_smile:
And I’m not, I’m just extending upon whats already there

You can’t reference nested game object in the inspector.

Here’s simplest example of SO variation:
6381786--711090--upload_2020-10-5_2-18-57.png
It’s just referencing data from base and has single override variable.

You can use these objects anywhere, it’s super modular and natural for design.

@superpig may we have your opinion on that? :slight_smile:

Btw, Rider has integrated support for Unity assets usages

[quote=“Neonage, post:14, topic: 811307, username:Neonage”]
Btw, Rider has integrated support for Unity assets usages
[/quote]Correct if I’m wrong but not really, it has support for code usages by Unity assets. Since GameEvent SO is very generic you can only see all references to all unknown events - that’s kind of useless.

1 Like

What about an SO with a list or array of listener interfaces? It’s debug-friendly, serializable and promotes class granularity.

It kinda looks for references, but it doesn’t show all of them at once
6382938--711315--upload_2020-10-5_12-44-16.png

6382938--711312--upload_2020-10-5_12-43-19.png

6382938--711318--upload_2020-10-5_12-45-40.png

I think so too! :slight_smile:
There is really no other way to call SO logic rather than by reference

[quote=“Neonage, post:13, topic: 811307, username:Neonage”]
@superpig may we have your opinion on that? :slight_smile:
[/quote]My opinion is that it is a bad idea to make decisions about which tool to use without a clear understanding of which problem you are using it to solve :wink:

It’s true that if you need a very ‘component-based’ design, using an uninstantiated prefab might be less work than an SO (though you can create it out of SOs as well, if you want). The addition of prefab workflows like overrides and variants is an interesting angle as well. I stand by the arguments I made before about their downsides, but just because they have some downsides doesn’t mean you couldn’t use them (especially if you’re just going to recreate the same downsides with SOs anyway).

Ultimately, both approaches are just tools, and having more tools available to you is always better. It’s good to understand the pros and cons of each tool, as well as principles about how to choose (e.g. why using a simpler, less capable design might be preferable), but trying to make up-front decisions about which tool to use in the absence of specific problems to solve is a bad idea.

3 Likes

[quote=“Neonage, post:17, topic: 811307, username:Neonage”]
It kinda looks for references, but it doesn’t show all of them at once
[/quote]It is a bit better in your example with SimpleParticleEvent instead generic GameEvent but still from your screenshots it’s unclear what SimpleParticleEvent particles event does, what event it is in a context etc and it will get worse the more that event is used. Also not everyone has Rider.

1 Like