Skip to content

Quickstart Guide

CoffeeVampir3 edited this page Apr 11, 2021 · 25 revisions

If at any point you're confused about what in tarnation is going on around here, you can reference the more specific documentation here in the wiki.

Graph Blueprints

Create a class that derives from Graph Blueprint

    [CreateAssetMenu]
    public class TestGraphBlueprint : GraphBlueprint
    {
    }

Root Nodes

Every graph needs a Root Node, to give our blueprint a root we must create and register our new root node:

    [RegisterTo(typeof(TestGraphBlueprint))]
    public class RootTester : RuntimeNode, IRootNode
    {
    }

You'll also want the root node to have a port so it can connect to something.

Add a port to the root node:

    [RegisterTo(typeof(TestGraphBlueprint))]
    public class RootTester : RuntimeNode, IRootNode
    {
        [Out, SerializeField]
        public ValuePort<Any> rootPort = new ValuePort<Any>();
    }

Here we've defined a Value Port in our case this is an Any which means it can connect to any type of port.

port example

Ports are how you define what is allowed to connect and how the connections will flow.

Now you can hop in and check out your first graph, simply create an instance of GraphBlueprint by taking advantage of the Create Asset Menu attribute you gave it. Then, double click on the created blueprint asset and your graph will open with it's root node..

example

It's that simple to get an editable graph, but you probably want more than a root node and no content.

More About Nodes

Now to add something we can connect to, we'll make another Runtime Node, this time one we can create in the graph:

    [RegisterTo(typeof(TestGraphBlueprint), "My Second Node")]
    public class MySecondNode : RuntimeNode
    {
        //These port options are: "Show Backing Value?", "Port Capacity" and default to false/single if none are selected.
        [In(false, Capacity.Multi), SerializeField]
        public ValuePort<string> stringValue = new ValuePort<string>();
        [Out(true, Capacity.Multi), SerializeField]
        public ValuePort<string> stringValue2 = new ValuePort<string>();
    }

example

Viola! Now you can head into your graph and right-click anywhere in the world, you'll see in the dropdown menu options a "Create Node", click that and it'll pull up a search menu where you can find your node which you've named "My Second Node". You can give nodes a more detailed path, for example:

    [RegisterTo(typeof(TestGraphBlueprint), "Dialogue Nodes/My Second Node")]

Will create a new category called "Dialogue Nodes" which your "My Second Node" will now belong to.

Now you know how to make nodes and ports! Next, how do you make the graph do something? Lets extend your root node by overriding it's OnEvaluate function:

    [RegisterTo(typeof(TestGraphBlueprint))]
    public class RootTester : RuntimeNode, IRootNode
    {
        [Out, SerializeField]
        public ValuePort<Any> rootPort = new ValuePort<Any>();

        protected override RuntimeNode OnEvaluate(Context evContext)
        {
            if (!rootPort.IsLinked()) return null;
            return rootPort.FirstNode();
        }
    }

Now when your root node gets evaluated, if it's linked to anything, it'll return the first node it's linked to. Returning null will tell the evaluator to stop running. Similarly, we can extend our "My Second Node" with some functionality as well:

    [RegisterTo(typeof(TestGraphBlueprint), "Wow/Node")]
    public class MySecondNode : RuntimeNode
    {
        [In(false, Capacity.Multi), SerializeField]
        public ValuePort<string> stringInput = new ValuePort<string>();
        [Out(true, Capacity.Multi), SerializeField]
        public ValuePort<string> stringOutput = new ValuePort<string>();

        protected override RuntimeNode OnEvaluate(Context evContext)
        {
            foreach (var link in stringInput.Links)
            {
                if (stringInput.TryGetValue(link , out var value))
                {
                    Debug.Log("Value of link: " + value);
                }
            }

            if (!stringOutput.IsLinked()) return null;
            var index = (Random.Range(0, stringOutput.Links.Count));
            return stringOutput.Links[index].Node;
        }
    }

This will output the value of everything connected to the stringInput ports as long as it's a string. It will also randomly pick any connected port to traverse to next if there's any connections.

Running a Graph:

To execute a graph, you use the Graph Evaluator class:

    public class GraphTester : MonoBehaviour
    {
        public GraphEvaluator evaluator;

        private void Start()
        {
            evaluator.Initialize();
        }

        private float lastTime = 0f;
        private void Update()
        {
            if ((Time.unscaledTime - lastTime < 2.00f)) return;
            evaluator.Step();
            lastTime = Time.unscaledTime;
        }
    }

Make sure to drag your GraphBlueprint into the executor, this will make the evaluator try to evaluate one step of your graph every two seconds. Give it a try!