UnityNavMesh2DAdapterInspector.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #if UNITY_NAVIGATION_COMPONENTS
  2. //#define NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF
  3. using DunGen.Adapters;
  4. using Unity.AI.Navigation.Editor;
  5. using UnityEditor;
  6. using UnityEditor.AI;
  7. using UnityEngine;
  8. using UnityEngine.AI;
  9. namespace Dungen.Adapters
  10. {
  11. [CanEditMultipleObjects]
  12. [CustomEditor(typeof(UnityNavMesh2DAdapter))]
  13. public sealed class UnityNavMesh2DAdapterInspector : Editor
  14. {
  15. private SerializedProperty agentTypeID;
  16. private SerializedProperty defaultArea;
  17. private SerializedProperty layerMask;
  18. private SerializedProperty overrideTileSize;
  19. private SerializedProperty overrideVoxelSize;
  20. private SerializedProperty tileSize;
  21. private SerializedProperty voxelSize;
  22. private SerializedProperty unwalkableArea;
  23. #if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF
  24. SerializedProperty m_NavMeshData;
  25. #endif
  26. private class Styles
  27. {
  28. public readonly GUIContent LayerMask = new GUIContent("Include Layers");
  29. public readonly GUIContent SpriteCollectGeometry = new GUIContent("Sprite Geometry", "Which type of geometry to collect for sprites");
  30. }
  31. static Styles styles;
  32. private void OnEnable()
  33. {
  34. agentTypeID = serializedObject.FindProperty("agentTypeID");
  35. defaultArea = serializedObject.FindProperty("defaultArea");
  36. layerMask = serializedObject.FindProperty("layerMask");
  37. overrideTileSize = serializedObject.FindProperty("overrideTileSize");
  38. overrideVoxelSize = serializedObject.FindProperty("overrideVoxelSize");
  39. tileSize = serializedObject.FindProperty("tileSize");
  40. voxelSize = serializedObject.FindProperty("voxelSize");
  41. unwalkableArea = serializedObject.FindProperty("unwalkableArea");
  42. #if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF
  43. m_NavMeshData = serializedObject.FindProperty("navMeshData");
  44. #endif
  45. }
  46. public override void OnInspectorGUI()
  47. {
  48. if (styles == null)
  49. styles = new Styles();
  50. serializedObject.Update();
  51. var buildSettings = NavMesh.GetSettingsByID(agentTypeID.intValue);
  52. if (buildSettings.agentTypeID != -1)
  53. {
  54. // Draw image
  55. const float diagramHeight = 80.0f;
  56. Rect agentDiagramRect = EditorGUILayout.GetControlRect(false, diagramHeight);
  57. NavMeshEditorHelpers.DrawAgentDiagram(agentDiagramRect, buildSettings.agentRadius, buildSettings.agentHeight, buildSettings.agentClimb, buildSettings.agentSlope);
  58. }
  59. NavMeshComponentsGUIUtility.AgentTypePopup("Agent Type", agentTypeID);
  60. EditorGUILayout.Space();
  61. EditorGUILayout.PropertyField(layerMask, styles.LayerMask);
  62. EditorGUILayout.Space();
  63. overrideVoxelSize.isExpanded = EditorGUILayout.Foldout(overrideVoxelSize.isExpanded, "Advanced");
  64. if (overrideVoxelSize.isExpanded)
  65. {
  66. EditorGUI.indentLevel++;
  67. NavMeshComponentsGUIUtility.AreaPopup("Default Area", defaultArea);
  68. NavMeshComponentsGUIUtility.AreaPopup("Unwalkable Area", unwalkableArea);
  69. // Override voxel size.
  70. EditorGUILayout.PropertyField(overrideVoxelSize);
  71. using (new EditorGUI.DisabledScope(!overrideVoxelSize.boolValue || overrideVoxelSize.hasMultipleDifferentValues))
  72. {
  73. EditorGUI.indentLevel++;
  74. EditorGUILayout.PropertyField(voxelSize);
  75. if (!overrideVoxelSize.hasMultipleDifferentValues)
  76. {
  77. if (!agentTypeID.hasMultipleDifferentValues)
  78. {
  79. float voxelsPerRadius = voxelSize.floatValue > 0.0f ? (buildSettings.agentRadius / voxelSize.floatValue) : 0.0f;
  80. EditorGUILayout.LabelField(" ", voxelsPerRadius.ToString("0.00") + " voxels per agent radius", EditorStyles.miniLabel);
  81. }
  82. if (overrideVoxelSize.boolValue)
  83. EditorGUILayout.HelpBox("Voxel size controls how accurately the navigation mesh is generated from the level geometry. A good voxel size is 2-4 voxels per agent radius. Making voxel size smaller will increase build time.", MessageType.None);
  84. }
  85. EditorGUI.indentLevel--;
  86. }
  87. // Override tile size
  88. EditorGUILayout.PropertyField(overrideTileSize);
  89. using (new EditorGUI.DisabledScope(!overrideTileSize.boolValue || overrideTileSize.hasMultipleDifferentValues))
  90. {
  91. EditorGUI.indentLevel++;
  92. EditorGUILayout.PropertyField(tileSize);
  93. if (!tileSize.hasMultipleDifferentValues && !voxelSize.hasMultipleDifferentValues)
  94. {
  95. float tileWorldSize = tileSize.intValue * voxelSize.floatValue;
  96. EditorGUILayout.LabelField(" ", tileWorldSize.ToString("0.00") + " world units", EditorStyles.miniLabel);
  97. }
  98. if (!overrideTileSize.hasMultipleDifferentValues)
  99. {
  100. if (overrideTileSize.boolValue)
  101. EditorGUILayout.HelpBox("Tile size controls the how local the changes to the world are (rebuild or carve). Small tile size allows more local changes, while potentially generating more data overall.", MessageType.None);
  102. }
  103. EditorGUI.indentLevel--;
  104. }
  105. EditorGUILayout.Space();
  106. EditorGUI.indentLevel--;
  107. }
  108. EditorGUILayout.Space();
  109. serializedObject.ApplyModifiedProperties();
  110. var hadError = false;
  111. var multipleTargets = targets.Length > 1;
  112. foreach (UnityNavMesh2DAdapter adapter in targets)
  113. {
  114. var settings = adapter.GetBuildSettings();
  115. var bounds = new Bounds(Vector3.zero, Vector3.zero);
  116. var errors = settings.ValidationReport(bounds);
  117. if (errors.Length > 0)
  118. {
  119. if (multipleTargets)
  120. EditorGUILayout.LabelField(adapter.name);
  121. foreach (var err in errors)
  122. {
  123. EditorGUILayout.HelpBox(err, MessageType.Warning);
  124. }
  125. GUILayout.BeginHorizontal();
  126. GUILayout.Space(EditorGUIUtility.labelWidth);
  127. if (GUILayout.Button("Open Agent Settings...", EditorStyles.miniButton))
  128. NavMeshEditorHelpers.OpenAgentSettings(adapter.AgentTypeID);
  129. GUILayout.EndHorizontal();
  130. hadError = true;
  131. }
  132. }
  133. if (hadError)
  134. EditorGUILayout.Space();
  135. #if NAVMESHCOMPONENTS_SHOW_NAVMESHDATA_REF
  136. var nmdRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
  137. EditorGUI.BeginProperty(nmdRect, GUIContent.none, m_NavMeshData);
  138. var rectLabel = EditorGUI.PrefixLabel(nmdRect, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(m_NavMeshData.displayName));
  139. EditorGUI.EndProperty();
  140. using (new EditorGUI.DisabledScope(true))
  141. {
  142. EditorGUI.BeginProperty(nmdRect, GUIContent.none, m_NavMeshData);
  143. EditorGUI.ObjectField(rectLabel, m_NavMeshData, GUIContent.none);
  144. EditorGUI.EndProperty();
  145. }
  146. #endif
  147. }
  148. }
  149. }
  150. #endif