5Y5T3M/Assets/Scripts/GameManager.cs

245 lines
No EOL
7.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using static UnityEngine.GraphicsBuffer;
[ExecuteAlways]
public class GameManager : MonoBehaviour
{
public Transform ConnectionParent;
public GameObject ConnectionPrefab;
public Transform NodeParent;
public GameObject NodePrefab;
public Player players;
public int currentPlayer = -1;
public static GameManager Instance { get; private set; }
public bool regenerateOnChange = false;
[HideInInspector] public float minConnectionLength = 6;
[HideInInspector] public float maxConnectionLength = 6;
[HideInInspector] public int nodeCount = 100;
[HideInInspector] public int hoverRadiusCon = 50;
[HideInInspector] public int hoverRadiusNode = 50;
[HideInInspector] public int selectedLevel = -1;
[SerializeField] [HideInInspector] public List<LevelData> levels = new List<LevelData>();
[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 minConnectionLength = 0;
public float maxConnectionLength = 0;
public List<NodeData> nodes = new List<NodeData>();
public List<ConnectionData> connections = new List<ConnectionData>();
}
void Awake()
{
if (Instance != null && Instance != this)
{
if (Application.isPlaying)
Destroy(gameObject);
return;
}
Instance = this;
if (Application.isPlaying)
DontDestroyOnLoad(gameObject);
GetConnections().ForEach(obj => obj.DelConnect());
GetConnections().ForEach(obj => obj.SetConnect());
}
private void Update()
{
}
public List<Node> GetNodes() => NodeParent.GetComponentsInChildren<Node>().ToList();
public List<Connection> GetConnections() => ConnectionParent.GetComponentsInChildren<Connection>().ToList();
public void OnNodesDragged(Node nodeA, Node nodeB)
{
}
public void GenerateAlongSphere()
{
for (int i = NodeParent.childCount - 1; i >= 0; i--)
DestroyImmediate(NodeParent.GetChild(i).gameObject);
float radius = 20f;
float goldenRatio = (1f + Mathf.Sqrt(5f)) / 2f;
float angleIncrement = 2f * Mathf.PI * goldenRatio;
for (int i = 0; i < nodeCount; i++)
{
float t = (float)i / nodeCount; // von 0 bis 1
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;
var auto = PrefabUtility.InstantiatePrefab(NodePrefab, NodeParent) as GameObject;
auto.GetComponent<Node>().id = i;
auto.transform.localPosition = pos;
}
}
public void GenerateConnections()
{
for (int i = ConnectionParent.childCount - 1; i >= 0; i--)
DestroyImmediate(ConnectionParent.GetChild(i).gameObject);
var nodes = GetNodes();
foreach (Node nodeA in nodes)
{
if (nodeA == null) continue;
foreach (Node nodeB in nodes)
{
if (nodeB == null) continue;
bool conExists = false;
float dist = Vector3.Distance(nodeA.transform.position, nodeB.transform.position);
if (nodeA == nodeB || dist > maxConnectionLength)
continue;
foreach (Connection con in GetConnections())
{
if ((con.nodeA == nodeA && con.nodeB == nodeB) || (con.nodeA == nodeB && con.nodeB == nodeA))
{
conExists = true;
break;
}
}
if (!conExists)
{
AddConnection(nodeA, nodeB, dist < minConnectionLength);
}
}
}
}
public void AddConnection(Node nodeA, Node nodeB, bool allowed = true)
{
var newCon = PrefabUtility.InstantiatePrefab(ConnectionPrefab, ConnectionParent).GetComponent<Connection>();
newCon.nodeA = nodeA;
newCon.nodeB = nodeB;
newCon.allowed = allowed;
}
public void LoadLevelData(int index)
{
if(index >= levels.Count)
{
Debug.LogWarning("LevelIndex out of range");
return;
}
for (int i = NodeParent.childCount - 1; i >= 0; i--)
DestroyImmediate(NodeParent.GetChild(i).gameObject);
foreach (LineRenderer line in ConnectionParent.GetComponentsInChildren<LineRenderer>())
DestroyImmediate(line.gameObject);
for(int i = 0; i < levels[index].nodes.Count; i++)
{
var nodeData = levels[index].nodes[i];
var auto = PrefabUtility.InstantiatePrefab(NodePrefab, NodeParent) as GameObject;
auto.transform.localPosition = nodeData.position;
auto.GetComponent<Node>().Owner = nodeData.owner;
auto.GetComponent<Node>().id = i;
}
var currentNodes = GetNodes();
int idx = 0;
foreach (Node node in currentNodes)
node.id = idx++;
currentNodes = GetNodes();
foreach (LevelData.ConnectionData conData in levels[index].connections)
{
AddConnection(currentNodes[conData.nodeAIndex], currentNodes[conData.nodeBIndex], conData.allowed);
Debug.Log(conData.nodeAIndex + " - " + conData.nodeBIndex);
}
selectedLevel = index;
minConnectionLength = levels[index].minConnectionLength;
maxConnectionLength = levels[index].maxConnectionLength;
nodeCount = currentNodes.Count;
}
public void SaveLevelData(int index = -1)
{
LevelData data = new LevelData();
data.minConnectionLength = minConnectionLength;
data.maxConnectionLength = maxConnectionLength;
// Nodes speichern
foreach (var node in GetNodes())
{
data.nodes.Add(new LevelData.NodeData
{
position = node.transform.localPosition,
owner = node.Owner
});
}
// Connections speichern
foreach (var con in GetConnections())
{
if (con.nodeA.id >= 0 && con.nodeB.id >= 0)
{
data.connections.Add(new LevelData.ConnectionData
{
nodeAIndex = con.nodeA.id,
nodeBIndex = con.nodeB.id,
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;
}
}