public override void OnInspectorGUI() { serializedObject.Update(); InspectorEditButtonGui(); EditorGUILayout.PropertyField(_mSize); EditorGUILayout.PropertyField(_mCenter); NavMeshComponentsGuiUtility.AreaPopup("Area Type", _mArea); NavMeshComponentsGuiUtility.AgentMaskPopup("Affected Agents", _mAffectedAgents); EditorGUILayout.Space(); serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { serializedObject.Update(); NavMeshComponentsGuiUtility.AgentTypePopup("Agent Type", _mAgentTypeId); EditorGUILayout.Space(); EditorGUILayout.PropertyField(_mStartPoint); EditorGUILayout.PropertyField(_mEndPoint); GUILayout.BeginHorizontal(); GUILayout.Space(EditorGUIUtility.labelWidth); if (GUILayout.Button("Swap")) { foreach (NavMeshLink navLink in targets) { var tmp = navLink.startPoint; navLink.startPoint = navLink.endPoint; navLink.endPoint = tmp; } SceneView.RepaintAll(); } if (GUILayout.Button("Align Transform")) { foreach (NavMeshLink navLink in targets) { Undo.RecordObject(navLink.transform, "Align Transform to End Points"); Undo.RecordObject(navLink, "Align Transform to End Points"); AlignTransformToEndPoints(navLink); } SceneView.RepaintAll(); } GUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.PropertyField(_mWidth); EditorGUILayout.PropertyField(_mCostModifier); EditorGUILayout.PropertyField(_mAutoUpdatePosition); EditorGUILayout.PropertyField(_mBidirectional); NavMeshComponentsGuiUtility.AreaPopup("Area Type", _mArea); serializedObject.ApplyModifiedProperties(); EditorGUILayout.Space(); }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(_mIgnoreFromBuild); EditorGUILayout.PropertyField(_mOverrideArea); if (_mOverrideArea.boolValue) { EditorGUI.indentLevel++; NavMeshComponentsGuiUtility.AreaPopup("Area Type", _mArea); EditorGUI.indentLevel--; } NavMeshComponentsGuiUtility.AgentMaskPopup("Affected Agents", _mAffectedAgents); EditorGUILayout.Space(); serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { if (_sStyles == null) { _sStyles = new Styles(); } serializedObject.Update(); var bs = NavMesh.GetSettingsByID(_mAgentTypeId.intValue); if (bs.agentTypeID != -1) { // Draw image const float diagramHeight = 80.0f; Rect agentDiagramRect = EditorGUILayout.GetControlRect(false, diagramHeight); NavMeshEditorHelpers.DrawAgentDiagram(agentDiagramRect, bs.agentRadius, bs.agentHeight, bs.agentClimb, bs.agentSlope); } NavMeshComponentsGuiUtility.AgentTypePopup("Agent Type", _mAgentTypeId); EditorGUILayout.Space(); EditorGUILayout.PropertyField(_mCollectObjects); if ((CollectObjects)_mCollectObjects.enumValueIndex == CollectObjects.Volume) { EditorGUI.indentLevel++; InspectorEditButtonGui(); EditorGUILayout.PropertyField(_mSize); EditorGUILayout.PropertyField(_mCenter); } else { if (editingCollider) { EditMode.QuitEditMode(); } } EditorGUILayout.PropertyField(_mLayerMask, _sStyles.MLayerMask); EditorGUILayout.PropertyField(_mUseGeometry); EditorGUILayout.Space(); EditorGUILayout.Space(); _mOverrideVoxelSize.isExpanded = EditorGUILayout.Foldout(_mOverrideVoxelSize.isExpanded, "Advanced"); if (_mOverrideVoxelSize.isExpanded) { EditorGUI.indentLevel++; NavMeshComponentsGuiUtility.AreaPopup("Default Area", _mDefaultArea); // Override voxel size. EditorGUILayout.PropertyField(_mOverrideVoxelSize); using (new EditorGUI.DisabledScope(!_mOverrideVoxelSize.boolValue || _mOverrideVoxelSize.hasMultipleDifferentValues)) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(_mVoxelSize); if (!_mOverrideVoxelSize.hasMultipleDifferentValues) { if (!_mAgentTypeId.hasMultipleDifferentValues) { float voxelsPerRadius = _mVoxelSize.floatValue > 0.0f ? (bs.agentRadius / _mVoxelSize.floatValue) : 0.0f; EditorGUILayout.LabelField(" ", $"{voxelsPerRadius:0.00} voxels per agent radius", EditorStyles.miniLabel); } if (_mOverrideVoxelSize.boolValue) { 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); } } EditorGUI.indentLevel--; } // Override tile size EditorGUILayout.PropertyField(_mOverrideTileSize); using (new EditorGUI.DisabledScope(!_mOverrideTileSize.boolValue || _mOverrideTileSize.hasMultipleDifferentValues)) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(_mTileSize); if (!_mTileSize.hasMultipleDifferentValues && !_mVoxelSize.hasMultipleDifferentValues) { float tileWorldSize = _mTileSize.intValue * _mVoxelSize.floatValue; EditorGUILayout.LabelField(" ", $"{tileWorldSize:0.00} world units", EditorStyles.miniLabel); } if (!_mOverrideTileSize.hasMultipleDifferentValues) { if (_mOverrideTileSize.boolValue) { 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 in overal.", MessageType.None); } } EditorGUI.indentLevel--; } // Height mesh using (new EditorGUI.DisabledScope(true)) { EditorGUILayout.PropertyField(_mBuildHeightMesh); } EditorGUILayout.Space(); EditorGUI.indentLevel--; } EditorGUILayout.Space(); serializedObject.ApplyModifiedProperties(); var hadError = false; var multipleTargets = targets.Length > 1; foreach (NavMeshSurface navSurface in targets) { var settings = navSurface.GetBuildSettings(); // Calculating bounds is potentially expensive when unbounded - so here we just use the center/size. // It means the validation is not checking vertical voxel limit correctly when the surface is set to something else than "in volume". var bounds = new Bounds(Vector3.zero, Vector3.zero); if (navSurface.collectObjects == CollectObjects.Volume) { bounds = new Bounds(navSurface.center, navSurface.size); } var errors = settings.ValidationReport(bounds); if (errors.Length > 0) { if (multipleTargets) { EditorGUILayout.LabelField(navSurface.name); } foreach (var err in errors) { EditorGUILayout.HelpBox(err, MessageType.Warning); } GUILayout.BeginHorizontal(); GUILayout.Space(EditorGUIUtility.labelWidth); if (GUILayout.Button("Open Agent Settings...", EditorStyles.miniButton)) { NavMeshEditorHelpers.OpenAgentSettings(navSurface.AgentTypeId); } GUILayout.EndHorizontal(); hadError = true; } } if (hadError) { EditorGUILayout.Space(); } using (new EditorGUI.DisabledScope(Application.isPlaying || _mAgentTypeId.intValue == -1)) { GUILayout.BeginHorizontal(); GUILayout.Space(EditorGUIUtility.labelWidth); if (GUILayout.Button("Clear")) { foreach (NavMeshSurface s in targets) { ClearSurface(s); } SceneView.RepaintAll(); } if (GUILayout.Button("Bake")) { // Remove first to avoid double registration of the callback EditorApplication.update -= UpdateAsyncBuildOperations; EditorApplication.update += UpdateAsyncBuildOperations; foreach (NavMeshSurface surf in targets) { var oper = new AsyncBakeOperation(); oper.BakeData = InitializeBakeData(surf); oper.BakeOperation = surf.UpdateNavMesh(oper.BakeData); oper.Surface = surf; _sBakeOperations.Add(oper); } } GUILayout.EndHorizontal(); } // Show progress for the selected targets for (int i = _sBakeOperations.Count - 1; i >= 0; --i) { if (!targets.Contains(_sBakeOperations[i].Surface)) { continue; } var oper = _sBakeOperations[i].BakeOperation; if (oper == null) { continue; } var p = oper.progress; if (oper.isDone) { SceneView.RepaintAll(); continue; } GUILayout.BeginHorizontal(); if (GUILayout.Button("Cancel", EditorStyles.miniButton)) { var bakeData = _sBakeOperations[i].BakeData; UnityEngine.AI.NavMeshBuilder.Cancel(bakeData); _sBakeOperations.RemoveAt(i); } EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), p, $"Baking: {(int) (100 * p)}%"); if (p <= 1) { Repaint(); } GUILayout.EndHorizontal(); } }