After surveying the landscape of graph frameworks for Unity for the past few years and trying to use them I found myself always painting myself into corners, having to work in constrained ways and/or just not liking the API setup around building graph based tools.
I've also come to love Odin Inspector and the power it brings to writing editor tools.
So here we are - this is our love letter to Odin by marrying it with a graph framework that gets out of your way and hopefully makes it trivial to build new graph based tools ontop.
SerializeReference
features)To write a new custom node quickly you inherit from the base Node class and define your ports.
using RedOwl.Sleipnir.Engine;
[Node]
public class AddNode : Node
{
[FlowIn(nameof(OnEnter))] public FlowPort Enter;
[FlowOut] public FlowPort Exit;
[ValueIn] public ValuePort<float> Left;
[ValueIn] public ValuePort<float> Right;
[ValueOut] public ValuePort<float> Output;
protected IFlowPort OnEnter(IFlow flow)
{
Output.Value = Left.Value + Right.Value;
return Exit;
}
}
The above is a simple definition of a node that performs an "add" math operation on the "left" and "right" value in ports and pushs the result to the value out port.
To then make use of this new node you navigate to your Project Browser in Unity right click
and then Create
-> Red Owl
-> Graph
This creates a scriptable object asset in your project that can serialize graph data using unity's serializer. From there you double click the asset to open the Graph Editor window.
From there you can press spacebar and a node search window will open - navigate to your new node and that will place an instance in your graph. You should beable to create a graph like the following image.
The follow graph will perform an addition on the 2 float values and log the result to the console.
Cheers! (For more examples dig into the codebase at ./Engine/Nodes)
private static void CreateSampleGraph()
{
var graph = new Graph();
var startNode = graph.Add(new StartNode {NodePosition = new Vector2(128, 0)});
var logNode1 = graph.Add(new LogNode {NodePosition = new Vector2(0, 100)});
var logNode2 = graph.Add(new LogNode {NodePosition = new Vector2(200, 100)});
var floatNode1 = graph.Add(new FloatValueNode(10) {NodePosition = new Vector2(-200, 0)});
var floatNode2 = graph.Add(new FloatValueNode(100) {NodePosition = new Vector2(-200, 200)});
var floatNode3 = graph.Add(new FloatValueNode(5) {NodePosition = new Vector2(-200, 400)});
// Flow
graph.Connect(startNode.Start, logNode1.Enter);
graph.Connect(startNode.Start, logNode2.Enter);
// Values
graph.Connect(floatNode1.Value, logNode1.Message);
graph.Connect(floatNode2.Value, logNode2.Message);
GraphAsset.Save(graph, "Generated", "Resources/Graphs");
}
In Package Manager click Add package from git URL and use the following:
https://github.com/red-owl-games/Sleipnir.git
https://github.com/buunguyen/fasterflect http://introspectingcode.blogspot.com/2011/06/dynamically-compile-code-at-runtime.html