|
@@ -0,0 +1,234 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using ICSharpCode.NRefactory.PrettyPrinter;
|
|
|
+using Roads;
|
|
|
+using Routes;
|
|
|
+using UnityEditor;
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.Rendering;
|
|
|
+using UnityEngine.Rendering.UI;
|
|
|
+
|
|
|
+
|
|
|
+[CustomEditor(typeof(Route))]
|
|
|
+[CanEditMultipleObjects]
|
|
|
+// ReSharper disable once CheckNamespace
|
|
|
+public class RoutesEditor : Editor
|
|
|
+{
|
|
|
+ private bool showListContent;
|
|
|
+ private bool inSelectionMode;
|
|
|
+ private SceneView sceneView;
|
|
|
+ private readonly List<Turn> selectedTurns = new List<Turn>();
|
|
|
+
|
|
|
+ private static readonly Dictionary<RoadDirection, int> roadDirectionIndexes = new Dictionary<RoadDirection, int>
|
|
|
+ {
|
|
|
+ {RoadDirection.West, 0},
|
|
|
+ {RoadDirection.North, 1},
|
|
|
+ {RoadDirection.East, 2},
|
|
|
+ {RoadDirection.South, 3},
|
|
|
+ {RoadDirection.None, 4}
|
|
|
+ };
|
|
|
+
|
|
|
+ public override void OnInspectorGUI()
|
|
|
+ {
|
|
|
+ serializedObject.Update();
|
|
|
+ RoutesList(serializedObject.FindProperty("items"));
|
|
|
+ //EditorGUILayout.PropertyField(routes.FindPropertyRelative("arraySize"), true);true);
|
|
|
+ serializedObject.ApplyModifiedProperties();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnSceneGUI()
|
|
|
+ {
|
|
|
+ if (inSelectionMode)
|
|
|
+ {
|
|
|
+ if (Event.current.type == EventType.Layout)
|
|
|
+ {
|
|
|
+ HandleUtility.AddDefaultControl(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ sceneView = SceneView.currentDrawingSceneView;
|
|
|
+ if (sceneView == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("RouteEditor: No Scene View found");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sceneView != null && Event.current.type == EventType.MouseDown && Event.current.button == 0)
|
|
|
+ {
|
|
|
+ /*var coords = Event.current.mousePosition;
|
|
|
+ var pos = sceneView.camera.ScreenToWorldPoint(new Vector3(coords.x, coords.y, sceneView.camera.nearClipPlane));
|
|
|
+ Debug.Log("pos: "+pos);
|
|
|
+ Debug.DrawRay(pos, Vector3.down * 1000, Color.magenta);*/
|
|
|
+ Ray worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
|
|
|
+ RaycastHit hitInfo;
|
|
|
+
|
|
|
+ if (Physics.Raycast(worldRay, out hitInfo))
|
|
|
+ {
|
|
|
+ var intersection = GetIntersection(hitInfo.collider.gameObject);
|
|
|
+ selectedTurns.Add(intersection);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (GUI.changed)
|
|
|
+ EditorUtility.SetDirty(target);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Turn GetIntersection(GameObject gameObject)
|
|
|
+ {
|
|
|
+ Turn turn = null;
|
|
|
+ for (var i = 0; i < 3; i++)
|
|
|
+ {
|
|
|
+ turn = gameObject.GetComponent<Turn>();
|
|
|
+ if (turn != null || gameObject.transform.parent == null) break;
|
|
|
+ gameObject = gameObject.transform.parent.gameObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log($"Intersected Turn: {turn}");
|
|
|
+ return turn;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void RoutesList(SerializedProperty list)
|
|
|
+ {
|
|
|
+ showListContent =
|
|
|
+ EditorGUILayout.BeginFoldoutHeaderGroup(showListContent, $"{list.displayName} (Length = {list.arraySize})");
|
|
|
+
|
|
|
+ if (showListContent)
|
|
|
+ {
|
|
|
+ EditorGUI.indentLevel += 1;
|
|
|
+ EditorGUILayout.BeginHorizontal();
|
|
|
+ EditorGUILayout.PropertyField(list.FindPropertyRelative("Array.size"));
|
|
|
+ if (GUILayout.Button("+", EditorStyles.miniButton, GUILayout.Width(32)))
|
|
|
+ {
|
|
|
+ list.InsertArrayElementAtIndex(list.arraySize);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (GUILayout.Button(!inSelectionMode ? "Selection Mode" : "Quit Selection Mode", GUILayout.Width(128)))
|
|
|
+ {
|
|
|
+ SwitchSelectionMode();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (GUILayout.Button("Clear", GUILayout.Width(56)))
|
|
|
+ {
|
|
|
+ Clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ GUILayout.FlexibleSpace();
|
|
|
+ EditorGUILayout.EndHorizontal();
|
|
|
+ for (var i = 0; i < list.arraySize; i++)
|
|
|
+ {
|
|
|
+ EditorGUILayout.BeginHorizontal();
|
|
|
+ EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), true);
|
|
|
+ if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.Width(32)))
|
|
|
+ {
|
|
|
+ list.DeleteArrayElementAtIndex(i);
|
|
|
+ }
|
|
|
+
|
|
|
+ EditorGUILayout.EndHorizontal();
|
|
|
+ }
|
|
|
+
|
|
|
+ EditorGUI.indentLevel -= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ EditorGUILayout.EndFoldoutHeaderGroup();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Clear()
|
|
|
+ {
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SwitchSelectionMode()
|
|
|
+ {
|
|
|
+ inSelectionMode = !inSelectionMode;
|
|
|
+ if (inSelectionMode)
|
|
|
+ {
|
|
|
+ selectedTurns.Clear();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ApplySelectedTurns();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ApplySelectedTurns()
|
|
|
+ {
|
|
|
+ var items = serializedObject.FindProperty("items");
|
|
|
+ var size = items.arraySize;
|
|
|
+ SerializedProperty previousItem = null;
|
|
|
+
|
|
|
+ for (var index = 0; index < selectedTurns.Count; index++)
|
|
|
+ {
|
|
|
+ var serializedIndex = size + index;
|
|
|
+ var turn = selectedTurns[index];
|
|
|
+ var previousTurn = index == 0 ? null : selectedTurns[index - 1];
|
|
|
+ items.InsertArrayElementAtIndex(serializedIndex);
|
|
|
+
|
|
|
+ var newItem = items.GetArrayElementAtIndex(serializedIndex);
|
|
|
+ newItem.FindPropertyRelative("turn").objectReferenceValue = turn;
|
|
|
+ Debug.Log($"---- Element {serializedIndex} ----");
|
|
|
+ Debug.Log("Calculate From");
|
|
|
+ newItem.FindPropertyRelative("from").enumValueIndex = CalculateDirection(turn.transform,
|
|
|
+ previousTurn != null ? previousTurn.transform : null);
|
|
|
+ newItem.FindPropertyRelative("to").enumValueIndex = roadDirectionIndexes[RoadDirection.None];
|
|
|
+
|
|
|
+ if (previousItem != null)
|
|
|
+ {
|
|
|
+ Debug.Log("Calculate Previous To");
|
|
|
+ previousItem.FindPropertyRelative("to").enumValueIndex =
|
|
|
+ CalculateDirection(previousTurn != null ? previousTurn.transform : null, turn.transform);
|
|
|
+ }
|
|
|
+
|
|
|
+ previousItem = newItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ selectedTurns.Clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ private int CalculateDirection(Transform turnTransform, Transform reference)
|
|
|
+ {
|
|
|
+ if (reference == null) return roadDirectionIndexes[RoadDirection.None];
|
|
|
+ var dif = reference.position - turnTransform.position;
|
|
|
+ Debug.Log("Difference to reference = " + dif);
|
|
|
+
|
|
|
+ RoadDirection direction;
|
|
|
+ if (Mathf.Abs(dif.x) > Mathf.Abs(dif.z))
|
|
|
+ {
|
|
|
+ direction = dif.x < 0 ? RoadDirection.West : RoadDirection.East;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ direction = dif.z < 0 ? RoadDirection.South : RoadDirection.North;
|
|
|
+ }
|
|
|
+
|
|
|
+ return roadDirectionIndexes[direction];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [DrawGizmo(GizmoType.Selected)]
|
|
|
+ private static void DrawRoutePreview(Route route, GizmoType gizmoType)
|
|
|
+ {
|
|
|
+ if (route.items == null) return;
|
|
|
+ Gizmos.color = Color.red;
|
|
|
+ Turn previousTurn = null;
|
|
|
+ foreach (var item in route.items)
|
|
|
+ {
|
|
|
+ var turn = item.turn;
|
|
|
+
|
|
|
+ if (previousTurn != null)
|
|
|
+ {
|
|
|
+ //Gizmos.DrawCube(previousTurn.transform.position + turn.transform.position /2f, turn.transform.position - previousTurn.transform.position + Vector3.one * 0.1f);
|
|
|
+ //Gizmos.DrawLine(previousTurn.transform.position, turn.transform.position);
|
|
|
+ //var p1 = previousTurn.transform.position;
|
|
|
+ //var p2 = turn.transform.position;
|
|
|
+ //var thickness = 3;
|
|
|
+ //Handles.DrawBezier(p1,p2,p1,p2, Color.red,null,thickness);
|
|
|
+ Helpers.DrawLine(previousTurn.transform.position, turn.transform.position, 3);
|
|
|
+ }
|
|
|
+
|
|
|
+ previousTurn = turn;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|