MayHeCome/Assets/三问c#/TreeControl.cs
2024-12-18 17:55:34 +08:00

578 lines
17 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using DG.Tweening;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class TreeControl : MonoSingleton<TreeControl>
{
[Header("面板UI")]
public GameObject CanvasUI;
private CanvasGroup canvasGroup;
private Sequence showSequence; // 缓存的打开动画序列
private Sequence hideSequence; // 缓存的关闭动画序列
[Header("树节点头部")]
public TechItem HeadItem;
[Header("解锁亮光强度")]
public float MaxLightNum;
[Header("解锁线宽度")]
public float MaxLineWidth;
[Header("未解锁亮光强度")]
public float MinLightNum;
[Header("未解锁线宽度")]
public float MinLineWidth;
[Header("点击所需时间")]
public float NeedTimes;
private Transform NodePa;
private Dictionary<Transform, TechItem> BlindItem;
private Dictionary<TechItem, Transform> BlindObj;
public Dictionary<string, TechItem> TechItems;
private Action FollowLineStyle;
private Action MainStyle;
private float currenttimes;
[HideInInspector]
public GameObject currentobj;
private TechItem currentItem;
private Dictionary<string, Action> NodeEvent;
public Material LockLinematerial;//亮线
public Material UnLockLineMaterial;//暗线
public GameObject lineObj;
public List<UI_InformationPanel.BTInfo> NoTechInfo;
public bool DebugRemainUnLock = false;
public Image TimeImage;//时间冷却图像
public override void Awake()
{
base.Awake();
canvasGroup = CanvasUI.transform.GetComponent<CanvasGroup>();
CanvasUI.SetActive(false);
// 创建动画序列
CreateSequences();
NodePa = transform.Find("节点组");
BlindItem = new Dictionary<Transform, TechItem>();
BlindObj = new Dictionary<TechItem, Transform>();
TechItems = new Dictionary<string, TechItem>();
Instance.UINameOpen(false);
}
private void Start()
{
InfoBlind(HeadItem);
CreatTree(HeadItem);
}
private void Update()
{
FollowLineStyle?.Invoke();
MainStyle?.Invoke();
// Vector3 pos = Camera.main.WorldToViewportPoint (CanvasUI.transform.position);
// pos.x = Mathf.Clamp01(pos.x);
// pos.y = Mathf.Clamp01(pos.y);
// CanvasUI.transform.position = Camera.main.ViewportToWorldPoint(pos);
}
#region
private void InfoBlind(TechItem techItem)
{
if(!DebugRemainUnLock)techItem.LockOver = false;
Debug.LogWarning("====" + techItem.itemName);
Transform trans = NodePa.Find(techItem.itemName);
Debug.LogWarning("---" + trans.name);
if (!BlindItem.ContainsKey(trans))
{
TechItems[techItem.itemName]= techItem;
Debug.Log(techItem.itemName + " keji add " + trans.name);
BlindItem.Add(trans, techItem);
BlindObj.Add(techItem, trans);
foreach (var item in techItem.children)
{
InfoBlind(item);
}
trans.Find("科技名UI/名字").GetComponent<Text>().text = techItem.itemName;
}
}
public void CreatTree(TechItem techItem, HashSet<string> names = null)
{
if (names == null)
{
names = new HashSet<string>();
}
if (!names.Contains(techItem.itemName))
{
names.Add(techItem.itemName);
BlindLineConnect(techItem);
foreach (var item in techItem.children)
{
CreatTree(item, names);
}
}
}
private void LightNode(TechItem techItem)
{
Transform SelfTrans = BlindObj[techItem];
Light2D light = SelfTrans.GetComponent<Light2D>();
LightOpenALL(light);
}
private void NoLightNode(TechItem techItem)
{
Transform trans = BlindObj[techItem];
Light2D light = trans.GetComponent<Light2D>();
LightClose(light);
}
/// <summary>
/// 已解锁亮光
/// </summary>
private void LightOpenALL(Light2D light)
{
Debug.Log("已经解锁亮光");
light.intensity = MaxLightNum;
}
/// <summary>
/// 未解锁-小亮
/// </summary>
/// <param name="light"></param>
private void LightClose(Light2D light)
{
light.intensity = MinLightNum;
}
/// <summary>
/// 绑定线
/// </summary>
private void BlindLineConnect(TechItem techItem)
{
Transform SelfTrans = BlindObj[techItem];
// 遍历所有父节点
if (techItem.parent != null && techItem.parent.Count > 0)
{
// 遍历所有父节点
for (int i = 0; i < techItem.parent.Count; i++)
{
TechItem parent = techItem.parent[i];
if (BlindObj.TryGetValue(parent, out Transform SelfTransPa))
{
// 创建一个空的子物体用于存放 LineRenderer
GameObject lineRendererObject = Instantiate(lineObj, SelfTransPa);
lineRendererObject.name = SelfTrans.name;
lineRendererObject.transform.localPosition = Vector3.zero; // 确保位置保持一致
// 为这个新创建的子物体添加 LineRenderer
LineRenderer newLineRenderer = lineRendererObject.GetComponent<LineRenderer>();
// 为该父节点的连接线添加 LineFollow 逻辑
FollowLineStyle += () => LineFollow(SelfTrans, newLineRenderer);
LineBuild(newLineRenderer, techItem.LockOver);
if (techItem.MainTech && BlindItem[SelfTransPa].MainTech)//两个都是主干
{
lineRendererObject.SetActive(true);
}
}
}
}
else
{
if (techItem == HeadItem) // 处理头节点的情况
{
Transform SelfTransPa = SelfTrans.parent;
LineRenderer newLineRenderer = SelfTransPa.GetComponent<LineRenderer>();
LineBuild(newLineRenderer, techItem.LockOver);
FollowLineStyle += () => LineFollow(SelfTrans, newLineRenderer);
}
}
if (techItem.LockOver) // 已解锁直接点亮
{
GetLightAnimation(techItem);
}
else
{
NoLightNode(techItem);
}
if (techItem.MainTech || techItem.LockOver)
{
SelfTrans.gameObject.SetActive(true);
}
else
{
SelfTrans.gameObject.SetActive(false);
}
}
private void LineBuild(LineRenderer lineRenderer, bool islock)
{
if (islock)
{
lineRenderer.startWidth = MaxLineWidth;
lineRenderer.endWidth = MaxLineWidth;
lineRenderer.material = LockLinematerial;
}
else
{
lineRenderer.startWidth = MinLineWidth;
lineRenderer.endWidth = MinLineWidth;
lineRenderer.material = UnLockLineMaterial;
}
}
private void LineFollow(Transform target, LineRenderer line)
{
Vector3 pos = line.transform.InverseTransformPoint(target.position);
line.SetPosition(1, pos);
}
#endregion
#region
public void BtnDowm() // 鼠标点到了
{
string str = "";
if (currentobj != null)
{
TechItem techItem = BlindItem[currentobj.transform];
if (!techItem.LockOver) // 自身未解锁
{
if (GodComeTIemsEnough(techItem, ref str))
{
if (techItem.ResourceEnough()) // 资源足够
{
if (techItem == HeadItem) // 如果是头节点
{
currenttimes = 0;
MainStyle = KeepTime;
currentobj.GetComponent<DoweenAnimator>().enabled = true;
Debug.Log("点亮");
}
else
{
if (AreAllParentsUnlocked(techItem)) // 检查所有父节点是否已解锁
{
currenttimes = 0;
MainStyle = KeepTime;
currentobj.GetComponent<DoweenAnimator>().enabled = true;
Debug.Log("点亮");
}
else str = "相邻节点未解锁完";
}
CanvasUI.transform.Find("内容").GetComponent<Text>().color = Color.yellow;
}
else CanvasUI.transform.Find("内容").GetComponent<Text>().color = Color.red;
}
}
}
ChangeCanvasContect(str);
}
/// <summary>
/// 检查所有父节点是否都已解锁
/// </summary>
private bool AreAllParentsUnlocked(TechItem techItem)
{
if (techItem.parent == null || techItem.parent.Count == 0)
return true; // 如果没有父节点,返回 true
foreach (var parent in techItem.parent)
{
if (!parent.LockOver) // 只要有一个父节点未解锁,就返回 false
{
return false;
}
}
return true; // 如果所有父节点都已解锁,返回 true
}
private bool GodComeTIemsEnough(TechItem techItem, ref string str)
{
List<GodComingTimes> gods = YiShiUI.Instance.godComingTimes;
for (int i = 0; i < gods.Count; i++)
{
if (gods[i].godType == techItem.GodTimes.godType)
{
if (gods[i].Count >= techItem.GodTimes.Count)
{
return true;
}
else
{
str = "降神次数不足!" + gods[i].GetGodName() + ":(" + gods[i].Count + "/" + techItem.GodTimes.Count + ")";
return false;
}
}
}
return false;
}
public void BtnUp()//鼠标释放或者点亮了
{
TimeImage.fillAmount = 0;
MainStyle = null;
if (currentobj != null && currentobj.TryGetComponent(out DoweenAnimator doween))
{
doween.enabled = false;
}
currentobj = null;
}
public void KeepTime()//计时
{
currenttimes += Time.deltaTime;
TimeImage.transform.position = currentobj.transform.position;
TimeImage.fillAmount = currenttimes / NeedTimes;
if (currenttimes >= NeedTimes)
{
PlayEvent(BlindItem[currentobj.transform].itemName);
GetLightAnimation(BlindItem[currentobj.transform]);
CutReource();
BtnUp();
}
}
private void GetLightAnimation(TechItem techItem)//点亮效果
{
if (techItem == HeadItem)
{
if (transform.Find("节点组").TryGetComponent(out LineRenderer line))
{
LineBuild(line, true);
}
}
else
{
foreach (TechItem item in techItem.parent)
{
Transform pa = BlindObj[item];
Transform child = pa.Find(techItem.itemName);
child.gameObject.SetActive(true);
if (child.TryGetComponent(out LineRenderer lineone))
{
LineBuild(lineone, true);
}
}
}
Transform currentobj = BlindObj[techItem];
if (currentobj.TryGetComponent(out Light2D light2D))
{
LightOpenALL(light2D);
}
CanvasUI.transform.Find("内容").GetComponent<Text>().text = "";
Refreshtech(currentobj.transform);
}
private void CutReource() //消耗资源
{
BlindItem[currentobj.transform].LockTech();
}
#endregion
#region CanvasUI动画
/// <summary>
/// 创建动画序列,用于打开和关闭 UI
/// </summary>
private void CreateSequences()
{
// 打开动画序列
showSequence = DOTween.Sequence()
.AppendCallback(() => CanvasUI.SetActive(true))
.Append(canvasGroup.DOFade(1, 0.1f))
.OnComplete(() =>
{
canvasGroup.interactable = true;
canvasGroup.blocksRaycasts = true;
})
.Pause() // 暂停动画
.SetAutoKill(false); // 防止动画自动销毁
// 关闭动画序列
hideSequence = DOTween.Sequence()
.Append(canvasGroup.DOFade(0, 0.1f))
.OnComplete(() =>
{
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
CanvasUI.SetActive(false);
})
.Pause() // 暂停动画
.SetAutoKill(false); // 防止动画自动销毁
}
public void ChangeUIcontect(Transform trans) //ui内容改变
{
currentItem = BlindItem[trans];
}
public void ChangeCanvasContect(string str)
{
TechItem techItem = currentItem;
CanvasUI.transform.Find("名字").GetComponent<Text>().text = techItem.itemName;
CanvasUI.transform.Find("描述").GetComponent<Text>().text = techItem.Describe;
CanvasUI.transform.Find("功能").GetComponent<Text>().text = techItem.FunDescription;
string contectstr = "";
if (str != "") contectstr = "[" + str + "]" + "\n"; ;
for (int i = 0; i < techItem.needReources.Count; i++)
{
string kindname = techItem.needReources[i].kind.ToString();
string countstr = techItem.needReources[i].Count.ToString();
contectstr += countstr ;
}
if (!techItem.LockOver)
{
CanvasUI.transform.Find("内容").GetComponent<Text>().text = contectstr;
CanvasUI.transform.Find("ICON").gameObject.SetActive(true);
}
else
{
CanvasUI.transform.Find("内容").GetComponent<Text>().text = "";
CanvasUI.transform.Find("ICON").gameObject.SetActive(false);
}
}
/// <summary>
/// 打开 UI
/// </summary>
public void ActiveUITrue(Vector3 pos)
{
CanvasUI.transform.position = new Vector3(pos.x, pos.y, CanvasUI.transform.position.z);
CanvasUI.SetActive(true);
canvasGroup.alpha = 0;
// 如果关闭动画正在播放,停止它
if (hideSequence.IsActive() && hideSequence.IsPlaying())
{
hideSequence.Restart();
hideSequence.Pause();
}
// 播放打开动画
showSequence.Restart();
UINameOpen(false);
}
/// <summary>
/// 关闭 UI
/// </summary>
public void ActiveUIFalse()
{
// 如果打开动画正在播放,停止它
if (showSequence.IsActive() && showSequence.IsPlaying())
{
showSequence.Restart();
showSequence.Pause();
}
// 播放关闭动画
hideSequence.Restart();
UINameOpen(true);
}
public void UINameOpen(bool open)
{
foreach (Transform child in transform.Find("节点组"))
{
child.Find("科技名UI").gameObject.SetActive(open);
}
}
#endregion
#region
public void AddEvent(string EventName, Action action)
{
if (NodeEvent == null)
{
NodeEvent = new Dictionary<string, Action>();
}
if (NodeEvent.TryGetValue(EventName, out Action events))
{
events += action;
NodeEvent[EventName] = events;
}
else
{
NodeEvent.Add(EventName, action);
}
}
public string[] GetDescription(string techName)
{
TechItem item = TechItems[techName];
return new[] { item.Describe, item.FunDescription };
}
private void PlayEvent(string EventName)
{
if (NodeEvent.TryGetValue(EventName, out Action action))
{
Debug.LogWarning("触发");
action?.Invoke();
}
else
{
Debug.LogError("不存在该事件名");
}
}
#endregion
public void Refreshtech(Transform trans) //子节点是否能打开
{
foreach (Transform child in trans)
{
if (child.name != "科技名UI")
{
child.gameObject.SetActive(true);
Debug.LogWarning(child.name);
transform.Find("节点组/" + child.name).gameObject.SetActive(true);
}
}
}
public UI_InformationPanel.BTInfo GetTechInfo(string name)
{
Debug.Log("Kejishu "+name);
if (TechItems.ContainsKey(name))
{
TechItem ti= TechItems[name];
return new UI_InformationPanel.BTInfo(ti.itemName, ti.FunDescription, ti.Describe);
}
else
{
foreach (UI_InformationPanel.BTInfo bti in NoTechInfo)
{
if (bti.BITName == name) return bti;
}
return null;
}
}
}