This tool lets you automatically create simple graph tools with minimal input.
I created it to get some practice with UIElements and GraphView, so this tool is just a weekend project, that I do not plan on continuing. However, in its current state it's still quite feature-rich, and easily readable despite being being a bit ill-organized.
Current feature-set includes:
- Automatic graph editor generation
- Customizing the graph using attributes
- Renaming objects for better readability in-graph.
- Clipboard functionalities - a bit buggy at times, but works 9/10 times.
- Undo/Redo functionalities - a bit buggy at times, but works 9/10 times.
- Automatic Unity serialization.
- Searcher integration to search for nodes.
- Fully validated type-safety, integrated with the search functionality.
- Correctly handles inherited types.
- Create a ScriptableObject class and add GraphEditable attribute to it.
namespace UnityEngine
{
[CreateAssetMenu, GraphEditable]
public class SomeGraph : ScriptableObject
{
}
}
- Add a
GraphEditorGraphData
member variable to it. The name does not matter. This is for storing some editor-only state.
#if UNITY_EDITOR
[SerializeField] private GraphEditorGraphData graphData = default;
// you can name it anything you'd like
#endif
- Add a member variable which is a collection of
ScriptableObject
or a class derived from it. This variable will hold all the nodes. You can have multiple node collections.
[GraphEditorNodeCollection(typeof(SomeOtherSubtype), typeof(YetAnotherSubtype))]
[SerializeField] private SomeScriptableObjectSubtype[] collection;
// List<T> works fine too.
// feel free to add as many filters as you'd like
// they must be assignable to the type of collection,
// but the data is validated right after compiling,
// with detailed feedback.
- Create your node classes, which must also derive from
ScriptableObject
.
namespace UnityEngine
{
[GraphEditorNode()]
public class SomeScriptableObjectSubtype : ScriptableObject
{
}
// [GraphEditorNode()] gets inherited, but can be overridden
// with custom values
public class SomeOtherSubtype: SomeScriptableObjectSubtype
{
}
// [GraphEditorNode()] implicit
public class NewType : SomeOtherSubtype
{
}
// [GraphEditorNode()] implicit
public class YetAnotherSubtype: SomeScriptableObjectSubtype
{
}
}
- You can modify where the port to represent the node's reference should be present from
[GraphEditorNode()]
's arguments.
[GraphEditorNode(PortOrientation.Vertical, PortDirection.Input, PortCapacity.Multi)]
// ORIENTATION can be vertical or horizontal - lets you modify the flow
// DIRECTION can be input or output - which is only visual
// direction only determines the position of the port, and nothing else
// CAPACITY can be single or multi - which will modify the behaviour of
// the graph editor, with an example use-case being Behaviour Trees where
// you don't want multiple nodes referencing a node.
- Add a
GraphEditorNodeData
member variable to it. The name does not matter. This is for storing some editor-only state such as node position.
#if UNITY_EDITOR
[SerializeField] private GraphEditorNodeData nodeData = default;
// you can name it anything you'd like
#endif
- Add your serialized fields to the class like you would in a normal Unity class. These will be displayed as inlined fields within the node.
namespace UnityEngine
{
public class RanOutOfNames : YetAnotherSubtype
{
[SerializeField] private float health = 0.0f;
[SerializeField] private int lives = 999;
// all serialized fields will be turned into inlined fields
// within the graph editor
}
}
- To add ports, use the
[GraphEditorPort]
attribute.
[GraphEditorPortAttribute()]
[SerializeField] private SomeScriptableObjectSubtype nextInChain = null;
[GraphEditorPortAttribute()]
[SerializeField] private RunOutOfName[] runners = new RunOutOfName[0];
// using an array will automatically generate a port with
// multiple reference capacity
- You can modify where the port to represent the node's reference should be present from
[GraphEditorPort()]
's arguments.
[GraphEditorPort(PortOrientation.Vertical, PortDirection.Output)]
// ORIENTATION can be vertical or horizontal - lets you modify the flow
// DIRECTION can be input or output - which is only visual
// direction only determines the position of the port, and nothing else
// CAPACITY is automatically determined by whether the port is a
// single reference or a collection
-
Open
Windows/GraphEditor
, create theSomeGraph
object fromAssets/Create/SomeGraph
, and keep it as the selected object. You're good to go. -
You can use space-bar to open search window to add nodes to a graph. Autographer internally handles type safety, so you'll only see relevant additions.
I will not be providing any support for this tool, and it's provided as-is. The runtime assembly contains a couple examples in how to use it.