RouteEditor.cs 7.7 KB

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