Graph Toolkit Update in Unity 6.5 alpha

Hello everyone,

First of all, we would like to thank you all for your feedback on Graph Toolkit (GTK). We have taken note of your suggestions and have worked to address as many of them as we could. It is important for us to understand your use cases in order to continue improving the framework.

As you know, GTK has been a module since Unity 6.4. With the alpha of Unity 6.5, we have introduced several exciting new features. Here is a list of the main improvements we have made:

Creating graphs by code

We have enabled API methods to create graphs by code. This can be helpful if, for example, you have a data flow and want to visualize it as a graph.

Here is a small example:

// Create a new graph based on a custom SandboxGraph class
var graph = GraphDatabase.CreateGraph<SandboxGraph>("Assets/Generated/mygraph.sbg");

// Create a variable of type int
var variable = graph.CreateVariable<int>("myInt");
var variableNode = graph.AddVariableNode(variable, Vector2.zero);
        
// Create a node based on a custom CustomNode class
var node = new CustomNode();
node.Position = new Vector2(200, 0);
graph.AddNode(node);
        
// Connect the nodes
graph.Connect(variableNode.GetOutputPort(0), node.GetInputPortByName("input"));

The result looks like this:

These graph creation methods can be batched as a single undo-able operation using the added Undo/Redo API calls.

Please have a look at the scripting documentation to learn more about how to build a graph using code.

Soon we will provide a sample in our Samples package to showcase a more complex use case.

Customization

Node Customization

We’ve enabled new node customization options such as modifying the title, subtitle, color, vertical ports, multi-line text (TextArea), etc.
The following example demonstrates modifying the title, the color, and the library location of a node. The node is also modified with a multi-line text field option:

[Serializable]
// The node attribute let's you change the category, the icon and the title of the node 
[Node("Tests/Custom", "Assets/Icons/Math.png", "Customized")]
public class CustomNode : Node
{
    protected override void OnDefineOptions(IOptionDefinitionContext context)
    {
        context.AddOption<string>("multi-line text").AsTextArea().Build();
    }

    protected override void OnDefinePorts(IPortDefinitionContext context)
    {
        context.AddInputPort<int>("input").Build();
        context.AddOutputPort<int>("output").Build();
    }

    public override void OnEnable()
    {
        Subtitle = "This node has some customizations";
        DefaultColor = Color.hotPink;
    }
}

Here is the result:

We know that some of you have been asking for deep UI customization such as applying your own USS or direct access to the visual elements of a graph. Members of the team are currently investigating this so rest assured that this is part of our roadmap. We just kindly ask for your patience regarding this matter.

Data Type Customization

With the new DataTypeStyleMapper you can now modify how a type is displayed in your graph. In the following example, the icon and the color of the Sprite type have been changed.

[DataTypeStyleMapper(typeof(SandboxGraph))]
public class SandboxDataStyleMapper : DataTypeStyleMapper
{
    public SandboxDataStyleMapper()
    {
        var icon = EditorGUIUtility.IconContent("Assets/Icons/Math.png").image as Texture2D;
        var color = EditorGUIUtility.isProSkin ? Color.yellowGreen : Color.darkOliveGreen;
        Register(typeof(Sprite), icon, color);
    }
}

Support for collections

Support has been added for inspectors for Lists and Arrays. You can now dynamically change the size of a collection and update the value of each entry directly in the graph.

Also with regards to Blackboard variables, you now have access to a dropdown menu (Mode) that allows you to convert a simple variable into a list of the same type. However for this Mode to appear, you must have created a port that can support this type of collection.

The code for the CollectionNode looks like this:

[Serializable]
public class CollectionNode : Node
{
    protected override void OnDefinePorts(IPortDefinitionContext context)
    {
        context.AddInputPort<List<int>>("input A").Build();
        context.AddInputPort<string[]>("input B").Build();
        context.AddOutputPort<Vector2[]>("output").Build();
    }
}

Other QoL improvements

Finally we’ve enabled some other quality of life improvements that have been requested by the community. Here is a list of some of these features:

Getting variables in the order in which they appear in Blackboard

You have now access to the Graph.GetVariables(SortMethod.Display) API to retrieve variables in the order they appear in the Blackboard.

Node Options on Subgraphs

Similar to a standard node, Subgraph nodes can have Node Options that can be defined in the Graph.OnDefineSubgraphNodeOptions(IOptionDefinitionContext ctx) callback.

Input/Output without type

You can now define an input/output without a type for your Subgraph.
Note that Untyped ports have their own defined icon and color. These can’t be changed at the moment, but we’re looking into a clean way to use the DataStyleMapper to modify these in the future.

Here is an example of a graph using Untyped input and output:

The resultant Subgraph node appears like this (note that it has a node option like described above):

Feel free to check out the 6.5 release notes for a complete list of changes and bugs we’ve fixed.
A new version of our Samples package is planned to be released soon, where we’ll provide examples of how to use the new features listed above.

What’s next?

The team is now focused on implementing debugging and visual feedback features such as animations on wires and progress bars on nodes. Stay tuned for updates on these.

Thank you again for using GTK. As always, we look forward to hearing your feedback on these new changes.

42 Likes

This is great news! Thank you for your hard work on this tool, I’m pretty sure it will be a very helpful and powerful ally during dev!

I’m also using the occasion of this post to show two of my other topics on the matter (GTK), I hope no one will hate me for just linking them rather than asking the same question again.

The first about output ports values.
The second about an issue I have with custom property drawers.

