189 lines
6.2 KiB
C#
189 lines
6.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
|
|
[CustomEditor(typeof(SkillTreeManager))]
|
|
public class SkillTreeManagerEditor : Editor
|
|
{
|
|
public override void OnInspectorGUI()
|
|
{
|
|
DrawDefaultInspector();
|
|
if (GUILayout.Button("Generate"))
|
|
{
|
|
(target as SkillTreeManager).Generate();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public class SkillTreeManager : MonoBehaviour
|
|
{
|
|
//[SerializeField]
|
|
//private
|
|
[SerializeField]
|
|
private float _lineColorVariation = 0.2f;
|
|
[SerializeField]
|
|
private float _lineOffset = 5f;
|
|
[SerializeField]
|
|
private float _lineThickness = 10f;
|
|
[SerializeField]
|
|
private Vector2 _startPositionOffset = new Vector2(200, 0);
|
|
[SerializeField]
|
|
Vector2 _distanceBetweenItems = Vector2.one * 200;
|
|
[SerializeField]
|
|
List<SkillTreeItem> _skillTreeItems;
|
|
[SerializeField]
|
|
GameObject _skillTreeItemPrefab;
|
|
[SerializeField]
|
|
GameObject _uiLineRendererPrefab;
|
|
[SerializeField]
|
|
GameObject _popUpConfigPrefab;
|
|
[SerializeField]
|
|
GameObject _skillTreeInfoItemPrefab;
|
|
|
|
[SerializeField]
|
|
Transform _nodeContainer;
|
|
[SerializeField]
|
|
Transform _lineContainer;
|
|
[Scene]
|
|
[SerializeField]
|
|
private string _skillTreeScene;
|
|
|
|
private List<SkillTreeItemDisplay> DrawColumn(List<SkillTreeItem> items, List<SkillTreeItemDisplay> created)
|
|
{
|
|
var testList = new List<SkillSO>();
|
|
var returnList = new List<SkillTreeItemDisplay>();
|
|
var ancestors = items.Max(current => GetAncestorCount(current));
|
|
for (int i = 0; i < items.Count; i++)
|
|
{
|
|
var item = items[i];
|
|
|
|
var comp = created.Find(x => x.Data == item);
|
|
if (comp)
|
|
{
|
|
returnList.Add(comp);
|
|
continue;
|
|
}
|
|
|
|
var x = _startPositionOffset.x + ancestors * _distanceBetweenItems.x;
|
|
var y = _startPositionOffset.y + _distanceBetweenItems.y * i - (items.Count / 2) * _distanceBetweenItems.y;
|
|
var pos = new Vector2(x, y);
|
|
|
|
|
|
var instance = Instantiate(_skillTreeItemPrefab, _nodeContainer.transform);
|
|
instance.GetComponent<RectTransform>().anchoredPosition = pos;
|
|
comp = instance.GetComponent<SkillTreeItemDisplay>();
|
|
comp.Data = item;
|
|
comp._popUpConf = _popUpConfigPrefab;
|
|
created.Add(comp);
|
|
returnList.Add(comp);
|
|
}
|
|
return returnList;
|
|
|
|
static int GetAncestorCount(SkillTreeItem item, int start = 0)
|
|
{
|
|
var max = start;
|
|
foreach (var ancestor in item.Prerequisites)
|
|
{
|
|
var count = GetAncestorCount(ancestor, start + 1);
|
|
if (count > max) max = count;
|
|
}
|
|
return max;
|
|
}
|
|
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
Generate();
|
|
SkillsManager.Instance._skillsList = _skillTreeItems;
|
|
}
|
|
|
|
public void LoadGameScene()
|
|
{
|
|
SceneManager.LoadScene(_skillTreeScene, LoadSceneMode.Single);
|
|
}
|
|
|
|
public void SkillResetBtn()
|
|
{
|
|
SkillsManager.Instance.ResetLists();
|
|
_skillTreeItems = SkillsManager.Instance.GetListOrigin();
|
|
foreach (SkillTreeItem i in _skillTreeItems)
|
|
{
|
|
PlayerPrefs.SetInt("Skill " + i.SkillID, 0);
|
|
if (PlayerPrefs.GetInt("Skill" + i.SkillID) == 0)
|
|
{
|
|
Debug.Log(PlayerPrefs.GetInt("Skill " + i.SkillID));
|
|
Debug.Log("Ce Skill à été reset!");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Generate()
|
|
{
|
|
foreach (Transform t in _nodeContainer) DestroyImmediate(t.gameObject);
|
|
foreach (Transform t in _lineContainer) DestroyImmediate(t.gameObject);
|
|
|
|
var dict = new Dictionary<int, HashSet<int>>();
|
|
var created = new List<SkillTreeItemDisplay>();
|
|
var choices = _skillTreeItems.FindAll(x => x.Prerequisites.Count <= 0);
|
|
|
|
DrawColumn(choices, created);
|
|
|
|
for (int i = 0; i < created.Count; i++)
|
|
{
|
|
var current = created[i];
|
|
|
|
choices = _skillTreeItems.FindAll(x => x.Prerequisites.Contains(current.Data));
|
|
if (choices.Count <= 0) continue;
|
|
|
|
var column = DrawColumn(choices, created);
|
|
}
|
|
|
|
foreach (var node in created)
|
|
{
|
|
dict.TryAdd(node.Data.GetHashCode(), new());
|
|
Vector2 colorVariation = new Vector2(Random.value - 0.5f, Random.value - 0.5f) * _lineColorVariation;
|
|
var rect1 = node.GetComponent<RectTransform>();
|
|
|
|
var prereqs = created.FindAll(x => x.Data.Prerequisites.Contains(node.Data));
|
|
|
|
for (int p = 0; p < prereqs.Count; p++)
|
|
{
|
|
var prereq = prereqs[p];
|
|
|
|
if (dict[node.Data.GetHashCode()].Contains(prereq.Data.GetHashCode())) continue;
|
|
dict[node.Data.GetHashCode()].Add(prereq.Data.GetHashCode());
|
|
|
|
var rect2 = prereq.GetComponent<RectTransform>();
|
|
var delta = rect2.anchoredPosition - rect1.anchoredPosition;
|
|
|
|
var lineObj = Instantiate(_uiLineRendererPrefab, _lineContainer);
|
|
var line = lineObj.GetComponent<UILineRenderer>();
|
|
|
|
node.RelatedLines.Add(line);
|
|
prereq.RelatedLines.Add(line);
|
|
|
|
line.points.Clear();
|
|
line.points.Add(rect1.anchoredPosition + (p * _lineOffset - prereqs.Count * _lineOffset / 2) * Vector2.one);
|
|
line.points.Add(rect1.anchoredPosition + (p * _lineOffset - prereqs.Count * _lineOffset / 2) * Vector2.one + Vector2.right * delta.x / 2);
|
|
line.points.Add(rect2.anchoredPosition + (p * _lineOffset - prereqs.Count * _lineOffset / 2) * Vector2.one + Vector2.left * delta.x / 2);
|
|
line.points.Add(rect2.anchoredPosition + (p * _lineOffset - prereqs.Count * _lineOffset / 2) * Vector2.one);
|
|
line.transform.SetAsFirstSibling();
|
|
|
|
Color.RGBToHSV(line.color, out float H, out float S, out float V);
|
|
line.thickness = _lineThickness;
|
|
line.color = Color.HSVToRGB(H, S + colorVariation.x, V + colorVariation.y);
|
|
}
|
|
}
|
|
}
|
|
}
|