diff options
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Editor/RecastMeshObjEditor.cs')
-rw-r--r-- | Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Editor/RecastMeshObjEditor.cs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Editor/RecastMeshObjEditor.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Editor/RecastMeshObjEditor.cs new file mode 100644 index 0000000..b911dc2 --- /dev/null +++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Editor/RecastMeshObjEditor.cs @@ -0,0 +1,129 @@ +using UnityEngine; +using UnityEditor; + +namespace Pathfinding { + [CustomEditor(typeof(RecastMeshObj))] + [CanEditMultipleObjects] + public class RecastMeshObjEditor : EditorBase { + protected override void Inspector () { + var modeProp = FindProperty("mode"); + var areaProp = FindProperty("surfaceID"); + var geometrySource = FindProperty("geometrySource"); + var includeInScan = FindProperty("includeInScan"); + var script = target as RecastMeshObj; + + if (areaProp.intValue < 0) { + areaProp.intValue = 0; + } + + PropertyField(includeInScan); + if (!includeInScan.hasMultipleDifferentValues && script.includeInScan == RecastMeshObj.ScanInclusion.AlwaysExclude) { + EditorGUILayout.HelpBox("This object will be completely ignored by the graph. Even if it would otherwise be included due to its layer or tag.", MessageType.None); + return; + } + + PropertyField(geometrySource, "Geometry Source"); + if (!geometrySource.hasMultipleDifferentValues) { + var geometrySourceValue = (RecastMeshObj.GeometrySource)geometrySource.intValue; + script.ResolveMeshSource(out var filter, out var coll, out var coll2D); + switch (geometrySourceValue) { + case RecastMeshObj.GeometrySource.Auto: + if (filter != null) { + EditorGUILayout.HelpBox("Using the attached MeshFilter as a source", MessageType.None); + if (script.GetComponent<MeshRenderer>() == null) { + EditorGUILayout.HelpBox("When a MeshFilter is used as a geometry source, a MeshRenderer must also be attached", MessageType.Error); + } + } else if (coll != null) { + EditorGUILayout.HelpBox("Using the attached collider as a source", MessageType.None); + } else if (coll2D != null) { + EditorGUILayout.HelpBox("Using the attached 2D collider as a source", MessageType.None); + } else { + EditorGUILayout.HelpBox("No MeshFilter or MeshCollider found on this GameObject", MessageType.Error); + } + break; + case RecastMeshObj.GeometrySource.MeshFilter: + if (filter == null) { + EditorGUILayout.HelpBox("No MeshFilter found on this GameObject", MessageType.Error); + } else if (script.GetComponent<MeshRenderer>() == null) { + EditorGUILayout.HelpBox("When a MeshFilter is used as a geometry source, a MeshRenderer must also be attached", MessageType.Error); + } + break; + case RecastMeshObj.GeometrySource.Collider: + if (coll == null && coll2D == null) { + EditorGUILayout.HelpBox("No collider found on this GameObject", MessageType.Error); + } + break; + } + } + + PropertyField(modeProp, "Surface Type"); + // Note: uses intValue instead of enumValueIndex because the enum does not start from 0. + var mode = (RecastMeshObj.Mode)modeProp.intValue; + if (!modeProp.hasMultipleDifferentValues) { + switch (mode) { + case RecastMeshObj.Mode.UnwalkableSurface: + EditorGUILayout.HelpBox("All surfaces on this mesh will be made unwalkable", MessageType.None); + break; + case RecastMeshObj.Mode.WalkableSurface: + EditorGUILayout.HelpBox("All surfaces on this mesh will be walkable", MessageType.None); + break; + case RecastMeshObj.Mode.WalkableSurfaceWithSeam: + EditorGUILayout.HelpBox("All surfaces on this mesh will be walkable and a " + + "seam will be created between the surfaces on this mesh and the surfaces on other meshes (with a different surface id)", MessageType.None); + EditorGUI.indentLevel++; + PropertyField(areaProp, "Surface ID"); + if (!areaProp.hasMultipleDifferentValues && areaProp.intValue < 0) { + areaProp.intValue = 0; + } + EditorGUI.indentLevel--; + break; + case RecastMeshObj.Mode.WalkableSurfaceWithTag: + EditorGUILayout.HelpBox("All surfaces on this mesh will be walkable and the given tag will be applied to them", MessageType.None); + EditorGUI.indentLevel++; + + EditorGUI.showMixedValue = areaProp.hasMultipleDifferentValues; + EditorGUI.BeginChangeCheck(); + var newTag = Util.EditorGUILayoutHelper.TagField(new GUIContent("Tag Value"), areaProp.intValue, AstarPathEditor.EditTags); + if (EditorGUI.EndChangeCheck()) { + areaProp.intValue = newTag; + } + if (!areaProp.hasMultipleDifferentValues && (areaProp.intValue < 0 || areaProp.intValue > GraphNode.MaxTagIndex)) { + areaProp.intValue = Mathf.Clamp(areaProp.intValue, 0, GraphNode.MaxTagIndex); + } + + EditorGUI.indentLevel--; + break; + } + } + + var dynamicProp = FindProperty("dynamic"); + PropertyField(dynamicProp, "Dynamic", "Setting this value to false will give better scanning performance, but you will not be able to move the object during runtime"); + if (!dynamicProp.hasMultipleDifferentValues && !dynamicProp.boolValue) { + EditorGUILayout.HelpBox("This object must not be moved during runtime since 'dynamic' is set to false", MessageType.Info); + } + + bool solidAlwaysEnabled = true; + bool solidRelevant = false; + for (int i = 0; i < targets.Length; i++) { + script.ResolveMeshSource(out var meshSource, out var collider, out var collider2D); + bool usesConvexCollider = collider != null && (collider is BoxCollider || collider is SphereCollider || collider is CapsuleCollider || (collider is MeshCollider mc && mc.convex)); + solidAlwaysEnabled &= usesConvexCollider; + + // If the object only has a 2D collider, the solid field doesn't affect anything + solidRelevant |= meshSource != null || collider != null; + } + + if (solidRelevant) { + if (solidAlwaysEnabled) { + // Forced solid + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.Toggle("Solid", true); + EditorGUILayout.HelpBox("Convex colliders are always treated as solid", MessageType.Info); + EditorGUI.EndDisabledGroup(); + } else { + PropertyField("solid"); + } + } + } + } +} |