I’m pretty sure that once I’ve sorted these two out I can really bring out the best of GTK in my projects.

If you have an answer to any of these please post it in the original topic if possible, then I will link your answer back here.

1 Like

I have a general question, maybe you can find time to answer it :slight_smile:

I tried to build a similiar tool like MapMagic2 using the new graph system.

I tried 2 approaches:

  1. Code generation of BurstJobs
  2. Just normal Terrain Gen

Both solutions failed:

For code gen i had to create the files manually and not as a “Result” of the save operations (so its tracked with unity when saving etc). So i feel that code generation is just not something which is truly supported right now and it would be great if you could add that in.

The normal solution was also not feasible since you cannot execute the graph at runtime

What i needed to do was save the graph data to a scriptable object, then basically write exactly the same node logic to parse the scriptable object again at runtime. In the end iam building 2 graph systems: 1 which works in the editor and the other which works at runtime.

So finally my question is: How would you build such a tool which has to work at runtime and cannot produce the full result in the editor? Is there a pattern i was missing somehow eg serializing the graph itself to a scriptable object or something like that?

1 Like

great job! im currently using xNode with a UITK interface for runtime usage, would a runtime version of the graph toolkit be better?

1 Like

Nice to see the Graph Toolkit getting more flexibility. Being able to create graphs by code and customize nodes more easily should make it much easier to build tools on top of it. The collection support and QoL improvements are also very welcome. Looking forward to the debugging and visual feedback features in future updates

1 Like

This is great! An API for creating graphs programatically is the cherry on top. There’s a lot of effort put into making very specific data available (now with collections, text areas, text fields, etc…) but there doesn’t seem to be a region in the “Node” class where we can add our own Visual Elements. Is this something being considered? Similar to how an Editor has the CreateInspectorGUI()

I cant find callbacks like: OnPortConnected/Disconnected/StateChanged (whatever)
I have Node with SO Data (quest asset. There i have SubQuestsList field and StartNextOnComplete field)
So node have inputs for “StartQuest” and “SubQuestsList”
Outputs for “out” and “OnComplete”

So i want in graph connect ports and this should modify SO asset.
But i dont understand how to do it. Am i missing something?

Is it possible to make the node model and port model GUIDs public and read-only? This is a very useful property for linking the runtime graph and the editor graph. I’m creating a flow graph for my game DOTS. I need this! Thanks!
Right now i modify yours code: Its worl perfect.

public virtual Entity BakePort(Entity nodeEntity, IPort port, IBaker baker)
        {
            var portEntity = CreateEntity(port.name, nodeEntity, baker);
            baker.AddComponent<PortTag>(portEntity);
            if (port.direction == PortDirection.Input) baker.AddComponent<PortInputTag>(portEntity);
            if (port.direction == PortDirection.Output) baker.AddComponent<PortOutputTag>(portEntity);
            baker.AddComponent<Guid>(portEntity, new Guid() { Value = port.Guid });
            PortValueBaker.TryBakeValues(portEntity, port, baker);

            return portEntity;
        }
1 Like

Noticed an issue where the nodes (all of them) appear narrow. When the editor compiles new code and reloads the graph view, the nodes appear at the correct width for a moment and then shrink back down to the size shown in the photo.

I’m running Unity 6000.5.0a8

Hi @Cell-i-Zenit!

Graph Toolkit only provides the front-end data model for graphs, so it’s expected that the generated graph assets are converted to a custom data model that can be executed at runtime. This is generally done using a ScriptedImporter from which you can load your graph when the graph is imported (ie. serialized) and convert into a corresponding runtime asset.

The Visual Novel sample provides a good example of how to perform this type of conversion.

Hi @derik-3dmax

We plan to make node and port model GUIDs publicly available in the next editor update. We intend to expand the tools to provide support for live-linking graphs with the runtime in order to allow for runtime debugging of graphs.

4 Likes

Hey @Ohadfarkash

Thank you for reporting this issue! I’ve been trying to reproduce this issue on my end but have been unsuccessful. If it’s still happening, could you file a bug report with your repro steps?

Hey @UnityAlexZ

Thanks for skipping my question! xd

i know that this is how it is intended right now, but as i described it for the Terrain UseCase, this means duplicating the graph logic. Since you didnt mention it i assume that there is no magic sauce.

Is runtime execution planned in the future?

Sorry about that! I was hoping that my answer to @Cell-i-Zenit would address it, which is that Graph Toolkit doesn’t currently provide a runtime graph model, meaning you would have to implement a tailored solution to convert your graph to a custom runtime data model. The reason for this is explained well here.

And although support for runtime graphs is not something that’s provided at the moment or planned for in the near future, this is of course subject to change as our priorities change based on user needs!

1 Like

Hey @UnityAlexZ

Thanks for taking a look.

I decided to try reproducing it myself in a new project, and to create a bug report. Turns out it’s an issue caused by a lack of width expanding content. When I place just a single option for a text area within a node, it appears to lack width. But when I add lots of ports and other elements, it becomes a reasonable width.

It’s probably just a general styling issue that needs some adjusting, like setting a larger minimum width for text areas, along with text wrapping the subtitle and other things that need stress testing :grin:

But I’m sure most of these your team has seen and it’s somewhere in the backlog. I implemented an importer, and I think that more API features to help importing graphs into runtime models would be way more important than some styling issues.

Great stuff so far! I really appreciate the simplicity of defining nodes, and look forward to future updates!

1 Like

I’m interested if reroute-nodes are still being considered. Seems like a basic, trivial to implement, feature

1 Like