5Y5T3M/Assets/Scripts/GameManager.cs

264 lines
8.3 KiB
C#
Raw Normal View History

2025-09-17 10:12:15 +02:00
using System;
2025-09-16 01:16:02 +02:00
using System.Collections.Generic;
2025-09-16 10:45:09 +02:00
using System.Dynamic;
2025-09-16 19:49:18 +02:00
using System.Linq;
2025-09-16 01:16:02 +02:00
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
2025-09-16 14:20:19 +02:00
using UnityEngine.UIElements;
2025-09-16 01:16:02 +02:00
using static UnityEngine.GraphicsBuffer;
[ExecuteAlways]
public class GameManager : MonoBehaviour
{
public Transform ConnectionParent;
2025-09-16 10:45:09 +02:00
public Transform NodeParent;
public GameObject NodePrefab;
2025-09-16 01:16:02 +02:00
public static GameManager Instance { get; private set; }
2025-09-16 01:16:02 +02:00
2025-09-16 19:49:18 +02:00
public bool regenerateOnChange = false;
[HideInInspector] public float maxConnectionLength = 6;
[HideInInspector] public int nodeCount = 100;
2025-09-16 17:40:34 +02:00
[HideInInspector] public int hoverRadiusCon = 50;
[HideInInspector] public int hoverRadiusNode = 50;
2025-09-17 10:12:15 +02:00
[HideInInspector] public int selectedLevel = -1;
2025-09-16 00:08:50 +02:00
2025-09-17 10:12:15 +02:00
[SerializeField] [HideInInspector] public List<Connection> connections = new List<Connection>();
[SerializeField] [HideInInspector] public List<Node> nodes = new List<Node>();
[SerializeField] [HideInInspector] public List<LevelData> levels = new List<LevelData>();
2025-09-16 10:45:09 +02:00
[Serializable]
public class Connection
2025-09-16 00:08:50 +02:00
{
2025-09-16 01:16:02 +02:00
public Node nodeA, nodeB;
public bool allowed = true;
public bool hovered = false;
2025-09-16 14:20:19 +02:00
public LineRenderer lineRenderer;
2025-09-16 01:16:02 +02:00
}
[Serializable]
public class LevelData
{
[Serializable]
public class NodeData
{
public Vector3 position;
public int owner;
}
[Serializable]
public class ConnectionData
{
public int nodeAIndex;
public int nodeBIndex;
public bool allowed = true;
}
public float maxConnectionLength = 0;
public List<NodeData> nodes = new List<NodeData>();
public List<ConnectionData> connections = new List<ConnectionData>();
}
void Awake()
2025-09-16 17:40:34 +02:00
{
if (Instance != null && Instance != this)
{
if (Application.isPlaying)
Destroy(gameObject);
return;
}
Instance = this;
if (Application.isPlaying)
DontDestroyOnLoad(gameObject);
}
2025-09-16 01:16:02 +02:00
public void GenerateAlongSphere()
2025-09-16 00:08:50 +02:00
{
connections.Clear();
nodes.Clear();
2025-09-16 01:16:02 +02:00
for (int i = NodeParent.childCount - 1; i >= 0; i--)
DestroyImmediate(NodeParent.GetChild(i).gameObject);
2025-09-16 00:08:50 +02:00
float radius = 20f;
float goldenRatio = (1f + Mathf.Sqrt(5f)) / 2f;
float angleIncrement = 2f * Mathf.PI * goldenRatio;
2025-09-16 01:16:02 +02:00
for (int i = 0; i < nodeCount; i++)
2025-09-16 00:08:50 +02:00
{
2025-09-16 01:16:02 +02:00
float t = (float)i / nodeCount; // von 0 bis 1
2025-09-16 00:08:50 +02:00
float inclination = Mathf.Acos(1f - 2f * t);
float azimuth = angleIncrement * i;
float x = Mathf.Sin(inclination) * Mathf.Cos(azimuth);
float y = Mathf.Sin(inclination) * Mathf.Sin(azimuth);
float z = Mathf.Cos(inclination);
Vector3 pos = new Vector3(x, y, z) * radius;
2025-09-16 14:20:19 +02:00
var auto = PrefabUtility.InstantiatePrefab(NodePrefab, NodeParent) as GameObject;
2025-09-16 00:08:50 +02:00
auto.transform.localPosition = pos;
nodes.Add(auto.GetComponent<Node>());
}
2025-09-16 01:16:02 +02:00
}
public void GenerateConnections()
2025-09-16 00:08:50 +02:00
{
connections.Clear();
foreach (LineRenderer line in ConnectionParent.GetComponentsInChildren<LineRenderer>())
DestroyImmediate(line.gameObject);
2025-09-16 01:16:02 +02:00
foreach (Node nodeA in nodes)
{
if (nodeA == null) continue;
foreach (Node nodeB in nodes)
{
if (nodeB == null) continue;
bool conExists = false;
if (nodeA == nodeB || Math.Abs(Vector3.Distance(nodeA.transform.position, nodeB.transform.position)) > maxConnectionLength)
continue;
foreach (Connection con in connections)
{
if ((con.nodeA == nodeA && con.nodeB == nodeB) || (con.nodeA == nodeB && con.nodeB == nodeA))
{
conExists = true;
break;
}
}
if (!conExists)
2025-09-16 14:20:19 +02:00
{
AddConnection(nodeA, nodeB);
2025-09-16 14:20:19 +02:00
}
2025-09-16 01:16:02 +02:00
}
2025-09-16 14:20:19 +02:00
2025-09-16 00:08:50 +02:00
}
2025-09-16 01:16:02 +02:00
}
2025-09-16 13:04:05 +02:00
2025-09-16 14:20:19 +02:00
private void Update()
{
foreach (var con in connections)
{
2025-09-16 17:40:34 +02:00
if(Application.isPlaying && !con.allowed)
{
con.lineRenderer.enabled = false;
continue;
}
float width = (con.hovered ? 0.6f : 0.3f) * (con.allowed ? 1f : 0.3f);
con.lineRenderer.startColor = con.allowed ? con.nodeA.transform.GetChild(0).GetComponent<Renderer>().sharedMaterial.color : new Color(0.2f, 0.2f, 0.2f);
con.lineRenderer.endColor = con.allowed ? con.nodeB.transform.GetChild(0).GetComponent<Renderer>().sharedMaterial.color : new Color(0.2f, 0.2f, 0.2f);
con.lineRenderer.startWidth = width;
con.lineRenderer.endWidth = width;
2025-09-16 14:20:19 +02:00
con.lineRenderer.SetGreatCircleArc(con.nodeA.transform.position, con.nodeB.transform.position, 5, 20.5f);
con.lineRenderer.enabled = true;
}
}
2025-09-17 10:12:15 +02:00
public void AddConnection(Node nodeA, Node nodeB, bool allowed = true)
{
var dummy = new GameObject("dummy");
dummy.transform.SetParent(ConnectionParent);
var newCon = new Connection
{
nodeA = nodeA,
nodeB = nodeB,
allowed = allowed,
lineRenderer = dummy.AddComponent<LineRenderer>()
};
newCon.lineRenderer.enabled = false;
newCon.lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
newCon.lineRenderer.positionCount = 3;
connections.Add(newCon);
}
2025-09-17 10:12:15 +02:00
public void LoadLevelData(int index)
{
if(index >= levels.Count)
{
Debug.LogWarning("LevelIndex out of range");
return;
}
connections.Clear();
nodes.Clear();
for (int i = NodeParent.childCount - 1; i >= 0; i--)
DestroyImmediate(NodeParent.GetChild(i).gameObject);
foreach (LineRenderer line in ConnectionParent.GetComponentsInChildren<LineRenderer>())
DestroyImmediate(line.gameObject);
foreach(LevelData.NodeData nodeData in levels[index].nodes)
{
var auto = PrefabUtility.InstantiatePrefab(NodePrefab, NodeParent) as GameObject;
auto.transform.localPosition = nodeData.position;
nodes.Add(auto.GetComponent<Node>());
auto.GetComponent<Node>().Owner = nodeData.owner;
}
foreach (LevelData.ConnectionData conData in levels[index].connections)
{
AddConnection(nodes[conData.nodeAIndex], nodes[conData.nodeBIndex]);
2025-09-17 10:12:15 +02:00
}
selectedLevel = index;
maxConnectionLength = levels[index].maxConnectionLength;
nodeCount = nodes.Count;
Debug.Log("Loaded Level " + index);
}
public void SaveLevelData(int index = -1)
{
LevelData data = new LevelData();
data.maxConnectionLength = maxConnectionLength;
// Nodes speichern
foreach (var node in nodes)
{
data.nodes.Add(new LevelData.NodeData
{
position = node.transform.localPosition,
owner = node.Owner
});
}
// Connections speichern
foreach (var con in connections)
{
int idxA = nodes.IndexOf(con.nodeA);
int idxB = nodes.IndexOf(con.nodeB);
if (idxA >= 0 && idxB >= 0)
{
data.connections.Add(new LevelData.ConnectionData
{
nodeAIndex = idxA,
nodeBIndex = idxB,
allowed = con.allowed
});
}
}
if (index == -1 || index >= levels.Count)
levels.Add(data);
else
levels[index] = data;
int newIndex = index < 0 ? levels.Count - 1 : index;
selectedLevel = newIndex;
Debug.Log("Saved Level " + newIndex);
}
2025-09-16 14:20:19 +02:00
}