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)); } }