Create Scriptable Objects using visual scripting

Hello Everyone,
I’m creating a framework to compose abilities using scriptable objects.
Each ability is defined by a Scriptable Object that contains a list of actions and each action can contain a list of other actions (sub-actions)…

The Unity Inspector is not designed to handle hierarchical models, especially when it has many layers.
So Is there a way to create scriptable objects using some kind of visual scripting to make the process easier ?

Thanks!

You can build custom nodes that reference a scriptable object asset. Are you trying to make a user friendly (readable) way of inspecting?

I have had no problem using deep hierarchical scriptable objects and also nesting SO(scriptable objects).
However, usually in the inspector when I nest SO’s within one another they show up as referenced files and they are not all inspect-able from one view.

Are you trying to see all values in one view from the inspector?

A work around I have used for special case scenarios:

Using a scriptable state or graph asset as data container. Graph assets do behave like a scriptable object. Therefore, you can store layers of embedded information visually. And then load the graph into scene and reference the graph data variables.

Alternatively you may have the graph run a event/flow that loads the abilities on demand.

Is a scriptable object just a collection of actions in your use case? As Starpaq2 already mentioned, graph assets behave like scriptable objects, so if you have a custom node per action, you can arrange them however you like. Nesting individual SOs on nodes also shouldn’t be a problem, although I don’t recall someone having a List<> embedded on a node in a user friendly way but you can still use the graph variables for that.

But there’s a lot of overhead in using UVS for this purpose. The performance overhead, the domain reload overhead, the impact on load times if you UVS present in the project, the significant boilerplate of the API, the garbage that’s generated when deserializing the graph or the type boxing if you’re using the UVS variables system, etc.

Personally, I’m partial to [SerializeReference] action lists based on an abstract class. And if the inspector can’t handle complex hierarchies, Odin Inspector typically saves my day with stuff like inline editors.

my bad i should have given more details about my plans so you guys get a greater context.

I’m creating a Gameplay Ability System ( or GAS for short) in a Data Oriented Approach using DOTS, it is a some sort of a skill system commonly used in an RPG or MOBA title games like (League of Legends, DOTA …).
GAS is purely based on composition, once the necessary code is in place, it can be used as the basis for a wider variety of possibilities, meaning any ability can be created without the need to add code as long as it uses existing behaviors such as : Move forward, Execute events on impact, Follow entity, Add Gameplay Effects to set of entities…

Some of GAS objectives related to this forum are:

  1. Make an Artist friendly framework to help designers create technical content ‘Abilities’ without requiring developers interventions.
  2. Make Abilities represented by Scriptable Objects (SO’s) or any alternative, so they can be loaded at runtime using something like addressables without the need to completely update the client.

i dont really need SO’s, as everything required is something i can load at runtime or in editor to construct Abilities from. i dont really care about their performance impact as those assets (SO’s, Graph assets …) as they are loaded once to get the data and create/update abilities, the ability itself will be very optimized for runtime as it will represented by Entities.

I’m sorry guys but I don’t have enough experience in visual scripting.
do you mean AssetGraph when you say graph assets?
if so, AssetGraph doesn’t really offer what I’m looking for because it’s a kind of state machine.
I just tried Bolt and it seems to give what I’m looking for, but the documentation isn’t complete.
im trying to create a Bolt FlowGraph per ability which fills a SO instance and returns it.
the problem im facing now is how to run a Bolt FlowGraph from a C# script and get the SO instance so i can use it as input in DOTS conversion.

I assumed you’re in the monobehaviour land and can apply the standard graph setup using ScriptMachine component. I’m unfamiliar with entities.

Also, Bolt is not developed anymore and is not supported past Unity 2020. From Unity 2021 and onwards, you’re supposed to switch to Unity Visual Scripting.

Accessing and running the FlowGraph to get the generated SO will be done in Unity Editor (edit mode) via a monobevior script.
What would be the Right approach for it ?
thanks

Unity DOTS users are blocked in Unity 2020 until the next release of DOTS.
I assume it’s possible to upgrade from BOLT to Unity Visual Scripting ?

Here is a rough and messy concept. Perhaps it can give you something to jump from. I tried to setup the example to demonstrate multiple options as a reference/resource primarily. As far as dots… I am not experienced in that realm at this time.

2 Scripts and 1 Graph


AbilityHolder.cs
A monobehavior that loads the graph and triggers the graphs function.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.VisualScripting;

namespace GAS
{
    public class AbilityHolder : MonoBehaviour
    {
       
        public List<soAbility> abilityList;
        public ScriptMachine scriptGraph;
       
        public void importAbility(string assetName)
        {
            ScriptGraphAsset scriptGraphAsset = Resources.Load<ScriptGraphAsset>(assetName);
            scriptGraph.nest.SwitchToMacro(scriptGraphAsset);
            CustomEvent.Trigger(this.gameObject, "importAbility");
        }
    }
}

8118242--1051988--ability_variable.png
Ability.cs
A serializable class to set the structure of the ability classes.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.VisualScripting;
using System;


namespace GAS
{
    [Inspectable]
    [Serializable]
    public class soAbility
    {
        [Inspectable]
        public float damage;
       
        [Inspectable]
        public float speed;
       
        [Inspectable]
        public float combo;
    }
}

The graph is can be duplicated from the master template to allow the team to create data sheets (data graphs?). There are a million ways that you can approach how they are setup for best workflow. The custom event will trigger the graph to import the ability data into the monobehavior in scene.

The graph first “packages” the data into a local ability variable and passes it to the holder. The graph finds the abilityholder by a scene variable.

To add to the above, Unity have some documentation for custom node creation: Custom C# nodes | Visual Scripting | 1.7.8

The API is likely identical between Bolt and UVS right now, with minor namespace differences. ie Bolt stuff is under Ludiq and Bolt namespaces, while UVS is under Unity.VisualScripting.

As for upgradeability, Unity say Bolt 1 graphs should be compatible with UVS.

Thank you very much guys for all the details and examples!

@Starpaq2 I’m still facing a little problem with the example above :/, when I add soAbility as a variable, it works like a charm, but when I change it as a ScriptableObject, the fields don’t show up and cannot be referenced as Set Get from the Graph.

I’m not able to get the scriptable object to display property fields either. It’s a possible limitation for the blackboard variables. However, they should still be able to be referenced the same way from the graph via set/get.

If you have not go to File Menu → Edit → Project Settings → Visual Scripting → Click the button “Regenerate NODES

This will update the node database with the get/set for the change of the soAbility to a scriptable object.

Optional Step:
Additionally you can add the soAbility as a type from the “Type Options” and regenerate again. But this last option should not be necessary.

Thanks!