How-To: Author a Skill Tree
Goal: build a tree's gameplay structure in the Logic graph (skills, dependencies, sub-nodes) and its player-facing layout in the Visual graph.
UCrimsonSkillTree asset open (Quick Start step 4).1. Build the Logic graph
In Logic mode, right-click -> Add Skill for each node and wire parent -> child (left to right). Everything unlockable at the start wires from the Root node's Out pin (Root is auto-spawned and can't be deleted).
| Node | Purpose |
|---|---|
| Root | Implicit prerequisite anchor; wire start-unlockable skills from its Out pin |
| Skill | Wraps a UCrimsonSkillTree_Node; hosts sub-nodes and the gameplay payload |
| Bridge | Auto-managed gate; activates when its prerequisites are met (sub-tree gating) |
| Reroute | Editor-only knot for tidy wiring; compile follows reroute chains through |
2. Attach sub-nodes (conditions, events, costs)
Click the + button on a section header (Conditions, Events, Costs) to add that sub-node type instantly; the Per-Edge header's + opens a small menu for Add Edge Condition / Add Edge Event. (Right-clicking the Skill -> Add Sub-Node still works too.) Sub-nodes are BT-style and drag-reorderable within their typed lane, and the color band shows the type.
| Sub-node | Color | Payload |
|---|---|---|
| Activation Condition | Amber | UCrimsonSkillTree_ActivationConditionBase - must pass before the node activates |
| Node Event | Teal | UCrimsonSkillTree_NodeEventBase - fires on level-up / level-down / reset |
| Cost | Blue | FNodeResourceCost - flat or curve-scaled per level |
| Edge Condition / Edge Event | Amber / Teal (edge-scoped) | Gates / reacts to a specific incoming edge via a FromParentGuid selector (zero = all edges) |
3. Lay out the Visual graph
Switch to Visual mode. Each Logic Skill has a mirror that renders a live UMG preview of its node widget. Drag mirrors freely (positions are independent of logic), set a per-node PreviewWidgetClass / PreviewLevel in Details (the class picker lists any Widget Blueprint implementing ICrimsonSkillTreeNodeWidget, whatever it derives from), and add Decoration nodes (Panel / Header / Divider) for framing.
A decoration carries DisplayText, GameSize, TintColor and an optional Widget Class Override in its Details panel, and its position is wherever you drag the node. The class it draws with is the override when set, otherwise the asset's Graph Config -> Decoration Widget Classes entry for its Kind; a decoration that resolves neither renders nothing, in the graph or in game (How-To: Display the Skill Tree).
The node previews that widget for real: it hosts a live instance driven through InitializeSkillTreeDecoration with this decoration's own data, sized to exactly GameSize, so the canvas shows what the screen will. Drag a decoration's edges or corners to size it - the dragged size is GameSize, exact to the pixel, committed on mouse up as one undoable Resize Decoration. An axis under 30 px has no grab border, so a 2 px divider is resized from its left and right ends and moved by dragging its body.
TintColor defaults to white, which draws the decoration widget exactly as it was authored. Any other value multiplies the widget's own color, so a tint dims or recolors a decoration and never brightens it past what the widget already carries - alpha 0.5 halves its opacity, (0.35, 0.60, 1.00) shifts it blue. Author the widget at full strength and tint individual decorations down from there.PreviewLevel you set. Style the connections next.Bridge nodes and junctions
A Bridge is an auto-activating gate: it turns on by itself once its prerequisites are met and the player never clicks it. Bridges mirror into the Visual graph like any other node, so you position them and their connections draw normally.
To make a bridge read as a pure junction - one line forking into several - give it the ready-made UCrimsonSkillTreeWidget_JunctionNode widget class. Leave Show Pip off and it draws nothing, so the lines simply fork; turn it on for a small dot tinted by the node state (inactive / active / maxed). Connections meet at the junction center, and it is hit-test invisible in game so it never steals clicks from real nodes.
| Assign it | How |
|---|---|
| One node | The visual node's Preview Widget Class |
| Every bridge | GraphConfig.NodeTypeToWidgetClassMap, keyed by the bridge node-type tag |
See also
- How-To: Shape Connections - material-capable spline lines
- Concept: Two-Graph Editor - Logic vs Visual sync semantics
- Concept: Compile Pipeline - how graphs become runtime data