using UnityEditor; using UnityEngine; using System.Linq; using NUnit.Framework.Internal.Commands; [InitializeOnLoad] public static class EditorCustom { static EditorCustom() { SceneView.duringSceneGui += OnSceneGUI; } private static void OnSceneGUI(SceneView sceneView) { Event e = Event.current; if (e.type == EventType.MouseDown && e.button == 1) { // Nodes prüfen GameManager gm = GameObject.FindFirstObjectByType(); if (!gm) return; Node[] selectedNodes = Selection.gameObjects .Select(g => g.GetComponent()) .Where(n => n != null) .ToArray(); GenericMenu menu = new GenericMenu(); if (selectedNodes.Length == 2) { menu.AddItem(new GUIContent("Connect Selected Nodes"), false, () => { Connection con = gm.GetConnections().Find(con => (con.nodeA == selectedNodes[0] && con.nodeB == selectedNodes[1]) || (con.nodeA == selectedNodes[1] && con.nodeB == selectedNodes[0])); if (con != null) con.allowed = true; else gm.AddConnection(selectedNodes[0], selectedNodes[1]); }); menu.ShowAsContext(); e.Use(); // verhindert, dass Unity sein eigenes Menü anzeigt } } } [CustomEditor(typeof(GameManager))] public class GameManagerEditor : Editor { int clickedConIdx = -1; // Custom Inspector public override void OnInspectorGUI() { DrawDefaultInspector(); GameManager gm = (GameManager)target; if (GUILayout.Button("Execute Turn") && gm.actions.Count > 0) { gm.ExecuteTurn(); } GUILayout.Label("Generation Parameters", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); gm.nodeCount = EditorGUILayout.IntSlider("Node Count", gm.nodeCount, 0, 200); if (EditorGUI.EndChangeCheck() && gm.regenerateOnChange) { gm.GenerateAlongSphere(); gm.GenerateConnections(); SceneView.RepaintAll(); } EditorGUI.BeginChangeCheck(); gm.minConnectionLength = EditorGUILayout.Slider("Min Connection Length", gm.minConnectionLength, 0, gm.maxConnectionLength); gm.maxConnectionLength = EditorGUILayout.Slider("Max Connection Length", gm.maxConnectionLength, gm.minConnectionLength, 30); if (EditorGUI.EndChangeCheck() && gm.regenerateOnChange) { gm.GenerateConnections(); SceneView.RepaintAll(); } GUILayout.Space(10); GUILayout.Label("Connection Gizmos", EditorStyles.boldLabel); gm.hoverRadiusCon = EditorGUILayout.IntSlider("Hover Radius (Connection)", gm.hoverRadiusCon, 0, 100); gm.hoverRadiusNode = EditorGUILayout.IntSlider("Hover Radius (Node)", gm.hoverRadiusNode, 0, 100); GUILayout.BeginHorizontal(); if (GUILayout.Button("Distribute Nodes")) { gm.GenerateAlongSphere(); SceneView.RepaintAll(); } if (GUILayout.Button("Generate Connections")) { gm.GenerateConnections(); SceneView.RepaintAll(); } if (GUILayout.Button("Generate Both")) { gm.GenerateAlongSphere(); gm.GenerateConnections(); SceneView.RepaintAll(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); for (int i = 0; i < gm.levels.Count; i++) { if (gm.selectedLevel == i) GUILayout.Label("▷ Level " + i, EditorStyles.boldLabel); else GUILayout.Label(" Level " + i); } GUILayout.EndVertical(); GUILayout.BeginVertical(); for (int i = 0; i < gm.levels.Count; i++) { if (GUILayout.Button("Load")) gm.LoadLevelData(i); } GUILayout.EndVertical(); GUILayout.BeginVertical(); for (int i = 0; i < gm.levels.Count; i++) { GUILayout.BeginHorizontal(); if (gm.selectedLevel == i) if (GUILayout.Button("Save")) gm.SaveLevelData(i); if (GUILayout.Button("Delete")) { gm.levels.Remove(gm.levels[i]); if (gm.selectedLevel == i) gm.selectedLevel = -1; if (gm.selectedLevel > i) gm.selectedLevel--; if (gm.levels.Count <= 0) gm.selectedLevel = -1; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); if (GUILayout.Button("Save as new")) gm.SaveLevelData(); } // Custom Scene Interaction while GameManager selected private void OnSceneGUI() { if (Application.isPlaying) return; Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual; GameManager gm = FindFirstObjectByType(); if (gm == null) return; var nodes = gm.GetNodes(); var connections = gm.GetConnections(); GameObject selected = Selection.activeGameObject; bool allowHover = false; if (selected == gm.gameObject) allowHover = true; else { Node node = selected?.GetComponent(); if (node != null && nodes.Contains(node)) allowHover = true; } if (!allowHover) return; if (connections == null || connections.Count == 0) return; Camera cam = SceneView.lastActiveSceneView.camera; if (cam == null) return; Vector2 mouse = Event.current.mousePosition; mouse.y = cam.pixelHeight - mouse.y; Vector3 mousePos = new Vector3(mouse.x, mouse.y, 0); int closestIdx = -1; float closestDist = float.MaxValue; bool cancelHover = false; // Hover-Ermittlung Connections for (int i = 0; i < connections.Count; i++) { connections[i].hovered = false; if (cancelHover) continue; var con = connections[i]; Vector3 a = cam.WorldToScreenPoint(con.nodeA.transform.position); Vector3 b = cam.WorldToScreenPoint(con.nodeB.transform.position); Vector3 ab = b - a; Vector3 am = mousePos - a; float t = Mathf.Clamp01(Vector3.Dot(am, ab) / ab.sqrMagnitude); Vector3 proj = a + t * ab; float dist = Vector3.Distance(mousePos, proj); if (Vector3.Distance(a, mousePos) <= gm.hoverRadiusNode || Vector3.Distance(b, mousePos) <= gm.hoverRadiusNode) cancelHover = true; if (dist < closestDist && dist < gm.hoverRadiusCon) { closestDist = dist; closestIdx = i; } } if (closestIdx < 0) cancelHover = true; if (!cancelHover) connections[closestIdx].hovered = true; // Klick-Behandlung Event e = Event.current; if (e.type == EventType.MouseDown && e.button == 0 && !cancelHover) { clickedConIdx = closestIdx; } if (e.type == EventType.MouseUp && e.button == 0) { if (closestIdx == clickedConIdx && !cancelHover) { connections[closestIdx].allowed = !connections[closestIdx].allowed; e.Use(); // Event als verarbeitet markieren } clickedConIdx = -1; } // SceneView kontinuierlich aktualisieren SceneView.RepaintAll(); } } }