Node graph
Four nodes with ports you can wire by dragging. GraphEdit draws the curve, accepting the connection is your call.
The editor above is running this project. Change a line and it reloads.
Godot classes used
GraphEditGraphNode
The code
scripts/main.gd
extends Node
const NODES: Array = [
{title = 'Noise', at = Vector2(60, 80), outputs = 1, inputs = 0, color = '#8eef97'},
{title = 'Color ramp', at = Vector2(360, 60), outputs = 1, inputs = 1, color = '#8da5f3'},
{title = 'Multiply', at = Vector2(360, 260), outputs = 1, inputs = 2, color = '#f3d48d'},
{title = 'Output', at = Vector2(680, 160), outputs = 0, inputs = 1, color = '#fc7f7f'},
]
var graph: GraphEdit
var status: Label
func _ready() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var column: VBoxContainer = VBoxContainer.new()
add_child(column)
column.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
# outside the GraphEdit, whose plain children stay pinned to a corner over the nodes
status = Label.new()
status.text = 'drag from a port to another to wire the nodes'
status.add_theme_color_override('font_color', Color('#999999'))
column.add_child(status)
graph = GraphEdit.new()
graph.show_grid = true
graph.minimap_enabled = false
graph.size_flags_vertical = Control.SIZE_EXPAND_FILL
column.add_child(graph)
for entry in NODES:
graph.add_child(_make_node(entry))
graph.connection_request.connect(_on_connect)
graph.disconnection_request.connect(_on_disconnect)
print('GraphEdit does the dragging and the curves, the connection is yours to accept')
func _make_node(entry: Dictionary) -> GraphNode:
var node: GraphNode = GraphNode.new()
node.title = entry.title
node.position_offset = entry.at
node.custom_minimum_size = Vector2(190, 0)
var rows: int = max(entry.inputs, entry.outputs)
for i in rows:
var label: Label = Label.new()
label.text = 'port %d' % i
label.add_theme_color_override('font_color', Color('#999999'))
node.add_child(label)
node.set_slot(i, i < entry.inputs, 0, Color(entry.color), i < entry.outputs, 0, Color(entry.color))
return node
func _on_connect(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
graph.connect_node(from_node, from_port, to_node, to_port)
status.text = '%s:%d -> %s:%d' % [from_node, from_port, to_node, to_port]
func _on_disconnect(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
graph.disconnect_node(from_node, from_port, to_node, to_port)
status.text = 'disconnected %s from %s' % [from_node, to_node]