Stannellc icon

Skill Tree UI

Stannellc | PRO | 08/19/26 01:37:50 PM UTC | 0 ⭐ | 5421 👁️ | Never ⏰ | []
C# |

7.73 KB

|

Gaming

|

0 👍

/

0 👎

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
 
/// <summary>
/// Manages the UI display for the skill tree, dynamically creating buttons
/// and updating their state based on player progression.
/// </summary>
public class SkillTreeUI : MonoBehaviour
{
    [Header("UI References")]
    [Tooltip("The parent transform where all skill buttons will be instantiated.")]
    public Transform skillButtonParent;
    [Tooltip("The prefab for a single skill button.")]
    public GameObject skillButtonPrefab;
    [Tooltip("Text element to display the player's available skill points.")]
    public TextMeshProUGUI availableSkillPointsText;
 
    [Header("Skill Info Pop-up")]
    [Tooltip("The panel that displays the skill information.")]
    public GameObject skillInfoPopupPanel;
    [Tooltip("Text element for the skill's name in the pop-up.")]
    public TextMeshProUGUI skillNameText;
    [Tooltip("Text element for the skill's description in the pop-up.")]
    public TextMeshProUGUI skillDescriptionText;
    [Tooltip("Text element for the skill's cost in the pop-up.")]
    public TextMeshProUGUI skillCostText;
    [Tooltip("The button to learn the skill from the pop-up.")]
    public Button learnSkillButton;
 
    private SkillTreeManager skillTreeManager;
    private PlayerProgression playerProgression;
    private Dictionary<string, GameObject> skillButtons = new Dictionary<string, GameObject>();
    private string activeSkillID;
 
    private void Start()
    {
        // Get references to the singleton managers
        skillTreeManager = SkillTreeManager.Instance;
        playerProgression = PlayerProgression.Instance;
 
        if (skillTreeManager == null || playerProgression == null)
        {
            Debug.LogError("Required managers not found. Ensure SkillTreeManager and PlayerProgression are in the scene.");
            return;
        }
 
        // Subscribe to events to refresh the UI
        skillTreeManager.OnSkillLearned.AddListener(RefreshUI);
        playerProgression.OnSkillPointChanged.AddListener(RefreshUI);
 
        PopulateSkillTreeUI();
        RefreshUI();
 
        // Hide the pop-up panel at the start
        if (skillInfoPopupPanel != null)
        {
            skillInfoPopupPanel.SetActive(false);
        }
    }
 
    private void OnDestroy()
    {
        // Unsubscribe from events to prevent memory leaks
        if (skillTreeManager != null)
        {
            skillTreeManager.OnSkillLearned.RemoveListener(RefreshUI);
        }
        if (playerProgression != null)
        {
            playerProgression.OnSkillPointChanged.RemoveListener(RefreshUI);
        }
    }
 
    /// <summary>
    /// Instantiates buttons for all skills defined in the Skill Tree ScriptableObject.
    /// </summary>
    private void PopulateSkillTreeUI()
    {
        // This line was updated to get the ScriptableObject directly from the manager.
        SkillTree skillTreeData = skillTreeManager.GetComponent<SkillTreeManager>().skillTreeData;
        
        foreach (Skill skill in skillTreeData.skills)
        {
            GameObject newButton = Instantiate(skillButtonPrefab, skillButtonParent);
            skillButtons[skill.skillID] = newButton;
            
            // Get the button's components
            Button buttonComponent = newButton.GetComponent<Button>();
            TextMeshProUGUI skillNameText = newButton.GetComponentInChildren<TextMeshProUGUI>();
            Image skillIcon = newButton.GetComponentInChildren<Image>(); // Assuming the image is a child
 
            // Set the skill button's text and icon
            if (skillNameText != null) skillNameText.text = skill.skillName;
            if (skillIcon != null && skill.icon != null) skillIcon.sprite = skill.icon;
            
            // Add a listener to the button's click event
            buttonComponent.onClick.AddListener(() => OnSkillButtonClicked(skill.skillID));
        }
    }
 
    /// <summary>
    /// Refreshes the state of all skill buttons based on player progression.
    /// </summary>
    private void RefreshUI()
    {
        // Update the available skill points text
        if (availableSkillPointsText != null)
        {
            availableSkillPointsText.text = $"Skill Points: {playerProgression.GetSkillPoints()}";
        }
 
        foreach (var pair in skillButtons)
        {
            string skillID = pair.Key;
            GameObject buttonObject = pair.Value;
            Button buttonComponent = buttonObject.GetComponent<Button>();
            
            // Check if the skill has been learned
            if (skillTreeManager.IsSkillLearned(skillID))
            {
                // Skill is learned: Disable the button and change its appearance
                buttonComponent.interactable = false;
                buttonComponent.image.color = Color.gray; // Example: change color to gray
            }
            else
            {
                // Skill is not learned: Check if it's learnable
                bool canLearn = CanLearnSkill(skillID);
                buttonComponent.interactable = canLearn;
                // Example: change color to green if learnable, red if not
                buttonComponent.image.color = canLearn ? Color.green : Color.red; 
            }
        }
    }
    
    /// <summary>
    /// Checks if a skill is currently learnable (has prerequisites and skill points).
    /// </summary>
    private bool CanLearnSkill(string skillID)
    {
        Skill skillData = skillTreeManager.GetSkillData(skillID);
        if (skillData == null) return false;
 
        // Check if player has enough skill points
        if (playerProgression.GetSkillPoints() < skillData.skillPointCost)
        {
            return false;
        }
 
        // Check if prerequisites are met
        foreach (string prereqID in skillData.prerequisites)
        {
            if (!skillTreeManager.IsSkillLearned(prereqID))
            {
                return false;
            }
        }
 
        return true;
    }
 
    /// <summary>
    /// Called when a skill button is clicked.
    /// </summary>
    /// <param name="skillID">The unique ID of the skill associated with the button.</param>
    private void OnSkillButtonClicked(string skillID)
    {
        // Show the info pop-up instead of trying to learn immediately.
        ShowSkillPopup(skillID);
    }
    
    /// <summary>
    /// Displays the skill info pop-up and populates it with data.
    /// </summary>
    /// <param name="skillID">The ID of the skill to display.</param>
    public void ShowSkillPopup(string skillID)
    {
        Skill skillData = skillTreeManager.GetSkillData(skillID);
        if (skillData == null) return;
 
        // Store the active skill ID to learn it later
        activeSkillID = skillID;
 
        // Populate the pop-up with skill data
        skillNameText.text = skillData.skillName;
        skillDescriptionText.text = skillData.description;
        skillCostText.text = $"Cost: {skillData.skillPointCost} SP";
 
        // Enable the "Learn" button if the skill is learnable
        learnSkillButton.interactable = CanLearnSkill(skillID);
 
        // Show the panel
        skillInfoPopupPanel.SetActive(true);
    }
 
    /// <summary>
    /// Called by the UI button to attempt learning the active skill.
    /// </summary>
    public void LearnSkillFromPopup()
    {
        skillTreeManager.TryLearnSkill(activeSkillID);
        skillInfoPopupPanel.SetActive(false);
    }
 
    /// <summary>
    /// Hides the skill info pop-up.
    /// </summary>
    public void HideSkillPopup()
    {
        skillInfoPopupPanel.SetActive(false);
    }
}

Comments