SeekerEditor.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections.Generic;
  4. namespace Pathfinding {
  5. [CustomEditor(typeof(Seeker))]
  6. [CanEditMultipleObjects]
  7. public class SeekerEditor : EditorBase {
  8. static bool tagPenaltiesOpen;
  9. static List<Seeker> scripts = new List<Seeker>();
  10. GUIContent[] exactnessLabels = new [] { new GUIContent("Node Center (Snap To Node)"), new GUIContent("Original"), new GUIContent("Interpolate (deprecated)"), new GUIContent("Closest On Node Surface"), new GUIContent("Node Connection") };
  11. string[] graphLabels = new string[32];
  12. protected override void Inspector () {
  13. base.Inspector();
  14. scripts.Clear();
  15. foreach (var script in targets) scripts.Add(script as Seeker);
  16. Undo.RecordObjects(targets, "Modify settings on Seeker");
  17. var startEndModifierProp = FindProperty("startEndModifier");
  18. startEndModifierProp.isExpanded = EditorGUILayout.Foldout(startEndModifierProp.isExpanded, startEndModifierProp.displayName);
  19. if (startEndModifierProp.isExpanded) {
  20. EditorGUI.indentLevel++;
  21. Popup("startEndModifier.exactStartPoint", exactnessLabels, "Start Point Snapping");
  22. Popup("startEndModifier.exactEndPoint", exactnessLabels, "End Point Snapping");
  23. PropertyField("startEndModifier.addPoints", "Add Points");
  24. if (FindProperty("startEndModifier.exactStartPoint").enumValueIndex == (int)StartEndModifier.Exactness.Original || FindProperty("startEndModifier.exactEndPoint").enumValueIndex == (int)StartEndModifier.Exactness.Original) {
  25. if (PropertyField("startEndModifier.useRaycasting", "Physics Raycasting")) {
  26. EditorGUI.indentLevel++;
  27. PropertyField("startEndModifier.mask", "Layer Mask");
  28. EditorGUI.indentLevel--;
  29. EditorGUILayout.HelpBox("Using raycasting to snap the start/end points has largely been superseded by the 'ClosestOnNode' snapping option. It is both faster and usually closer to what you want to achieve.", MessageType.Info);
  30. }
  31. if (PropertyField("startEndModifier.useGraphRaycasting", "Graph Raycasting")) {
  32. EditorGUILayout.HelpBox("Using raycasting to snap the start/end points has largely been superseded by the 'ClosestOnNode' snapping option. It is both faster and usually closer to what you want to achieve.", MessageType.Info);
  33. }
  34. }
  35. EditorGUI.indentLevel--;
  36. }
  37. // Make sure the AstarPath object is initialized and the graphs are loaded, this is required to be able to show graph names in the mask popup
  38. AstarPath.FindAstarPath();
  39. for (int i = 0; i < graphLabels.Length; i++) {
  40. if (AstarPath.active == null || AstarPath.active.data.graphs == null || i >= AstarPath.active.data.graphs.Length || AstarPath.active.data.graphs[i] == null) graphLabels[i] = "Graph " + i + (i == 31 ? "+" : "");
  41. else {
  42. graphLabels[i] = AstarPath.active.data.graphs[i].name + " (graph " + i + ")";
  43. }
  44. }
  45. Mask("graphMask.value", graphLabels, "Traversable Graphs");
  46. tagPenaltiesOpen = EditorGUILayout.Foldout(tagPenaltiesOpen, new GUIContent("Tags", "Settings for each tag"));
  47. if (tagPenaltiesOpen) {
  48. string[] tagNames = AstarPath.FindTagNames();
  49. EditorGUI.indentLevel++;
  50. if (tagNames.Length != 32) {
  51. tagNames = new string[32];
  52. for (int i = 0; i < tagNames.Length; i++) tagNames[i] = "" + i;
  53. }
  54. EditorGUILayout.BeginHorizontal();
  55. EditorGUILayout.BeginVertical();
  56. EditorGUILayout.LabelField("Tag", EditorStyles.boldLabel, GUILayout.MaxWidth(120));
  57. for (int i = 0; i < tagNames.Length; i++) {
  58. EditorGUILayout.LabelField(tagNames[i], GUILayout.MaxWidth(120));
  59. }
  60. // Make sure the arrays are all of the correct size
  61. for (int i = 0; i < scripts.Count; i++) {
  62. if (scripts[i].tagPenalties == null || scripts[i].tagPenalties.Length != tagNames.Length) scripts[i].tagPenalties = new int[tagNames.Length];
  63. }
  64. if (GUILayout.Button("Edit names", EditorStyles.miniButton)) {
  65. AstarPathEditor.EditTags();
  66. }
  67. EditorGUILayout.EndVertical();
  68. #if !ASTAR_NoTagPenalty
  69. EditorGUILayout.BeginVertical();
  70. EditorGUILayout.LabelField("Penalty", EditorStyles.boldLabel, GUILayout.MaxWidth(100));
  71. var prop = FindProperty("tagPenalties").FindPropertyRelative("Array");
  72. prop.Next(true);
  73. for (int i = 0; i < tagNames.Length; i++) {
  74. prop.Next(false);
  75. EditorGUILayout.PropertyField(prop, GUIContent.none, false, GUILayout.MinWidth(100));
  76. // Penalties should not be negative
  77. if (prop.intValue < 0) prop.intValue = 0;
  78. }
  79. if (GUILayout.Button("Reset all", EditorStyles.miniButton)) {
  80. for (int i = 0; i < tagNames.Length; i++) {
  81. for (int j = 0; j < scripts.Count; j++) {
  82. scripts[j].tagPenalties[i] = 0;
  83. }
  84. }
  85. }
  86. EditorGUILayout.EndVertical();
  87. #endif
  88. EditorGUILayout.BeginVertical();
  89. EditorGUILayout.LabelField("Traversable", EditorStyles.boldLabel, GUILayout.MaxWidth(100));
  90. for (int i = 0; i < tagNames.Length; i++) {
  91. var anyFalse = false;
  92. var anyTrue = false;
  93. for (int j = 0; j < scripts.Count; j++) {
  94. var prevTraversable = ((scripts[j].traversableTags >> i) & 0x1) != 0;
  95. anyTrue |= prevTraversable;
  96. anyFalse |= !prevTraversable;
  97. }
  98. EditorGUI.BeginChangeCheck();
  99. EditorGUI.showMixedValue = anyTrue & anyFalse;
  100. var newTraversable = EditorGUILayout.Toggle(anyTrue);
  101. EditorGUI.showMixedValue = false;
  102. if (EditorGUI.EndChangeCheck()) {
  103. for (int j = 0; j < scripts.Count; j++) {
  104. scripts[j].traversableTags = (scripts[j].traversableTags & ~(1 << i)) | ((newTraversable ? 1 : 0) << i);
  105. }
  106. }
  107. }
  108. if (GUILayout.Button("Set all/none", EditorStyles.miniButton)) {
  109. for (int j = scripts.Count - 1; j >= 0; j--) {
  110. scripts[j].traversableTags = (scripts[0].traversableTags & 0x1) == 0 ? -1 : 0;
  111. }
  112. }
  113. EditorGUILayout.EndVertical();
  114. EditorGUILayout.EndHorizontal();
  115. }
  116. }
  117. }
  118. }