Building a Custom Upgrade Tree Editor in Unreal Engine 5.5.4
These articles are AI-generated summaries. Please check the original sources for full details.
Upgrade Tree Editor for Unreal Engine 5.5.4
Developer Cami engineered a custom upgrade tree tool for Unreal Engine 5.5.4 to manage complex game progression data. The system implements a specialized Slate layout to handle real-time data asset editing and one-way node connections.
Why This Matters
Standard Unreal Engine pin systems are often too rigid for specific game design requirements like one-way upgrade paths with custom visual arrows. By bypassing the default pin system in favor of a TArray of FGuids and manual OnPaint overrides, developers can achieve high-fidelity visual feedback and strict data persistence that standard graph nodes do not provide natively.
Key Insights
- FGuid implementation (2026) ensures pure persistence by using globally unique identifiers to map runtime progress to static data assets.
- Slate Overlay nesting is used to layer borders and icons, allowing dynamic updates via delegates rather than per-frame redrawing.
- AABB (Axis-Aligned Bounding Box) mathematics are applied via a custom utility class to calculate the closest point on a square for clean line rendering between nodes.
- SLeafWidget is utilized as a transparent overlay to hijack drag-and-drop operations, validating UUpgradeNodeDataAsset types before allowing node creation.
Working Examples
Custom math function to find the closest point on an AABB box for drawing connection lines.
FVector2D CamiMath::GetClosestPointAABB(FVector2D Origin, FVector2D Direction, FVector2D BoxHalfExtent, float InternalOffset) {
float _X = (Direction.X != 0.0f) ? (FMath::Sign(Direction.X) * BoxHalfExtent.X) / Direction.X : FLT_MAX;
float _Y = (Direction.Y != 0.0f) ? (FMath::Sign(Direction.Y) * BoxHalfExtent.Y) / Direction.Y : FLT_MAX;
float _Min = FMath::Min(_X, _Y);
return (Origin + (Direction * FMath::Max(0.0f, _Min - InternalOffset)));
}
Logic for establishing validated one-way connections between nodes using GUIDs.
void UUpgradeAssetGraphNode::AddNewUnlockConnection(FGuid nodeId) {
if (GetNodeUnlocks().Contains(nodeId)) { return; }
if (GetGraph()) { GetGraph()->Modify(); }
this->Modify();
for (UEdGraphNode* node : this->GetGraph()->Nodes) {
UUpgradeAssetGraphNode* castNode = Cast<UUpgradeAssetGraphNode>(node);
if (!castNode || castNode->GetNodeId() != nodeId) { continue; }
if (castNode->GetNodeId() == nodeId && castNode->GetNodeUnlocks().Contains(GetNodeId())) { return; }
}
_unlocks.Add(nodeId);
this->GetGraph()->NotifyGraphChanged();
}
Practical Applications
- Use case: UpgradeTreeComponent allows any actor to track player progression using a TMap of FGuid and runtime progress structs.
- Pitfall: Neglecting to check validity of attachedData during graph loading leads to memory breakpoints when assets are deleted from the content browser.
References:
Continue reading
Next article
GoBadge Dynamic: Transform Any JSON API to Universal Badge Generator
Related Content
Engineering a Real-Time Robot Battle Simulator: Lessons in Performance and Language Design
A technical deep dive into Logic Arena, featuring a custom scripting language and the resolution of a 3,862ms scripting bottleneck.
Building Advanced Django-Unfold Dashboards: Custom Models, Filters, and KPIs
A technical guide to building professional Django admin dashboards using Django-Unfold, featuring custom KPI cards and dynamic back-office navigation.
Why I Built the 🕍 Cathedral Roo Architect Mode: A Technical Vision for Open-Source Game Development
Rebecca Susan Lemke explains her custom Roo mode for aligning cathedral-real, a Godot 4 open-world game and creative OS, with ethical, spec-driven development practices.