Encounter / Assets / Scripts / GUIHandlers / GraphicalSkillTree.cs
GraphicalSkillTree.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// UI Based Skill Tree that is the primary component on a skill tree object
/// </summary>
public class GraphicalSkillTree : MonoBehaviour
{
    [Header("Data Components")]
    [SerializeField] private string entityNameReference;     // Reference to the entity's name for comparison in injecting entity data
    [SerializeField] private List<SkillSO> skillsInTree;     // List of all of the skills available for this tree

    [Header("Material Components")]
    [SerializeField] private Material canBeChosenMaterial;
    [SerializeField] private Material lockedMaterial;
    [SerializeField] private Material glowMaterial;

    private Entity entityData;
    private EntitySkills entitySkills;

    public void InitializeTree()
    {
        AcquireEntityData();
        InitializeSkillData();
    }
    private void InitializeSkillData()
    {
        entitySkills ??= new EntitySkills(entityData, skillsInTree);
        InjectDataIntoButtons();

        Transform buttonTransform = transform.GetChild(0);
        TurnOnActiveButtons(new List<Skill> { }, buttonTransform);
        TurnOnInactiveButtons(skillsInTree, buttonTransform);
    }
    private void InjectDataIntoButtons()
    {
        foreach (SkillSO skill in skillsInTree)
        {
            foreach (Transform child in transform.GetChild(0))
            {
                string gatheredName = DecipherButtonSkill(child);

                if (skill.SkillName.Equals(gatheredName))
                {
                    bool isEnablingSkill = skill.IsEnablingSkill;
                    bool isEnabled = isEnablingSkill && entitySkills.IsSkillEnabled(skill);
                    child.GetComponent<SkillButton>().CallInitialization(entityData, skill, entitySkills.ContainsActivated(skill), isEnabled);
                }
            }
        }
    }
    private static string DecipherButtonSkill(Transform child)
    {
        string[] splitString = child.name.Split('_');
        string gatheredName = string.Empty;

        for (int i = 0; i < splitString.Length - 1; ++i)
        {
            gatheredName += splitString[i];
            if (i != splitString.Length - 2)
                gatheredName += " ";
        }

        return gatheredName;
    }
    /// <summary>
    /// Filters through the available data from the Game Manager to find the matching entity to the name indicated
    /// </summary>
    private void AcquireEntityData()
    {
        if (entityNameReference.Contains("Player"))
        {
            GameObject playerObject = GameManager.Instance.GetPlayerObject();
            entityData = playerObject.GetComponent<Player>();
        }
        else
        {
            GameObject[] allyObjects = GameManager.Instance.GetAllyObjects();
            foreach (GameObject allyObj in allyObjects)
            {
                Ally allyComp = allyObj.GetComponent<Ally>();
                if (entityNameReference.Equals(allyComp.GetName()))
                {
                    entityData = allyComp;
                    break;
                }
            }
        }
    }
    public void InjectExistingData(EntitySkills entitySkills)
    {
        AcquireEntityData();
        this.entitySkills = entitySkills;
        InjectDataIntoButtons();

        List<SkillSO> nonActiveSkills   = entitySkills.GetNonActivatedSkills();
        List<Skill> activeSkills        = entitySkills.GetActivatedSkills();
        List<Skill> enabledSkills       = entitySkills.GetEnabledSkills();
        List<Skill> disabledSkills      = entitySkills.GetDisabledSkills();

        Transform buttonTransform = transform.GetChild(0);

        TurnOnActiveButtons(activeSkills, buttonTransform);
        TurnOnInactiveButtons(nonActiveSkills, buttonTransform);

        ImplementEnabledSkills(enabledSkills);
        ImplementDisabledSkills(disabledSkills);
    }
    private void ImplementDisabledSkills(List<Skill> disabledSkills)
    {
        foreach (Skill skill in disabledSkills)
        {
            foreach (Transform child in transform.GetChild(0))
            {
                string gatheredName = DecipherButtonSkill(child);

                if (skill.GetName().Equals(gatheredName))
                {
                    child.GetComponent<Image>().material = null;
                    break;
                }
            }
        }
    }
    private void ImplementEnabledSkills(List<Skill> enabledSkills)
    {
        foreach (Skill skill in enabledSkills)
        {
            foreach (Transform child in transform.GetChild(0))
            {
                string gatheredName = DecipherButtonSkill(child);

                if (skill.GetName().Equals(gatheredName))
                {
                    child.GetComponent<Image>().material = glowMaterial;
                    break;
                }
            }
        }
    }
    private void TurnOnInactiveButtons(List<SkillSO> nonActiveSkills, Transform buttonTransform)
    {
        foreach (SkillSO skill in nonActiveSkills)
        {
            if (skill.RequiredSkills.Any(skill => nonActiveSkills.Contains(skill)))
                DecipherButtonLocations(buttonTransform, skill, lockedMaterial);
            else
                DecipherButtonLocations(buttonTransform, skill, canBeChosenMaterial);
        }
    }
    private void TurnOnActiveButtons(List<Skill> activeSkills, Transform buttonTransform)
    {
        foreach (Skill skill in activeSkills)
            DecipherButtonLocations(buttonTransform, skill, null);
    }
    private static void DecipherButtonLocations(Transform buttonTransform, object skill, Material material)
    {
        foreach (Transform child in buttonTransform)
        {
            string[] splitString = child.name.Split('_');
            string gatheredName = string.Empty;

            for (int i = 0; i < splitString.Length - 1; ++i)
            {
                gatheredName += splitString[i];
                if (i != splitString.Length - 2)
                    gatheredName += " ";
            }

            if (skill is Skill skillA)
            {
                if (gatheredName.Equals(skillA.GetName()))
                {
                    Image[] images = child.gameObject.GetComponentsInChildren<Image>();

                    images[0].material = material;
                    images[1].material = material;
                }
            }
            else if (skill is SkillSO skillIn)
            {
                if (gatheredName.Equals(skillIn.SkillName))
                {
                    Image[] images = child.gameObject.GetComponentsInChildren<Image>();

                    images[0].material = material;
                    images[1].material = material;
                }
            }
        }
    }
    /// <summary>
    /// Switches on the skill to a brighter material
    /// </summary>
    /// <param name="skill">The skill to activate on the tree graphically</param>
    public void SwitchOnSkill(SkillSO skill)
        => DecipherButtonLocations(transform.GetChild(0), skill, null);
    /// <summary>
    /// Retrieval for the name that is needed to access this skill tree
    /// </summary>
    /// <returns></returns>
    public string GetEntityNameReference()
        => entityNameReference;
    /// <summary>
    /// Retrieval for the skills data set attached
    /// </summary>
    /// <returns></returns>
    public EntitySkills GetSkillSet()
        => entitySkills;
    /// <summary>
    /// Attempts to activate the skill based on the data being passed
    /// </summary>
    /// <param name="skillToActivate">The Skill attempting to be activated</param>
    /// <returns>True if skill was successfully activated, false if otherwise</returns>
    public bool TryActivateSkill(SkillSO skillToActivate)
        => entitySkills.TryAddSkill(skillToActivate);
    public void DisableSkill(SkillSO skill, Image attachedImage)
    {
        entitySkills.DeactivateSkill(skill);

        attachedImage.material = null;
    }
    public void ReactivateSkill(SkillSO skill, Image attachedImage)
    {
        entitySkills.ReactivateSkill(skill);

        attachedImage.material = glowMaterial;
    }
    public void UpdateSkillTreeVisually(SkillSO skillData, Image image)
    {
        if (skillData.IsEnablingSkill)
            image.material = glowMaterial;

        TurnOnInactiveButtons(entitySkills.GetNonActivatedSkills(), transform.GetChild(0));
    }
}