效果
技能树面板
技能配置
触发技能根据已解锁ID按照需求实现即可。
代码
面板类
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
using System.Linq;
using System.Collections.Generic;
using Unity.Linq;
using DG.Tweening;
public class SkillTreePanel : Monobehavior
{
void OnEnable()
{
//观察者模式监听技能点消耗的方法,可以自己写
EventCenter.Instance.AddEventListener("技能点变化", SkillPointsRefresh);
RefreshPanel();
}
void OnDisable()
{
EventCenter.Instance.RemoveEventListener("技能点变化", SkillPointsRefresh);
gameObject.SetActive(false);
}
void SkillPointsRefresh()
{
SkillPointsTxt.text = GameManager.CurrentSkillPoints.ToString();
}
//选中技能
public void UpdateCurrentSkill(SkillBtn skill)
{
if(skill != currentSkill)
{
currentSkill = skill.skill;
}
else
{
return;
}
RefreshPanel();
}
//加点
private void Add()
{
GameManager.CurrentSkillPoints -= 1;
preSkills.Add(currentSkill);
//这是我自己写的存档,可自行实现
var temp = GameManager.UnLockSkillID;
temp.Add(currentSkill.ID);
GameManager.UnLockSkillID = temp;
RefreshPanel();
}
//取消加点
private void Minus()
{
GameManager.CurrentSkillPoints += 1;
preSkills.Remove(currentSkill);
//存档
var temp = GameManager.UnLockSkillID;
temp.Remove(currentSkill.ID);
GameManager.UnLockSkillID = temp;
RefreshPanel();
}
//刷新面板显示
private void RefreshPanel()
{
//恢复颜色,关闭所有选中(这么写有点浪费性能,但无伤大雅)
allSkills.Values.ToList().ForEach(_ =>
{
_.transform.GetChild(0).GetComponent<Image>().color = Color.HSVToRGB(0, 0, 1);
_.transform.GetChild(1).gameObject.SetActive(false);
});
allSkills.Where(_ => !GameManager.UnLockSkillID.Contains(_.Key.ID)).Select(_ => _.Value).ToList().ForEach(_ => _.transform.GetChild(0).GetComponent<Image>().color = Color.HSVToRGB(0, 0, 0.5f));
//刷新当前技能信息
if (currentSkill != null)
{
//刷新技能信息
SkillInfoPanelTrans.gameObject.SetActive(true);
SkillNameTxt.text = currentSkill.name.Text;
SkillIntroTxt.text = currentSkill.des.Text;
//禁用+-按钮
MinusBtn.interactable = false;
AddBtn.interactable = false;
if (currentSkill.PreSkill.Count != 0)
{
if (currentSkill.isNeedAllPreSkill)
{
bool isAllUnlock = true; //用于标记是否全部合格
foreach (var item in currentSkill.PreSkill.Select(i => i.ID))
{
if (!GameManager.UnLockSkillID.Contains(item))
{
//未解锁
LockSkill();
isAllUnlock = false;
}
}
//全部符合条件
if (isAllUnlock)
{
//解锁
UnlockSkill();
}
}
else
{
if (GameManager.UnLockSkillID.Any(_ => currentSkill.PreSkill.Select(s => s.ID).Contains(_)))
{
//已解锁,可以+
UnlockSkill();
}
else
{
//未解锁,不能+
LockSkill();
}
}
}
else
{
//已解锁
UnlockSkill();
}
//显示选中效果
allSkills.First(_ => _.Key.ID == currentSkill.ID).Value.transform.GetChild(1).gameObject.SetActive(true);
}
else
{
//关闭技能信息面板
SkillInfoPanelTrans.gameObject.SetActive(false);
}
}
//技能权限解锁
void UnlockSkill()
{
SkillExIntroTxt.text = currentSkill.exDes.Text;
//如果没点数了或者已解锁过了就不能+ 这里只能加一次点
if (GameManager.CurrentSkillPoints == 0 || GameManager.UnLockSkillID.Contains(currentSkill.ID))
{
AddBtn.interactable = false;
}
else
{
AddBtn.interactable = true;
}
//只有本次加的可以选择- 而且不可以越过之后的能力-
if (preSkills.Any(_ => _.ID == currentSkill.ID) && !preSkills.Any(_ => _.PreSkill.Contains(currentSkill)))
{
MinusBtn.interactable = true;
}
else
{
MinusBtn.interactable = false;
}
}
void LockSkill()
{
SkillExIntroTxt.text = "请先解锁上一个能力!";
allSkills[currentSkill].transform.GetChild(0).GetComponent<Image>().color = Color.HSVToRGB(0, 0, 0.5f);
}
//开始游戏
private void StartGame()
{
//触发buff
SkillPointsTxt.text = GameManager.CurrentSkillPoints.ToString();
if (GameManager.CurrentSkillPoints != 0)
{
//提醒点数没加完是否进入游戏
//测试
preSkills.Clear();
HidePanel();
}
else
{
//下次就不可以-了
preSkills.Clear();
//进入游戏
HidePanel();
}
UIMgr.Instance.ShowUI<PlayerControlPanel>(UILayer.Bottom);
}
//重置技能点
private void ResetSkill()
{
GameManager.CurrentSkillPoints += GameManager.UnLockSkillID.Count;
var temp = GameManager.UnLockSkillID;
temp.Clear();
GameManager.UnLockSkillID = temp;
preSkills.Clear();
RefreshPanel();
}
//显示看广告加技能点面板
private void MorePoints()
{
GameManager.ExSkillPoints += 3;
GameManager.CurrentSkillPoints += 3;
RefreshPanel();
}
private SkillData currentSkill; //选中的技能
private Dictionary<SkillData,GameObject> allSkills = new Dictionary<SkillData,GameObject>(); //存储全部技能和按钮
private List<SkillData> preSkills = new List<SkillData>(); //本次调整的技能
//auto
private Transform ContentTrans = null;
private Transform SkillContentTrans = null;
private Button ResetBtn = null;
private Button StartGameBtn = null;
private Text SkillPointsTxt = null;
private Transform SkillInfoPanelTrans = null;
private Text SkillNameTxt = null;
private Text SkillIntroTxt = null;
private Text SkillExIntroTxt = null;
private Button AddBtn = null;
private Button MinusBtn = null;
private Button MoreSkillPointsBtn = null;
public override void Init()
{
base.Init();
ContentTrans = transform.Find("ContentTrans").GetComponent<Transform>();
SkillContentTrans = transform.Find("ContentTrans/Skills/Viewport/SkillContentTrans").GetComponent<Transform>();
ResetBtn = transform.Find("ContentTrans/ResetBtn").GetComponent<Button>();
StartGameBtn = transform.Find("ContentTrans/StartGameBtn").GetComponent<Button>();
SkillPointsTxt = transform.Find("ContentTrans/SkillPointsTxt").GetComponent<Text>();
SkillInfoPanelTrans = transform.Find("ContentTrans/SkillInfoPanelTrans").GetComponent<Transform>();
SkillNameTxt = transform.Find("ContentTrans/SkillInfoPanelTrans/IntroPanel/SkillNameTxt").GetComponent<Text>();
SkillIntroTxt = transform.Find("ContentTrans/SkillInfoPanelTrans/IntroPanel/SkillIntroTxt").GetComponent<Text>();
SkillExIntroTxt = transform.Find("ContentTrans/SkillInfoPanelTrans/IntroPanel/SkillExIntroTxt").GetComponent<Text>();
AddBtn = transform.Find("ContentTrans/SkillInfoPanelTrans/AddBtn").GetComponent<Button>();
MinusBtn = transform.Find("ContentTrans/SkillInfoPanelTrans/MinusBtn").GetComponent<Button>();
MoreSkillPointsBtn = transform.Find("ContentTrans/SkillInfoPanelTrans/MoreSkillPointsBtn").GetComponent<Button>();
//按钮注册
AddBtn.onClick.RemoveAllListeners();
AddBtn.onClick.AddListener(Add);
MinusBtn.onClick.RemoveAllListeners();
MinusBtn.onClick.AddListener(Minus);
StartGameBtn.onClick.RemoveAllListeners();
StartGameBtn.onClick.AddListener(StartGame);
ResetBtn.onClick.RemoveAllListeners();
ResetBtn.onClick.AddListener(ResetSkill);
MoreSkillPointsBtn.onClick.RemoveAllListeners();
MoreSkillPointsBtn.onClick.AddListener(MorePoints);
currentSkill = null;
allSkills.Clear();
preSkills.Clear();
SkillPointsRefresh();
//刷新技能图标
SkillContentTrans.gameObject.Children().ForEach(_ =>
{
var btn = _.GetComponent<SkillBtn>();
if (btn != null)
{
_.transform.GetChild(0).GetComponent<Image>().sprite = btn.skill.sprite;
allSkills.Add(_.GetComponent<SkillBtn>().skill, btn.gameObject);
}
});
}
}
技能配置
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Skill/SkillInfo", fileName = "Skill_")]
public class SkillData : ScriptableObject
{
public int ID;
public Sprite sprite;
public MultiLanguageText name;
public MultiLanguageText des;
public MultiLanguageText exDes;
public bool isNeedAllPreSkill;
public List<SkillData> PreSkill;
}