127 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # U-Tad UI Project
 | |
| 
 | |
| ## Skill Tree System Implementation
 | |
| 
 | |
| ### Overview
 | |
| A complete skill tree system with node-based progression, prerequisite validation, visual connection lines, and data-driven configuration.
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## 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
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## 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.
 | |
| 
 | |
| ### 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.
 | |
| 
 | |
| ### 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
 |