first commit

This commit is contained in:
2026-06-04 22:14:21 +03:00
commit 677f9b8090
139 changed files with 15981 additions and 0 deletions
+279
View File
@@ -0,0 +1,279 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TalentTreeUI : MonoBehaviour
{
public TalentManager manager;
public PlayerStats playerStats;
[Header("Tree")]
public GameObject panelRoot;
public RectTransform lineRoot;
public RectTransform nodesRoot;
public TalentNodeUI nodePrefab;
public TalentTooltipUI tooltip;
[Header("Panels")]
public Text titleText;
public Text pointsText;
public Text controlsText;
public StatsPanelUI statsPanel;
[Header("Buttons")]
public Button saveButton;
public Button loadButton;
public Button resetButton;
public bool openOnStart;
private readonly List<TalentNodeUI> nodes = new List<TalentNodeUI>();
private readonly List<LineConnectorUI> lines = new List<LineConnectorUI>();
private bool isOpen;
private void Awake()
{
if (manager == null)
{
manager = FindObjectOfType<TalentManager>();
}
if (playerStats == null)
{
playerStats = FindObjectOfType<PlayerStats>();
}
}
private void OnEnable()
{
if (manager != null)
{
manager.OnTalentStateChanged += Refresh;
}
}
private void OnDisable()
{
if (manager != null)
{
manager.OnTalentStateChanged -= Refresh;
}
}
private void Start()
{
BindButtons();
BuildTree();
Refresh();
SetOpen(openOnStart);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{
Toggle();
}
}
public void Toggle()
{
SetOpen(!isOpen);
}
public void SetOpen(bool open)
{
isOpen = open;
if (panelRoot != null)
{
panelRoot.SetActive(open);
}
if (open)
{
Refresh();
UpdateLines();
}
}
public void BuildTree()
{
ClearChildren(nodesRoot);
ClearChildren(lineRoot);
nodes.Clear();
lines.Clear();
if (manager == null || nodePrefab == null || nodesRoot == null)
{
return;
}
Dictionary<TalentData, TalentNodeUI> nodeByTalent = new Dictionary<TalentData, TalentNodeUI>();
for (int i = 0; i < manager.allTalents.Count; i++)
{
TalentData talent = manager.allTalents[i];
if (talent == null)
{
continue;
}
TalentNodeUI node = Instantiate(nodePrefab, nodesRoot);
node.gameObject.SetActive(true);
node.tooltip = tooltip;
node.Setup(talent, manager);
RectTransform rectTransform = node.transform as RectTransform;
if (rectTransform != null)
{
rectTransform.anchoredPosition = talent.treePosition;
}
nodes.Add(node);
nodeByTalent[talent] = node;
}
if (lineRoot == null)
{
return;
}
for (int i = 0; i < manager.allTalents.Count; i++)
{
TalentData talent = manager.allTalents[i];
if (talent == null || talent.prerequisites == null)
{
continue;
}
for (int prerequisiteIndex = 0; prerequisiteIndex < talent.prerequisites.Length; prerequisiteIndex++)
{
TalentData prerequisite = talent.prerequisites[prerequisiteIndex];
if (prerequisite == null || !nodeByTalent.ContainsKey(prerequisite) || !nodeByTalent.ContainsKey(talent))
{
continue;
}
LineConnectorUI line = CreateLine(lineRoot, prerequisite, nodeByTalent[prerequisite], nodeByTalent[talent]);
lines.Add(line);
}
}
UpdateLines();
}
public void Refresh()
{
if (titleText != null)
{
titleText.text = "Дерево талантов";
}
if (pointsText != null)
{
int points = manager != null ? manager.GetAvailableTalentPoints() : 0;
pointsText.text = $"Очки талантов: {points}";
}
if (controlsText != null)
{
controlsText.text = "K - дерево X - +50 XP T - +1 очко E - кристалл F5 - сохранить F9 - загрузить Backspace - сброс";
}
for (int i = 0; i < nodes.Count; i++)
{
if (nodes[i] != null)
{
nodes[i].Refresh();
}
}
if (statsPanel != null)
{
statsPanel.Refresh();
}
UpdateLines();
}
private void BindButtons()
{
if (saveButton != null)
{
saveButton.onClick.RemoveAllListeners();
saveButton.onClick.AddListener(() =>
{
if (manager != null)
{
manager.SaveProgress();
}
});
}
if (loadButton != null)
{
loadButton.onClick.RemoveAllListeners();
loadButton.onClick.AddListener(() =>
{
if (manager != null)
{
manager.LoadProgress();
}
});
}
if (resetButton != null)
{
resetButton.onClick.RemoveAllListeners();
resetButton.onClick.AddListener(() =>
{
if (manager != null)
{
manager.ResetProgress();
}
});
}
}
private LineConnectorUI CreateLine(RectTransform parent, TalentData childTalent, TalentNodeUI startNode, TalentNodeUI endNode)
{
GameObject lineObject = new GameObject($"Line_{startNode.talent.talentId}_to_{childTalent.talentId}", typeof(RectTransform), typeof(Image), typeof(LineConnectorUI));
lineObject.transform.SetParent(parent, false);
Image image = lineObject.GetComponent<Image>();
Color color = childTalent.branchColor;
image.color = new Color(color.r, color.g, color.b, 0.72f);
image.raycastTarget = false;
LineConnectorUI connector = lineObject.GetComponent<LineConnectorUI>();
connector.lineImage = image;
connector.thickness = 5f;
connector.dynamicUpdate = true;
connector.SetEndpoints(startNode.transform as RectTransform, endNode.transform as RectTransform);
return connector;
}
private void UpdateLines()
{
Canvas.ForceUpdateCanvases();
for (int i = 0; i < lines.Count; i++)
{
if (lines[i] != null)
{
lines[i].UpdateLine();
}
}
}
private void ClearChildren(RectTransform root)
{
if (root == null)
{
return;
}
for (int i = root.childCount - 1; i >= 0; i--)
{
Destroy(root.GetChild(i).gameObject);
}
}
}