Overview
The Progression Tree Builder system consists of the following main components:
- Progression Tree — Scriptable Object containing all skills
- Progression Skill — Scriptable Object defining individual skills
- Tree Manager — MonoBehaviour managing runtime state
- Skill Instruction Manager — MonoBehaviour coordinating scene-based instructions
- Skill Instructions — MonoBehaviour for per-skill scene-specific behavior
- UI Controller — MonoBehaviour coordinating the display
- Skill Node Renderer — Sub-controller for node creation and positioning
- Connection Renderer — Sub-controller for visual connection lines
- Tree Navigation Controller — Sub-controller for multi-tree navigation
- Latest Mode Layout Controller — Specialized controller for roguelike progression
- Latest Mode Detail Panel — Individual skill panel in Latest mode
- Progression Tree Viewport — Optional pan/zoom controller for the runtime UI
- IProgressionTreeReference — Interface for flexible tree references
- ProgressionTreeReference — Wrapper class for tree asset references
Progression Tree
Scriptable ObjectThe main object that defines a complete skill tree.
Create via:
Create → Game Creator → Progression Tree Builder → Progression TreeProperties
| Property | Type | Description |
|---|---|---|
| Tree Name | string | Name of the tree displayed in the UI |
| Description | string | Description of the tree |
| Skills | List<ProgressionSkill> | All skills in this tree |
| Root Skills | List<ProgressionSkill> | Skills without prerequisites |
| Allow Respec | bool | Can skills be reset? |
| Layout Type | enum | Vertical, Horizontal, Radial, or Free-form |
| Choice Groups | List<ChoiceGroup> | Groups where only one skill can be chosen |
| Point Pool ID | string | Empty (default) = this tree keeps its own point pool. Set the same non-empty ID on several trees to share one available/earned skill point bank via ProgressionTreeManager. Unlock state, skill ranks and Max Skill Points always stay per tree. |
Progression Skill
Scriptable ObjectDefines a single skill or ability.
Create via:
Create → Game Creator → Progression Tree Builder → Progression SkillProperties
| Property | Type | Description |
|---|---|---|
| Skill Name | string | Display name of the skill |
| Description | string | What does this skill do? |
| Icon | Sprite | Icon for the UI |
| Skill Type | enum | Passive, Active, or Choice |
| Max Rank | int | Maximum level (1 = not upgradeable) |
| Base Skill Point Cost | int | Cost to unlock |
| Selection Weight | int | Weight for Latest mode (1-100, higher = more common) |
| Required Skills | List<ProgressionSkill> | Skills that must be unlocked first |
| Requirement Mode | enum | All (default): every Required Skill must be unlocked. Any: needs at least Minimum Required Count of them (0 = any single one) |
| Item Costs | List<ItemCostEntry> | Optional GC2 Inventory item costs (Unique ID + amount). See the Item & Currency Costs guide |
| Currency Costs | List<CurrencyCostEntry> | Optional GC2 Inventory currency costs (Unique ID + amount). See the Item & Currency Costs guide |
| Stat Modifiers | List<SkillStatModifier> | Stats that are modified |
Progression Tree Manager
MonoBehaviourManages the runtime state of all Progression Trees.
Properties
| Property | Type | Description |
|---|---|---|
| Target Character | GameObject | GameObject with Traits component |
| Available Trees | List<TreeConfig> | List of all available trees |
| Auto Unlock Trees | bool | Unlock all trees automatically? |
| Use Separate Points | bool | Each tree has its own points vs. global |
Methods
UnlockSkill(tree, skill) → bool
UpgradeSkill(tree, skill) → bool
GetSkillRank(tree, skill) → int
IsSkillUnlocked(tree, skill) → bool
GetAvailablePoints(tree) → int
RefreshLatestPool(tree, count) → void
GetCurrentLatestPool(tree) → List<ProgressionSkill>
RespecTree(tree) → bool
GetBlockReason(tree, skill) → string
CanAffordTreeUnlock(tree) → bool
CanAffordTreeRespec(tree) → boolSkill Instruction Manager
MonoBehaviourCentral manager for all scene-based skill instructions. Automatically finds and executes SkillInstructions components when skills are triggered. Add this component to your ProgressionTreeManager GameObject.
Properties
| Property | Type | Description |
|---|---|---|
| Auto Find On Awake | bool | Automatically find all SkillInstructions in scene on start |
| Search Children Only | bool | Limit search to children only (false = search entire scene) |
| Debug Mode | bool | Log when instructions are executed for debugging |
| Registered Skills | List<SkillInstructions> | All found SkillInstructions components (read-only) |
Methods
FindAllSkillInstructions() → void
GetSkillInstructions(skillId) → SkillInstructions
HasInstructions(skillId) → bool
ExecuteOnUnlocked(skillId, args) → void
ExecuteOnActivated(skillId, args) → void
ExecuteOnUpgrade(skillId, args) → void
RegisterSkill(skill) → voidSkill Instructions
MonoBehaviourScene-based instruction component that executes Game Creator Instructions for a specific skill. Supports GameObject drag & drop references and scene-specific behavior. Each skill can have multiple SkillInstructions components across different scenes.
Properties
| Property | Type | Description |
|---|---|---|
| Skill | ProgressionSkill | The skill this component controls (required) |
| Use On Unlocked | bool | Execute instructions when skill is unlocked |
| On Unlocked | InstructionList | Instructions to run when unlocked |
| Use On Activated | bool | Execute instructions when skill is activated |
| On Activated | InstructionList | Instructions to run when activated |
| Use On Upgrade | bool | Execute instructions when skill ranks up |
| On Upgrade | InstructionList | Instructions to run on upgrade |
Methods
GetSkillID() → string
GetSkillName() → string
GetSkill() → ProgressionSkill
ExecuteOnUnlocked(args) → Task
ExecuteOnActivated(args) → Task
ExecuteOnUpgrade(args) → Task
HasAnyInstructions() → bool
HasSkillAssigned() → boolProgression Tree UI Controller
MonoBehaviourControls the entire UI display and user interaction.
Properties
| Property | Type | Description |
|---|---|---|
| Layout Mode | enum | Grid, Graph, List, or Latest |
| Grid Columns | int | Number of columns in Grid mode |
| Details Panel Alignment | enum | Position of the details popup |
| Latest Node Count | int | How many skills to show in Latest mode (2-6) |
| Latest Column Spacing | float | Space between panels in Latest mode |
| Auto Refresh On All Maxed | bool | Refresh pool when all skills are maxed |
| Column Width | float | Fixed width per column (0 = auto-fit) |
| Padding | float | Distance to screen edges |
| Show Block Reason | bool | Show why a skill is currently blocked (tree locked, choice group, level, missing prerequisite, rank requirement, stat requirement, tree point limit, not enough points) in the tooltip/detail panel |
Methods
OpenTree(tree) → void
CloseTree() → void
SwitchToTree(tree) → void
SelectSkill(skill) → void
RefreshUI() → void
GetBlockReason(skill) → string
FocusOnSkill(skill) → voidLatest Mode Layout Controller
MonoBehaviourSpecialized controller for roguelike-style Latest mode with N detail panels side-by-side. Handles weighted random skill selection and pool refresh mechanics.
Properties
| Property | Type | Description |
|---|---|---|
| Node Count | int | Number of skill panels (2-6) |
| Column Spacing | float | Space between panels |
| Detail Panel Prefab | GameObject | Prefab for skill panels |
| Auto Refresh On All Maxed | bool | Refresh when all visible skills maxed |
Methods
RefreshPool(count) → void
GetCurrentPool() → List<ProgressionSkill>
SelectSkillFromPool(index) → voidLatest Mode Detail Panel
MonoBehaviourIndividual skill panel used in Latest mode. Displays skill details and handles unlock interaction.
Properties
| Property | Type | Description |
|---|---|---|
| Skill Icon | Image | UI Image for skill icon |
| Skill Name | TextMeshProUGUI | Skill name display |
| Description | TextMeshProUGUI | Skill description |
| Cost Display | TextMeshProUGUI | Point cost display |
| Unlock Button | Button | Button to unlock skill |
Methods
SetSkill(skill) → void
UpdateState() → void
OnUnlockClicked() → voidProgression Tree Viewport
MonoBehaviourOptional pan & zoom controller for the runtime tree UI. Add it to the Scroll View's Viewport GameObject to get clamped mouse-wheel zoom and a pinch-friendly API for touch. Without this component the UI behaves exactly as before.
Properties
| Property | Type | Description |
|---|---|---|
| Min Zoom | float | Closest zoom level allowed |
| Max Zoom | float | Furthest zoom level allowed |
| Zoom Speed | float | Mouse-wheel zoom sensitivity |
Methods
Pinch(delta) → void
FocusOn(node) → void
ResetView() → voidLayout Modes
| Mode | Description |
|---|---|
| Grid | Skills in N columns, simple and clean |
| Graph | Visual tree with connections showing dependencies |
| List | Vertical list with filter/sort options |
| Latest | Roguelike mode - shows random pool of skills |
Skill Types
| Type | Example | Description |
|---|---|---|
| Passive | Health Boost | Effects are always active. |
| Active | Fireball Spell | Must be activated manually. Use On Unlock Actions. |
| Choice | Warrior vs Mage | Part of a Choice Group - only one can be chosen. |
Stat Modifiers
| Type | Example | Description |
|---|---|---|
| Flat | +10 Health | Fixed value is added |
| Percentage | +15% Damage | Percentage bonus |
| Per Rank | +5 per Rank | Scales with skill rank |
Shared Point Pools (Point Pool ID)
Every ProgressionTree has an optional Point Pool ID field (empty by default). Set the same non-empty ID on two or more trees to have them share one available/earned skill point bank via ProgressionTreeManager instead of each tree keeping its own — for example a "Class Points" pool spent across three specialization trees.
- Empty (default) = the tree's own ID is used as the key, i.e. every tree keeps its own pool — unchanged behaviour.
- Same non-empty ID on several trees = awarding, spending, unlocking and upgrading skills all read/write the same bank.
- Only the point bank is shared. Each tree's own unlock state, Max Skill Points limit and skill ranks stay per tree.
- Locking a tree resets its pool to 0, unless another tree that is still unlocked shares the same pool — in that case the shared bank is left untouched for that other tree.
Game Creator 2 Integration
Everything below appears in the normal Game Creator pickers under the Progression Tree category: 12 Instructions, 8 Conditions and 1 Property.
Instructions (12)
| Instruction | Menu Path | What it does |
|---|---|---|
| Unlock Tree | Progression Tree > Tree > Unlock Tree | Unlocks a tree, awards its starting points and auto-unlocks its Root skills. Checks the minimum level and the unlock cost. |
| Lock Tree | Progression Tree > Tree > Lock Tree | Locks a tree again and resets its progress. Removes the stat modifiers of its skills and never charges the respec cost. |
| Respec Tree | Progression Tree > Tree > Respec Tree | Resets every non-Root skill of a tree, refunds the spent points and removes the skills' stat modifiers. Checks the respec cost. |
| Unlock Skill | Progression Tree > Skill > Unlock Skills | Unlocks a single skill at rank 1 if its requirements are met and enough points are available. |
| Upgrade Skill | Progression Tree > Skill > Upgrade Skill | Raises an already unlocked skill by one rank. |
| Activate Skill | Progression Tree > Skill > Activate Skills | Triggers an Active skill: checks the cooldown, checks and consumes the skill's activation costs, then runs the skill's On Activated instructions. |
| Award Skill Points | Progression Tree > Points > Awards Points | Adds progression points to a tree. |
| Spend Skill Points | Progression Tree > Points > Spend Points | Removes progression points from a tree without unlocking anything (for custom costs). |
| Open Progression Tree UI | Progression Tree > UI > Open Progression Tree UI | Opens a tree on a ProgressionTreeUIController. |
| Close Progression Tree UI | Progression Tree > UI > Close Progression Tree UI | Closes the tree UI. |
| Refresh Progression Tree UI | Progression Tree > UI > Refresh Progression Tree UI | Rebuilds the visible nodes, e.g. after changing progression from script. |
| Refresh Latest Pool | Progression Tree > Latest > Refresh Latest Mode | Rerolls the weighted pick-N pool of a tree in Latest Mode. |
Conditions (8)
| Condition | Menu Path | True when |
|---|---|---|
| Is Skill Unlocked | Progression Tree > Skill > Is Skill Unlocked | The skill is unlocked in the given tree |
| Can Unlock Skill | Progression Tree > Skill > Can Unlock Skill | Requirements, prerequisites, choice groups and available points allow unlocking it |
| Can Upgrade Skill | Progression Tree > Skill > Can Upgrade Skill | The skill is below its max rank and the next rank is affordable |
| Has Available Skill | Progression Tree > Skill > Has Available Skill | At least one skill in the tree could be unlocked right now |
| Is Skill On Cooldown | Progression Tree > Skill > Is Skill On Cooldown | An Active skill is still cooling down |
| Is Progression Tree Unlocked | Progression Tree > Tree > Is Tree Unlocked | The tree is unlocked for the player |
| Progression Points Comparison | Progression Tree > Points > Progression Points Comparison | The tree's available points compare as configured |
| Progression Rank Comparison | Progression Tree > Points > Skill Rank Comparison | A skill's current rank compares as configured |
Property (1)
| Property | Menu Path | Returns |
|---|---|---|
| Progression Tree | Progression Tree > Tree Reference | A ProgressionTree, either a direct reference or resolved from a ProgressionTreeGraphAsset. Used by every Instruction and Condition above, so a graph asset and a runtime tree are interchangeable. |
Code Examples
Unlock Skill
// Get reference to manager
var manager = ProgressionTreeManager.Instance;
// Unlock a skill
bool success = manager.UnlockSkill(myTree, mySkill);
if (success)
{
Debug.Log("Skill unlocked!");
}Refresh Latest Pool
// Refresh pool with 3 new skills
manager.RefreshLatestPool(myTree, 3);
// Get current pool
var currentPool = manager.GetCurrentLatestPool(myTree);
Debug.Log($"Pool size: {currentPool.Count}");Listen to Skill Events
// Subscribe to unlock events
manager.OnSkillUnlocked.AddListener((tree, skill) =>
{
Debug.Log($"Unlocked: {skill.skillName}");
});
// Subscribe to upgrade events
manager.OnSkillUpgraded.AddListener((tree, skill, newRank) =>
{
Debug.Log($"{skill.skillName} now rank {newRank}");
});UI Widgets (Optional)
Optional UI components that enhance user experience by providing real-time progression feedback. All widgets use interface-based architecture for easy customization.
Progression Notification System
MonoBehaviourWidgetToast-style notification system that displays events in real-time. Automatically subscribes to progression events and queues multiple notifications.
Properties
| Property | Type | Description |
|---|---|---|
| notificationPrefab | GameObject | Prefab for notification toasts |
| maxQueueSize | int | Maximum notifications in queue (default: 5) |
| displayDuration | float | Seconds each notification displays |
| fadeInDuration | float | Fade-in animation time |
| fadeOutDuration | float | Fade-out animation time |
Interface
public interface IProgressionNotificationSystem : IProgressionUIWidget
{
void ShowNotification(NotificationType type, string title, string message, Sprite icon = null);
void SetQueueSize(int size);
void ClearAll();
}Supported Events
- Skill Unlocked
- Skill Upgraded
- Points Awarded
- Tree Unlocked
Skill Points HUD Widget
MonoBehaviourWidgetHUD element displaying available progression points. Can be clicked to open the tree UI. Features pulse effect on points gained and auto-refresh.
Properties
| Property | Type | Description |
|---|---|---|
| pointsText | TextMeshProUGUI | Text field showing point count |
| iconImage | Image | Icon graphic |
| clickToOpenTree | bool | Enable click to open tree UI (default: true) |
| pulseOnPointsGained | bool | Show pulse effect on points awarded (default: true) |
| uiController | ProgressionTreeUIController | Optional - auto-finds if not assigned |
Interface
public interface IProgressionPointsDisplay : IProgressionUIWidget
{
void UpdatePoints(ProgressionTree tree, int availablePoints);
void SetTrackedTree(ProgressionTree tree);
void SetClickable(bool clickable);
}Methods
SetTrackedTree(tree)- Set which tree to display points forUpdatePoints(tree, points)- Manually update displayRefresh()- Refresh from current tree data
Skill Unlock Animation Overlay
MonoBehaviourWidgetFullscreen celebration overlay for skill unlocks. Automatically detects if tree UI is open and only displays when UI is closed to avoid visual clutter.
Properties
| Property | Type | Description |
|---|---|---|
| overlayPanel | GameObject | Main overlay container |
| skillIcon | Image | Skill icon display |
| skillNameText | TextMeshProUGUI | Skill name display |
| autoDismiss | bool | Auto-close after duration (default: true) |
| autoDismissDuration | float | Seconds before auto-dismiss (default: 3) |
| playOnUpgrade | bool | Show on rank upgrades (default: false) |
| uiController | ProgressionTreeUIController | For detecting tree UI state |
Interface
public interface ISkillUnlockAnimation : IProgressionUIWidget
{
void PlayUnlockAnimation(ProgressionSkill skill, int rank);
void SetAutoDismiss(bool auto, float duration = 3f);
bool IsPlaying();
}Customization
- Edit prefab to change panel size, colors, fonts
- Add custom particle systems for celebration effects
- Modify fade-in/out durations
- Add sound effects via Game Creator Audio instructions
IProgressionUIWidget (Base Interface)
InterfaceBase interface inherited by all UI widgets. Implement this to create custom progression widgets.
Interface
public interface IProgressionUIWidget
{
// Called when widget should initialize
void Initialize(ProgressionTreeManager manager);
// Called when widget should clean up
void Cleanup();
// Check if widget is active
bool IsActive { get; }
// Enable/disable widget
void SetActive(bool active);
}Implementation Tips
- Always null-check the manager reference
- Subscribe to events in Initialize(), unsubscribe in Cleanup()
- Use FindObjectOfType<ProgressionTreeManager>() if manager not provided
- Gracefully handle missing references for drag-drop flexibility