RouteEditor.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using ICSharpCode.NRefactory.PrettyPrinter;
  6. using Roads;
  7. using Routes;
  8. using UnityEditor;
  9. using UnityEngine;
  10. using UnityEngine.Rendering;
  11. using UnityEngine.Rendering.UI;
  12. [CustomEditor(typeof(Route))]
  13. [CanEditMultipleObjects]
  14. // ReSharper disable once CheckNamespace
  15. public class RoutesEditor : Editor
  16. {
  17. private bool showListContent;
  18. private bool inSelectionMode;
  19. private SceneView sceneView;
  20. private readonly List<Turn> selectedTurns = new List<Turn>();
  21. private static readonly Dictionary<RoadDirection, int> roadDirectionIndexes = new Dictionary<RoadDirection, int>
  22. {
  23. {RoadDirection.West, 0},
  24. {RoadDirection.North, 1},
  25. {RoadDirection.East, 2},
  26. {RoadDirection.South, 3},
  27. {RoadDirection.None, 4}
  28. };
  29. public override void OnInspectorGUI()
  30. {
  31. serializedObject.Update();
  32. EditorGUILayout.PropertyField(serializedObject.FindProperty("start"));
  33. EditorGUILayout.PropertyField(serializedObject.FindProperty("finish"));
  34. RoutesList(serializedObject.FindProperty("items"));
  35. //EditorGUILayout.PropertyField(routes.FindPropertyRelative("arraySize"), true);true);
  36. serializedObject.ApplyModifiedProperties();
  37. }
  38. private void OnSceneGUI()
  39. {
  40. if (inSelectionMode)
  41. {
  42. if (Event.current.type == EventType.Layout)
  43. {
  44. HandleUtility.AddDefaultControl(0);
  45. }
  46. sceneView = SceneView.currentDrawingSceneView;
  47. if (sceneView == null)
  48. {
  49. Debug.LogError("RouteEditor: No Scene View found");
  50. }
  51. if (sceneView != null && Event.current.type == EventType.MouseDown && Event.current.button == 0)
  52. {
  53. /*var coords = Event.current.mousePosition;
  54. var pos = sceneView.camera.ScreenToWorldPoint(new Vector3(coords.x, coords.y, sceneView.camera.nearClipPlane));
  55. Debug.Log("pos: "+pos);
  56. Debug.DrawRay(pos, Vector3.down * 1000, Color.magenta);*/
  57. Ray worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
  58. RaycastHit hitInfo;
  59. if (Physics.Raycast(worldRay, out hitInfo))
  60. {
  61. var intersection = GetIntersection(hitInfo.collider.gameObject);
  62. selectedTurns.Add(intersection);
  63. }
  64. }
  65. }
  66. if (GUI.changed)
  67. EditorUtility.SetDirty(target);
  68. }
  69. private Turn GetIntersection(GameObject gameObject)
  70. {
  71. Turn turn = null;
  72. for (var i = 0; i < 3; i++)
  73. {
  74. turn = gameObject.GetComponent<Turn>();
  75. if (turn != null || gameObject.transform.parent == null) break;
  76. gameObject = gameObject.transform.parent.gameObject;
  77. }
  78. Debug.Log($"Intersected Turn: {turn}");
  79. return turn;
  80. }
  81. private void RoutesList(SerializedProperty list)
  82. {
  83. showListContent =
  84. EditorGUILayout.BeginFoldoutHeaderGroup(showListContent, $"{list.displayName} (Length = {list.arraySize})");
  85. if (showListContent)
  86. {
  87. EditorGUI.indentLevel += 1;
  88. EditorGUILayout.BeginHorizontal();
  89. EditorGUILayout.PropertyField(list.FindPropertyRelative("Array.size"));
  90. if (GUILayout.Button("+", EditorStyles.miniButton, GUILayout.Width(32)))
  91. {
  92. list.InsertArrayElementAtIndex(list.arraySize);
  93. }
  94. if (GUILayout.Button(!inSelectionMode ? "Selection Mode" : "Quit Selection Mode", GUILayout.Width(128)))
  95. {
  96. SwitchSelectionMode();
  97. }
  98. if (GUILayout.Button("Clear", GUILayout.Width(56)))
  99. {
  100. Clear();
  101. }
  102. GUILayout.FlexibleSpace();
  103. EditorGUILayout.EndHorizontal();
  104. for (var i = 0; i < list.arraySize; i++)
  105. {
  106. EditorGUILayout.BeginHorizontal();
  107. EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), true);
  108. if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.Width(32)))
  109. {
  110. list.DeleteArrayElementAtIndex(i);
  111. }
  112. EditorGUILayout.EndHorizontal();
  113. }
  114. EditorGUI.indentLevel -= 1;
  115. }
  116. EditorGUILayout.EndFoldoutHeaderGroup();
  117. }
  118. private void Clear()
  119. {
  120. throw new NotImplementedException();
  121. }
  122. private void SwitchSelectionMode()
  123. {
  124. inSelectionMode = !inSelectionMode;
  125. if (inSelectionMode)
  126. {
  127. selectedTurns.Clear();
  128. }
  129. else
  130. {
  131. ApplySelectedTurns();
  132. }
  133. }
  134. private void ApplySelectedTurns()
  135. {
  136. var items = serializedObject.FindProperty("items");
  137. var size = items.arraySize;
  138. SerializedProperty previousItem = null;
  139. for (var index = 0; index < selectedTurns.Count; index++)
  140. {
  141. var serializedIndex = size + index;
  142. var turn = selectedTurns[index];
  143. var previousTurn = index == 0 ? null : selectedTurns[index - 1];
  144. items.InsertArrayElementAtIndex(serializedIndex);
  145. var newItem = items.GetArrayElementAtIndex(serializedIndex);
  146. newItem.FindPropertyRelative("turn").objectReferenceValue = turn;
  147. Debug.Log($"---- Element {serializedIndex} ----");
  148. Debug.Log("Calculate From");
  149. newItem.FindPropertyRelative("from").enumValueIndex = CalculateDirection(turn.transform,
  150. previousTurn != null ? previousTurn.transform : null);
  151. newItem.FindPropertyRelative("to").enumValueIndex = roadDirectionIndexes[RoadDirection.None];
  152. if (previousItem != null)
  153. {
  154. Debug.Log("Calculate Previous To");
  155. previousItem.FindPropertyRelative("to").enumValueIndex =
  156. CalculateDirection(previousTurn != null ? previousTurn.transform : null, turn.transform);
  157. }
  158. previousItem = newItem;
  159. }
  160. selectedTurns.Clear();
  161. }
  162. private int CalculateDirection(Transform turnTransform, Transform reference)
  163. {
  164. if (reference == null) return roadDirectionIndexes[RoadDirection.None];
  165. var dif = reference.position - turnTransform.position;
  166. Debug.Log("Difference to reference = " + dif);
  167. RoadDirection direction;
  168. if (Mathf.Abs(dif.x) > Mathf.Abs(dif.z))
  169. {
  170. direction = dif.x < 0 ? RoadDirection.West : RoadDirection.East;
  171. }
  172. else
  173. {
  174. direction = dif.z < 0 ? RoadDirection.South : RoadDirection.North;
  175. }
  176. return roadDirectionIndexes[direction];
  177. }
  178. [DrawGizmo(GizmoType.Selected)]
  179. private static void DrawRoutePreview(Route route, GizmoType gizmoType)
  180. {
  181. if (route.items == null) return;
  182. Gizmos.color = Color.red;
  183. Turn previousTurn = null;
  184. foreach (var item in route.items)
  185. {
  186. var turn = item.turn;
  187. if (previousTurn != null)
  188. {
  189. //Gizmos.DrawCube(previousTurn.transform.position + turn.transform.position /2f, turn.transform.position - previousTurn.transform.position + Vector3.one * 0.1f);
  190. //Gizmos.DrawLine(previousTurn.transform.position, turn.transform.position);
  191. //var p1 = previousTurn.transform.position;
  192. //var p2 = turn.transform.position;
  193. //var thickness = 3;
  194. //Handles.DrawBezier(p1,p2,p1,p2, Color.red,null,thickness);
  195. Helpers.DrawLine(previousTurn.transform.position, turn.transform.position, 3);
  196. }
  197. previousTurn = turn;
  198. }
  199. }
  200. }