Search Unity

Assign graph data inputs in the inspector

Discussion in 'Visual Scripting' started by johanolofsson, Sep 2, 2021.

  1. johanolofsson

    johanolofsson

    Joined:
    Nov 21, 2018
    Posts:
    94
    So I've just started to learn about visual scripting and I immediately find my self a bit confused. I've been programming since mid 90's so I've kinda got the hang of that by now and of course I recognize most of what I am accustomed to in UVS.

    Now what strikes me as odd is that if I create a graph A as an asset and I place that as a sub graph unit in another graph B the data inputs appear as expected and can be connected to other units in B. However, should I use A as the root graph in a ScriptMachine, I obviously expect those data inputs to be assignable properties in the inspector, but they wont. I mean, they got their type and their name just as if they were public fields in a script?

    I've been fiddling around with variables to mitigate this but nothing seems to do the trick. I realize this is probably a bad case of newbness on my part so please help me figure this out :)
     
  2. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,068
    There are "Input" and "Output" nodes specifically for defining subgraph control and value inputs/outputs. If you create a subgraph (previously superunit) via the fuzzy finder, then it'll automatically add these nodes. For graph assets created elsewhere you can add them manually.
     
  3. johanolofsson

    johanolofsson

    Joined:
    Nov 21, 2018
    Posts:
    94
    No the problem is not to access the inputs inside the actual graph. The problem is to be able to assign those inputs where the graph is used as a root graph.

    I.e.
    * drag a prefab on which I want to use my graph into my scene
    * add a script machine to the prefab instance in the scene
    * add graph A to the script machine

    at this point I expect to be able to assign the inputs of graph A in the inspector, just as if A where a script (mono behaviour) and the data inputs were public fields.
     
  4. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,068
    Ah, I misread the OP.

    You can't directly assign subgraph input values on the top/ScriptMachine level.

    UnityVS GameObject variables are used as the alternative for C# serialized Inspector values. A GameObject Variables component is automatically added when you add the ScriptMachine component.

    Long story short, subgraph's input values can only be set in a graph it's embedded in.
     
  5. johanolofsson

    johanolofsson

    Joined:
    Nov 21, 2018
    Posts:
    94
    Ok sure, that would be sort of be sufficient given that a set of variables was automatically:

    1. created by the mere existence of data inputs in the graph added to the script machine
    2. automatically given the same name/type as the data inputs
    3. automatically mapped to these inputs

    after that I could easily just assign the values to those variables.

    If this process is not automated the repeated job of setting this up for every single instance is just not going to be feasible.
     
  6. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,068
    You are correct in that this does not scale. Unity have to work on improving it. Temporary workaround could be using a Prefab with per instance overrides. Or copy/pasting the Variables component via the gear icon. I think component templates might also work in this case. All of these are more complex than necessary, however.
     
  7. codemonkeynorth

    codemonkeynorth

    Joined:
    Dec 5, 2017
    Posts:
    13
    I've just come across the same problem the first time I used Visual Scripting

    Say I have 2 game objects on the scene Cat and Dog. I add a Destroy On Touch graph to each of them that listens for an event on a Box Collider, but that Box Collider maybe nested somewhere in the children. I want to be able to provide the specific Box Collider to the graph.

    Currently I have to add an object variable (eg TargetBoxCollider) to both Cat and Dog, so the graph can grab it.

    I know I could work around the problem using eg an Animal prefab, but ideally the graph would expose inputs to the inspector when added to a game object.
     
  8. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,068
    The issue is that there are two graph types - Script Machine and State Machine. Currently, both can share variables and communicate via the same Variables component. This is a desired functionality at the cost of having to recreate Object variables on each new object which we've concluded doesn't scale.

    If Variables are nested in the Script Machine and State Machine directly, different graph types can't share variables anymore, which is a no go in my opinion. And there might be more graph types such as Behaviour Trees in the future.

    There is a perfect solution for this, though. Simply group all graph types and object scope variables under a new type. It would contain object scope variables, any amount of script graphs and any amount of state graphs. This would solve both the variables scaling issue because variables are defined on the type level and then optionally overriden per instance. And different graph types can still share the variables. And why stop there? Throw in custom events there too, so we can actually manage them on a project level. Let's name this type a... Class.

    The exact thing Bolt 2 implemented and Unity called too programmer centric when they cancelled it. As far as I can see, it's the only way of solving current architectural problems. It would also fix their variable improvement roadblock. They say they can't make Object scope variables GUID based so that they can be safely renamed and have that rename automatically propagate through all graphs that reference the renamed variable.

    GUIDs would also enable strong typing so we could see type mismatch errors before entering Play mode and getters/setters could also display their type icons instead of the generic green object icon Bolt 1 variables have. And they can't do it precisely because Object Variables are in a separate component and are in no way tied to a graph or a Class like type that groups all these concepts together.

    Perhaps now they understand why Bolt 2 went the way it did. It was a massive improvement in just about every way but I don't see any lessons learned from it so far.

    EDIT: I've seen people ask to mark variables for automatic addition to the Variables component. But what happens when two different graphs add a variable with identical name but different type and default value? Or add the same variable of the same type but different value? This would become a mess pretty fast.

    TL; DR: The separate object scope Variables component is fundamentally a bad design that doesn't scale. Bolt 2 solved it perfectly by grouping these separate concepts together. You don't even have to call it a class. Any term works, just please learn from it, Unity.
     
    Last edited: Mar 19, 2022
  9. codemonkeynorth

    codemonkeynorth

    Joined:
    Dec 5, 2017
    Posts:
    13
    @PanthenEye
    re: what happens when two different graphs add a variable with identical name but different type and default value

    the same with a normal MonoBehaviour component. ideally the inspector fields for inputs/variables would appear on the Script Machine component when the graph is added, rather than a separate Variables component.

    the Object variables could still exist as a separate component but the graph should have it's own exposed inputs in the inspector
     
  10. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    2,068
    What if you want to access the exposed variables from a different graph? Say a script graph automatically exposes variables on the Script Machine component that describe a character. A State Machine on the same GameObject would like to see those variables for its AI logic. How does the State Machine access the exposed Script Machine variables?

    I guess following the Monobehaviour route, you'd need to reference graph instances directly for Get Variable node. But do exposed variables then require a new Getter/Setter type node? Or are exposed variables a new scope added to the already too long variable scopes dropdown? The latter one could work, I guess.
     
    Last edited: Mar 20, 2022