private Tuple <PropertyWrapper, CableProperties.Direction, object> OnPropertyGUI(CableProperties.Direction dir, CableProperties properties) { Tuple <PropertyWrapper, CableProperties.Direction, object> changed = null; var data = EditorData.Instance.GetData(properties, "CableProperty" + dir.ToString()); if (InspectorGUI.Foldout(data, GUI.MakeLabel(dir.ToString()))) { using (InspectorGUI.IndentScope.Single) { var wrappers = PropertyWrapper.FindProperties <CableProperty>(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); foreach (var wrapper in wrappers) { if (wrapper.GetContainingType() == typeof(float) && InspectorEditor.ShouldBeShownInInspector(wrapper.Member)) { var value = EditorGUILayout.FloatField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <float>(properties[dir])); if (UnityEngine.GUI.changed) { changed = new Tuple <PropertyWrapper, CableProperties.Direction, object>(wrapper, dir, value); UnityEngine.GUI.changed = false; } } } } } return(changed); }
public override void OnPostTargetMembersGUI() { if (IsMultiSelect) { return; } var shapeVisual = ShapeVisual.Find(Shape); if (shapeVisual == null) { return; } var materials = shapeVisual.GetMaterials(); if (materials.Length > 1) { var names = (from renderer in shapeVisual.GetComponentsInChildren <MeshRenderer>() from material in renderer.sharedMaterials select renderer.name).ToArray(); var distinctMaterials = materials.Distinct().ToArray(); var isExtended = false; if (distinctMaterials.Length == 1) { isExtended = ShapeVisualMaterialGUI("Common Render Material", distinctMaterials[0], newMaterial => shapeVisual.SetMaterial(newMaterial)); } else { isExtended = InspectorGUI.Foldout(EditorData.Instance.GetData(Shape, "Render Materials"), GUI.MakeLabel("Render Materials")); } if (isExtended) { using (InspectorGUI.IndentScope.Single) for (int i = 0; i < materials.Length; ++i) { ShapeVisualMaterialGUI(names[i], materials[i], newMaterial => shapeVisual.ReplaceMaterial(i, newMaterial)); } } } else if (materials.Length == 1) { ShapeVisualMaterialGUI("Render Material", materials[0], newMaterial => shapeVisual.ReplaceMaterial(0, newMaterial)); } }
private void MeshStatisticsGUI() { if (IsMultiSelect || Mesh.PrecomputedCollisionMeshes.Length == 0) { return; } EditorGUILayout.Space(); InspectorGUI.BrandSeparator(); var numCollisionMeshes = Mesh.PrecomputedCollisionMeshes.Length; var totNumVertices = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Vertices.Length).Sum(); var totNumTriangles = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Indices.Length).Sum() / 3; var meshPlural = numCollisionMeshes > 1 ? "es" : string.Empty; var summaryString = $"Summary ({numCollisionMeshes} mesh{meshPlural}, {totNumTriangles} triangles, {totNumVertices} vertices)"; if (InspectorGUI.Foldout(GetMeshStatisticsEditorData(Mesh), GUI.MakeLabel(summaryString))) { InspectorGUI.Separator(); EditorGUILayout.LabelField(GUI.MakeLabel("Number of meshes"), GUI.MakeLabel(Mesh.PrecomputedCollisionMeshes.Length.ToString(), Color.green), InspectorEditor.Skin.TextField); using (InspectorGUI.IndentScope.Single) { InspectorGUI.Separator(); for (int i = 0; i < Mesh.PrecomputedCollisionMeshes.Length; ++i) { var numVertices = Mesh.PrecomputedCollisionMeshes[i].Vertices.Length; var numTriangles = Mesh.PrecomputedCollisionMeshes[i].Indices.Length / 3; EditorGUILayout.LabelField(GUI.MakeLabel($"[{i}] Number of triangles (vertices)"), GUI.MakeLabel($"{numTriangles.ToString().Color( InspectorGUISkin.BrandColorBlue )} ({numVertices.ToString()})"), InspectorEditor.Skin.TextField); } InspectorGUI.Separator(); } var totNumTrianglesString = totNumTriangles.ToString().Color(InspectorGUISkin.BrandColorBlue); var hasReducedNumTriangles = Mesh.Options != null && (Mesh.Options.Mode != AGXUnity.Collide.CollisionMeshOptions.MeshMode.Trimesh || Mesh.Options.ReductionEnabled); if (hasReducedNumTriangles) { totNumTrianglesString += $" (originally: {Mesh.SourceObjects.Select( source => source.triangles.Length / 3 ).Sum().ToString().Color( Color.red )})"; } EditorGUILayout.LabelField(GUI.MakeLabel("Total number of triangles"), GUI.MakeLabel(totNumTrianglesString), InspectorEditor.Skin.TextField); } }
private NodeFoldoutState NodeFoldout(Route <NodeT> .ValidatedNode validatedNode) { if (s_invalidNodeStyle == null) { s_invalidNodeStyle = new GUIStyle(InspectorEditor.Skin.Label); s_invalidNodeStyle.normal.background = GUI.CreateColoredTexture(1, 1, Color.Lerp(UnityEngine.GUI.color, Color.red, 0.75f)); } var state = new NodeFoldoutState(); var node = validatedNode.Node; var verticalScope = !validatedNode.Valid ? new EditorGUILayout.VerticalScope(s_invalidNodeStyle) : null; var horizontalScope = node == Selected ? new EditorGUILayout.HorizontalScope(InspectorEditor.Skin.Label) : new EditorGUILayout.HorizontalScope(InspectorEditor.Skin.TextArea); state.Foldout = InspectorGUI.Foldout(GetFoldoutData(node), GUI.MakeLabel(GetNodeTypeString(node) + ' ' + SelectGameObjectDropdownMenuTool.GetGUIContent(node.Parent).text, !validatedNode.Valid, validatedNode.ErrorString), newState => { Selected = newState ? node : null; EditorUtility.SetDirty(Parent); }); state.InsertBefore = InspectorGUI.Button(MiscIcon.EntryInsertBefore, true, "Insert a new node before this node.", GUILayout.Width(18)); state.InsertAfter = InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Insert a new node after this node.", GUILayout.Width(18)); state.Erase = InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove this node from the route.", GUILayout.Width(18)); horizontalScope?.Dispose(); verticalScope?.Dispose(); return(state); }
private void HandleLineToolInspectorGUI(LineTool lineTool, string name) { // If visible, the vertical maker starts under the foldout, otherwise // render the marker through the fouldout label. var isVisible = GetLineToggleData(name).Bool; var color = Color.Lerp(lineTool.Color, InspectorGUI.BackgroundColor, 0.25f); using (new InspectorGUI.VerticalScopeMarker(color)) { if (!InspectorGUI.Foldout(GetLineToggleData(name), GUI.MakeLabel(name, true))) { return; } //using ( new InspectorGUI.VerticalScopeMarker( color ) ) using (InspectorGUI.IndentScope.Single) lineTool.OnInspectorGUI(); } }
public void OnInspectorGUI() { if (Mode == ToolMode.Direction) { StartFrameNameId = "Frame"; } StartFrameToolEnable = Line.Valid; EndFrameToolEnable = Line.Valid; bool toggleCreateEdge = false; bool toggleFlipDirection = false; bool toggleRenderAsArrow = false; bool showTools = !EditorApplication.isPlaying; if (showTools) { var toolButtonData = new List <InspectorGUI.ToolButtonData>(); toolButtonData.Add(InspectorGUI.ToolButtonData.Create(ToolIcon.VisualizeLineDirection, RenderAsArrow, "Visualize line direction.", () => toggleRenderAsArrow = true, Mode != ToolMode.Direction)); toolButtonData.Add(InspectorGUI.ToolButtonData.Create(ToolIcon.FlipDirection, false, "Flip direction.", () => toggleFlipDirection = true, Line.Valid)); toolButtonData.Add(InspectorGUI.ToolButtonData.Create(ToolIcon.FindTransformGivenEdge, EdgeDetectionToolEnable, "Find line given edge.", () => toggleCreateEdge = true)); InspectorGUI.ToolButtons(toolButtonData.ToArray()); } if (toggleCreateEdge) { EdgeDetectionToolEnable = !EdgeDetectionToolEnable; } if (toggleFlipDirection && EditorUtility.DisplayDialog("Line direction", "Flip direction of " + Name + "?", "Yes", "No")) { StartFrameToolEnable = false; if (Mode == ToolMode.Direction) { Line.End.Position = Line.End.Position - 2.0f * Line.Length * Line.Direction; Line.Start.Rotation = Quaternion.Euler(-Line.Start.Rotation.eulerAngles); Line.End.Rotation = Quaternion.Euler(-Line.End.Rotation.eulerAngles); } else { var tmp = Line.Start; Line.Start = Line.End; Line.End = tmp; } } if (toggleRenderAsArrow) { RenderAsArrow = !RenderAsArrow; } if (!Line.Valid) { InspectorGUI.WarningLabel(Name + " isn't created - use Tools to configure."); } if (StartFrameToolEnable) { if (InspectorGUI.Foldout(GetToggleData(StartFrameNameId), GUI.MakeLabel(StartFrameNameId, true))) { StartFrameTool.ForceDisableTransformHandle = EditorApplication.isPlaying; using (new GUI.EnabledBlock(!EditorApplication.isPlaying)) InspectorGUI.HandleFrame(StartFrameTool.Frame, 1); } } if (EndFrameToolEnable) { if (InspectorGUI.Foldout(GetToggleData(EndFrameNameId), GUI.MakeLabel(EndFrameNameId, true))) { EndFrameTool.ForceDisableTransformHandle = EditorApplication.isPlaying; using (new GUI.EnabledBlock(!EditorApplication.isPlaying)) InspectorGUI.HandleFrame(EndFrameTool.Frame, 1); } } Synchronize(); }
public override void OnPreTargetMembersGUI() { var skin = InspectorEditor.Skin; var constraints = GetTargets <Constraint>().ToArray(); var refConstraint = constraints[0]; var differentTypes = false; var anyUnknownType = constraints.Any(c => c.Type == ConstraintType.Unknown); for (int i = 1; i < constraints.Length; ++i) { differentTypes = differentTypes || refConstraint.Type != constraints[i].Type; } // Render AttachmentPair GUI. ConstraintAttachmentFrameTool.OnPreTargetMembersGUI(); Undo.RecordObjects(constraints, "ConstraintTool"); UnityEngine.GUI.changed = false; // The constraint type is Unknown when, e.g., go.AddComponent<Constraint>() // or when the constraint has been reset. If any of the selected constraints // is of type Unknown, we exit the GUI here. if (!ConstraintTypeGUI(constraints, differentTypes)) { return; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.CollisionsState != constraint.CollisionsState); var collisionsState = ConstraintCollisionsStateGUI(refConstraint.CollisionsState); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.CollisionsState = collisionsState; } UnityEngine.GUI.changed = false; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.SolveType != constraint.SolveType); var solveType = ConstraintSolveTypeGUI(refConstraint.SolveType); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.SolveType = solveType; } UnityEngine.GUI.changed = false; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.ConnectedFrameNativeSyncEnabled != constraint.ConnectedFrameNativeSyncEnabled); var frameNativeSync = ConstraintConnectedFrameSyncGUI(refConstraint.ConnectedFrameNativeSyncEnabled); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.ConnectedFrameNativeSyncEnabled = frameNativeSync; } UnityEngine.GUI.changed = false; } if (differentTypes) { InspectorGUI.WarningLabel("Constraints are of different types.\nRow data editing not supported."); return; } Func <string, EditorDataEntry> selected = (id) => { return(EditorData.Instance.GetData(refConstraint, id, entry => entry.Bool = false)); }; var constraintsParser = (from constraint in constraints select ConstraintUtils.ConstraintRowParser.Create(constraint)).ToArray(); var allElementaryConstraints = constraints.SelectMany(constraint => constraint.GetOrdinaryElementaryConstraints()).ToArray(); Undo.RecordObjects(allElementaryConstraints, "ConstraintTool"); var ecRowDataWrappers = InvokeWrapper.FindFieldsAndProperties <ElementaryConstraintRowData>(); foreach (ConstraintUtils.ConstraintRowParser.RowType rowType in Enum.GetValues(typeof(ConstraintUtils.ConstraintRowParser.RowType))) { if (!InspectorGUI.Foldout(selected("ec_" + rowType.ToString()), GUI.MakeLabel(rowType.ToString() + " properties", true))) { continue; } using (InspectorGUI.IndentScope.Single) { var refTransOrRotRowData = constraintsParser[0][rowType]; foreach (var wrapper in ecRowDataWrappers) { if (!InspectorEditor.ShouldBeShownInInspector(wrapper.Member)) { continue; } for (int i = 0; i < 3; ++i) { var rowDataInstances = (from constraintParser in constraintsParser where constraintParser[rowType][i] != null select constraintParser[rowType][i].RowData).ToArray(); using (new GUI.EnabledBlock(refTransOrRotRowData[i] != null)) { var labelContent = i == 0 ? InspectorGUI.MakeLabel(wrapper.Member) : null; var fieldContent = GUI.MakeLabel(RowLabels[i], RowColors[i]); if (wrapper.IsType <float>()) { EditorGUI.showMixedValue = !wrapper.AreValuesEqual(rowDataInstances); var value = InspectorGUI.CustomFloatField(labelContent, fieldContent, wrapper.Get <float>(refTransOrRotRowData[i]?.RowData)); if (UnityEngine.GUI.changed) { foreach (var constraintParser in constraintsParser) { wrapper.ConditionalSet(constraintParser[rowType][i]?.RowData, value); } } } else if (wrapper.IsType <RangeReal>()) { EditorGUI.showMixedValue = rowDataInstances.Any(rowData => !Equals(wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData).Min, wrapper.Get <RangeReal>(rowData).Min)) || rowDataInstances.Any(rowData => !Equals(wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData).Max, wrapper.Get <RangeReal>(rowData).Max)); var rangeChangeData = InspectorGUI.RangeRealField(labelContent, wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData), GUI.MakeLabel(RowLabels[i], RowColors[i])); if (rangeChangeData.MinChanged || rangeChangeData.MaxChanged) { foreach (var constraintParser in constraintsParser) { var range = wrapper.Get <RangeReal>(constraintParser[rowType][i].RowData); if (rangeChangeData.MinChanged) { range.Min = rangeChangeData.Min; } if (rangeChangeData.MaxChanged) { range.Max = rangeChangeData.Max; } // Validation of Min > Max has to go somewhere else because if e.g., // Min = 50 and the user wants to type Max = 200 we're receiving // Max = 2 as the user types. wrapper.ConditionalSet(constraintParser[rowType][i].RowData, range); } } } } UnityEngine.GUI.changed = false; EditorGUI.showMixedValue = false; } } // For type wrappers. } // Indentation. } // For Translational, Rotational. var ecControllers = refConstraint.GetElementaryConstraintControllers(); if (ecControllers.Length > 0 && InspectorGUI.Foldout(selected("controllers"), GUI.MakeLabel("Controllers", true))) { using (InspectorGUI.IndentScope.Single) { foreach (var refController in ecControllers) { var controllerType = refController.GetControllerType(); var controllerTypeTag = controllerType.ToString()[0].ToString(); var controllerName = ConstraintUtils.FindName(refController); if (controllerName.EndsWith(" Controller")) { controllerName = controllerName.Remove(controllerName.LastIndexOf(" Controller")); } var controllerLabel = GUI.MakeLabel((controllerType == Constraint.ControllerType.Rotational ? GUI.Symbols.CircleArrowAcw.ToString() + " " : GUI.Symbols.ArrowRight.ToString() + " ") + controllerName, true); if (!InspectorGUI.Foldout(selected(controllerTypeTag + controllerName), controllerLabel)) { continue; } var controllers = (from constraint in constraints from controller in constraint.GetElementaryConstraintControllers() where controller.GetType() == refController.GetType() && controller.GetControllerType() == refController.GetControllerType() select controller).ToArray(); using (InspectorGUI.IndentScope.Single) { InspectorEditor.DrawMembersGUI(controllers); InspectorEditor.DrawMembersGUI(controllers, controller => (controller as ElementaryConstraint).RowData[0]); } } } } }
private void MeshOptionsGUI() { InspectorGUI.Separator(); using (new GUI.EnabledBlock(!EditorApplication.isPlayingOrWillChangePlaymode)) { if (InspectorGUI.Foldout(GetEditorData(Mesh), GUI.MakeLabel("Options"))) { using (InspectorGUI.IndentScope.Single) { InspectorEditor.DrawMembersGUI(Targets, t => (t as AGXUnity.Collide.Mesh).Options); var applyResetResult = InspectorGUI.PositiveNegativeButtons(UnityEngine.GUI.enabled, "Apply", "Apply the changes", "Reset", "Delete collision meshes and reset mesh options values to default."); if (applyResetResult == InspectorGUI.PositiveNegativeResult.Positive) { var meshes = GetTargets <AGXUnity.Collide.Mesh>().ToArray(); var collisionMeshGenerator = new AGXUnity.Collide.CollisionMeshGenerator(); var generatorStartTime = EditorApplication.timeSinceStartup; collisionMeshGenerator.GenerateAsync(meshes); var isCanceled = false; while (!isCanceled && collisionMeshGenerator.IsRunning) { var progressBarTitle = $"Generating collision meshes: {(int)( EditorApplication.timeSinceStartup - generatorStartTime )} s"; var progressBarInfo = string.Empty; var progress = collisionMeshGenerator.Progress; isCanceled = EditorUtility.DisplayCancelableProgressBar(progressBarTitle, progressBarInfo, progress); if (!isCanceled) { System.Threading.Thread.Sleep(50); } } EditorUtility.ClearProgressBar(); if (isCanceled) { CanceledAsyncCollisionMeshGeneretors.RegisterCanceled(collisionMeshGenerator); } else { var results = collisionMeshGenerator.CollectResults(); using (new Utils.UndoCollapseBlock("Apply collision mesh data")) { foreach (var result in results) { Undo.RecordObject(result.Mesh, "Collision Meshes"); result.Mesh.Options = result.Options; result.Mesh.PrecomputedCollisionMeshes = result.CollisionMeshes; } } var hasPrefabAssetBeenChanged = results.Any(result => PrefabUtility.GetCorrespondingObjectFromOriginalSource(result.Mesh.gameObject) == null && PrefabUtility.GetPrefabInstanceHandle(result.Mesh.gameObject) == null); // Trying to dirty gizmos rendering of all affected prefab instances. // We don't have to dirty them all but it's hard to determine where // the instance is located in the hierarchy. if (hasPrefabAssetBeenChanged) { var allMeshes = Object.FindObjectsOfType <AGXUnity.Collide.Mesh>(); foreach (var m in allMeshes) { m.OnPrecomputedCollisionMeshDataDirty(); } } } collisionMeshGenerator = null; GUIUtility.ExitGUI(); } else if (applyResetResult == InspectorGUI.PositiveNegativeResult.Negative && EditorUtility.DisplayDialog("Reset collision meshes to default", "Destroy collision meshes and reset mesh options to default?", "Yes", "Cancel")) { var meshes = GetTargets <AGXUnity.Collide.Mesh>().ToArray(); using (new Utils.UndoCollapseBlock("Reset collision mesh data")) { for (int i = 0; i < meshes.Length; ++i) { var mesh = meshes[i]; Undo.RecordObject(mesh, "Resetting collision mesh data"); mesh.DestroyCollisionMeshes(); if (mesh.Options != null) { Undo.RecordObject(mesh, "Resetting mesh options to default"); mesh.Options.ResetToDesfault(); } } } } } } } }
private void RouteGUI() { var addNewPressed = false; var insertBeforePressed = false; var insertAfterPressed = false; var erasePressed = false; NodeT listOpNode = null; Undo.RecordObject(Route, "Route changed"); if (InspectorGUI.Foldout(EditorData.Instance.GetData(Parent, "Route", entry => { entry.Bool = true; }), GUI.MakeLabel("Route"))) { var validatedRoute = Route.GetValidated(); foreach (var validatedNode in validatedRoute) { var node = validatedNode.Node; using (InspectorGUI.IndentScope.Single) { var foldoutState = NodeFoldout(validatedNode); if (foldoutState.Foldout) { OnPreFrameGUI(node); InspectorGUI.HandleFrame(node, 1); OnPostFrameGUI(node); } if (listOpNode == null && foldoutState.ButtonPressed) { listOpNode = node; } insertBeforePressed = insertBeforePressed || foldoutState.InsertBefore; insertAfterPressed = insertAfterPressed || foldoutState.InsertAfter; erasePressed = erasePressed || foldoutState.Erase; } if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDown && Event.current.button == 0) { Selected = node; } } GUILayout.BeginHorizontal(); { InspectorGUI.Separator(1, EditorGUIUtility.singleLineHeight); addNewPressed = InspectorGUI.Button(MiscIcon.EntryAdd, true, "Add new node to the route.", GUILayout.Width(18)); if (listOpNode == null && addNewPressed) { listOpNode = Route.LastOrDefault(); } } GUILayout.EndHorizontal(); } else { InspectorGUI.Separator(1, 3); } if (addNewPressed || insertBeforePressed || insertAfterPressed) { NodeT newRouteNode = null; // Clicking "Add" will not copy data from last node. newRouteNode = listOpNode != null? addNewPressed? RouteNode.Create <NodeT>(null, listOpNode.Position, listOpNode.Rotation) : RouteNode.Create <NodeT>(listOpNode.Parent, listOpNode.LocalPosition, listOpNode.LocalRotation) : RouteNode.Create <NodeT>(); OnNodeCreate(newRouteNode, listOpNode, addNewPressed); if (addNewPressed) { Route.Add(newRouteNode); } if (insertBeforePressed) { Route.InsertBefore(newRouteNode, listOpNode); } if (insertAfterPressed) { Route.InsertAfter(newRouteNode, listOpNode); } if (newRouteNode != null) { CreateRouteNodeTool(newRouteNode); Selected = newRouteNode; } } else if (listOpNode != null && erasePressed) { Selected = null; Route.Remove(listOpNode); } }
public override void OnPreTargetMembersGUI() { var skin = InspectorEditor.Skin; var disabledPairs = Manager.DisabledPairs; bool clearPressed = false; bool addPressed = false; CollisionGroupEntryPair erasePair = null; GUILayout.Label(GUI.MakeLabel("Add pair", true), skin.LabelMiddleCenter); GUILayout.BeginVertical(skin.TextArea); { HandleCollisionGroupEntryPair(m_groupEntryPairToAdd); var buttonState = InspectorGUI.PositiveNegativeButtons(m_groupEntryPairToAdd.First.Tag.Length > 0 || m_groupEntryPairToAdd.Second.Tag.Length > 0, "Add", "Add pair to disabled pairs.", "Clear"); addPressed = buttonState == InspectorGUI.PositiveNegativeResult.Positive; clearPressed = buttonState == InspectorGUI.PositiveNegativeResult.Negative; } GUILayout.EndVertical(); if (InspectorGUI.Foldout(FoldoutDataEntry, GUI.MakeLabel("Disabled Pairs [" + disabledPairs.Length + "]"))) { using (InspectorGUI.IndentScope.Single) { foreach (var disabledPair in disabledPairs) { GUILayout.BeginHorizontal(); { InspectorGUI.Separator(1, EditorGUIUtility.singleLineHeight); if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove pair from list.", GUILayout.Width(18))) { erasePair = disabledPair; } } GUILayout.EndHorizontal(); HandleCollisionGroupEntryPair(disabledPair); // TODO GUI: Maybe unnecessary space with correct separator. GUILayout.Space(6.0f); } } } if (clearPressed) { m_groupEntryPairToAdd.First.Tag = m_groupEntryPairToAdd.Second.Tag = string.Empty; } if (addPressed) { Manager.SetEnablePair(m_groupEntryPairToAdd.First.Tag, m_groupEntryPairToAdd.Second.Tag, false); m_groupEntryPairToAdd.First.Tag = m_groupEntryPairToAdd.Second.Tag = string.Empty; FoldoutDataEntry.Bool = true; } if (erasePair != null) { if (EditorUtility.DisplayDialog("Remove pair", "Erase disabled pair: " + erasePair.First.Tag + " and " + erasePair.Second.Tag + "?", "Yes", "No")) { Manager.SetEnablePair(erasePair.First.Tag, erasePair.Second.Tag, true); } } }