2025-10-12 23:44:07 +02:00
2025-10-12 23:18:17 +02:00
2025-10-12 21:06:48 +02:00
2025-10-10 20:23:14 +02:00
2025-10-10 20:23:14 +02:00
2025-10-10 20:23:14 +02:00
2025-10-10 20:23:14 +02:00
2025-10-12 23:44:07 +02:00
2025-10-12 23:43:22 +02:00
2025-10-10 20:23:14 +02:00

U-Tad UI Project

English | Leer en Español


Skill Tree System Implementation

Overview

A complete skill tree system with node-based progression, prerequisite validation, visual connection lines, and data-driven configuration.

Overview 1


Architecture: Blueprint Decision

Blueprint Implementation

Components: WBP_SkillTree, WBP_SkillNode, WBP_SkillNodeTooltip

Reasoning:

  • Iteration speed: UI layout and styling require rapid visual iteration
  • Designer-friendly: Artists/designers can modify UI without C++ knowledge

Decision Blueprint 1


Core Systems

1. Data Layer (SkillTreeTypes.h)

Structures:

  • FSkillNodeData: Skill definition row for skill data table (name, cost, prerequisites, effects, starting flag)
  • FSkillNodeRuntime: Runtime state wrapper
  • ESkillNodeState: State enum (Locked, Available, Selected, Purchased)

Decision: Data Table-driven design allows non-programmers to configure skills without recompiling.

Data Layer 1

2. Logic Layer (SkillTreeComponent)

Responsibilities:

  • Skill tree initialization from DataTable
  • State management (prerequisites, affordability checks)
  • Selection validation and purchase confirmation
  • Starting skills auto-purchase
  • Skill point management
  • Effect application hooks

Key Features:

  • Purchase order sorting: Ensures prerequisites are purchased before dependents
  • Cascade deselection: Removing a prerequisite deselects dependent skills
  • Starting skills: Marked in DataTable, auto-purchased at init, preserved on reset
  • Stat aggregation: Provides GetTotal[Stat]Bonus() functions to sum all purchased skills' bonuses

3. Stats Integration Layer (CharacterStatsComponent)

Responsibilities:

  • Automatic stat calculation from purchased skills
  • Character stat management (Health, Damage, Speed)
  • Real-time updates when skills are purchased
  • Movement speed integration

How it works:

  • Finds SkillTreeComponent on same actor at BeginPlay
  • Listens to OnSkillPurchased event
  • Iterates all purchased skills, sums flat + percentage bonuses
  • Applies formula: FinalStat = Base + FlatBonus + (Base * PercentBonus / 100)
  • Auto-updates CharacterMovementComponent speed
  • Broadcasts stat change events for UI updates

Decision: Separate stats component keeps concerns separated - SkillTreeComponent handles progression, CharacterStatsComponent handles stat application. Makes both reusable independently.

4. Visualization Layer (SkillTreeConnectionsWidget)

Responsibilities:

  • Automatic line drawing between prerequisite nodes (You only need to place nodes in the UI!)
  • Dynamic line coloring based on skill states
  • Event-driven refresh on state changes

Technical Approach:

  • Generic search: Works with any widget hierarchy so designers/artist are not limited when creating the skill tree widget (Canvas, Overlay, Grid)
  • NativePaint override: Direct Slate rendering for performance
  • Delegate binding: Auto-refreshes when skills change state

Decision: Single self-contained widget eliminates manual line management and Blueprint complexity.

Lines 1 Lines 1

5. UI Layer (Blueprints)

WBP_SkillNode & WBP_SkillNodeTooltip:

  • Displays skill icon, state, cost
  • Handles click events (select/deselect)
  • Stores SkillID for runtime lookup
  • Custom tooltip support to display skill details
  • Real time state updates via event binding allows real-time visual feedback

WBP_SkillTree:

  • Contains manually-placed skill nodes
  • References SkillTreeComponent
  • Hosts SkillTreeConnectionsWidget which draws lines between nodes automatically
  • Binds to component events for UI updates

Decision: Manual node placement allows custom layouts (linear, radial, branching) per designer preference.


Key Design Decisions

1. Skill prerequisites in DataTable

Alternative: Hard-coded in C++ or DataAssets references Chosen: DataTable array Reason: Designers can modify skill dependencies without programmer intervention and without recompiling

2. Component vs Subsystem

Alternative: Game Instance Subsystem Chosen: Actor Component Reason: Supports multiple skill trees per player (e.g., combat tree, crafting tree) and easier save/load integration

3. Single Connections Widget

Alternative: Individual line widgets per connection with manual management Chosen: One widget draws all lines automatically Reason: Eliminates array management, better performance, automatic coordinate handling

4. Separate Stats Component

Alternative: Apply stats directly in SkillTreeComponent Chosen: Separate CharacterStatsComponent Reason: Separation of concerns - SkillTreeComponent is reusable for any progression system, CharacterStatsComponent specifically handles character stats. Allows skill trees without stat bonuses, or stats without skill trees.


Technical Highlights

  • Event-driven architecture: Component broadcasts state changes, UI responds automatically
  • State machine validation: Prevents invalid transitions (e.g., can't select locked skills)
  • Automatic stat application: CharacterStatsComponent listens to skill purchases, recalculates stats, applies to character
  • Geometry-aware rendering: Lines adapt to any widget positioning system
  • Data-driven configuration: Zero code changes and no need to compile for new skills or tree layouts
  • Reset functionality: Refunds non-starting skills, maintains starting points
  • Modular design: Skill progression, stats, and visualization are independent
Description
Skill tree system made in Unreal Engine 5
Readme 1,002 MiB
Languages
C++ 98.1%
C# 1.7%
C 0.2%