public void Manual_PlanarProjection() { //Select faces List <Face> selectedFaces = new List <Face>(); selectedFaces.Add(m_cube.faces[2]); selectedFaces.Add(m_cube.faces[4]); selectedFaces.Add(m_cube.faces[5]); MeshSelection.SetSelection(m_cube.gameObject); m_cube.SetSelectedFaces(selectedFaces); MeshSelection.OnObjectSelectionChanged(); foreach (Face f in selectedFaces) { Assert.That(f.manualUV, Is.EqualTo(false)); } //Select faces UVEditor.instance.Menu_SetManualUV(); foreach (Face f in selectedFaces) { Assert.That(f.manualUV, Is.EqualTo(true)); } //Modify those faces Vector2 minimalUV = UVEditor.instance.UVSelectionMinimalUV(); Assert.That(minimalUV, !Is.EqualTo(UVEditor.LowerLeft)); UVEditor.instance.Menu_PlanarProject(); minimalUV = UVEditor.instance.UVSelectionMinimalUV(); Assert.That(minimalUV, Is.EqualTo(UVEditor.LowerLeft)); }
public void SelectMaterial_WithNullMaterial() { //Make first faces selected ProBuilderMesh mesh = selectables[0]; MeshSelection.SetSelection(mesh.gameObject); mesh.AddToFaceSelection(3); MeshSelection.OnObjectSelectionChanged(); UnityEditor.ProBuilder.Actions.SelectMaterial selectMaterial = new UnityEditor.ProBuilder.Actions.SelectMaterial(); var oldValue = selectMaterial.m_RestrictToSelectedObjects.value; selectMaterial.m_RestrictToSelectedObjects.value = false; selectMaterial.PerformAction(); selectMaterial.m_RestrictToSelectedObjects.value = oldValue; //We need to force the object selection change here to ensure that MeshSelection reflect the result //of the action, which typically would notify the MeshSelection asynchronously. MeshSelection.OnObjectSelectionChanged(); Assert.That(MeshSelection.selectedObjectCount, Is.EqualTo(1)); Assert.That(mesh.selectedFaceCount, Is.EqualTo(3)); Assert.That(mesh.selectedFaceIndexes.IndexOf(3), !Is.EqualTo(-1)); Assert.That(mesh.selectedFaceIndexes.IndexOf(4), !Is.EqualTo(-1)); Assert.That(mesh.selectedFaceIndexes.IndexOf(5), !Is.EqualTo(-1)); Assert.That(selectables[1].selectedFaceCount, Is.EqualTo(0)); }
public void DuplicateFaces_ToSubmesh() { //Make first faces selected ProBuilderMesh mesh = selectables[0]; Assume.That(mesh.faces, Is.Not.Null); Face face = selectables[0].faces[0]; List <Face> selectedFaces = new List <Face>(); selectedFaces.Add(face); mesh.SetSelectedFaces(selectedFaces); Assert.AreEqual(mesh.selectedFaceCount, 1); MeshSelection.SetSelection(mesh.gameObject); MeshSelection.OnObjectSelectionChanged(); UnityEditor.ProBuilder.Actions.DuplicateFaces duplicateFaces = new UnityEditor.ProBuilder.Actions.DuplicateFaces(); ProBuilderSettings.Set <UnityEditor.ProBuilder.Actions.DuplicateFaces.DuplicateFaceSetting>("DuplicateFaces.target", UnityEditor.ProBuilder.Actions.DuplicateFaces.DuplicateFaceSetting.Submesh); duplicateFaces.DoAction(); //All selectable object should have all faces selected Assert.AreEqual(selectables[0].faces.Count, 7); Assert.AreEqual(MeshSelection.selectedObjectCount, 1); Assert.AreEqual(UnityEditor.Selection.objects[0], mesh.gameObject); }
public override ActionResult DoAction() { GameObject go = new GameObject(); PolyShape poly = go.AddComponent <PolyShape>(); ProBuilderMesh pb = poly.gameObject.AddComponent <ProBuilderMesh>(); pb.CreateShapeFromPolygon(poly.m_Points, poly.extrude, poly.flipNormals); EditorUtility.InitObject(pb); // Special case - we don't want to reset the grid pivot because we rely on it to set the active plane for // interaction, regardless of whether snapping is enabled or not. if (ProGridsInterface.SnapEnabled() || ProGridsInterface.GridVisible()) { Vector3 pivot; if (ProGridsInterface.GetPivot(out pivot)) { go.transform.position = pivot; } } MeshSelection.SetSelection(go); UndoUtility.RegisterCreatedObjectUndo(go, "Create Poly Shape"); poly.polyEditMode = PolyShape.PolyEditMode.Path; return(new ActionResult(ActionResult.Status.Success, "Create Poly Shape")); }
public void CollapseVertices_SelectedSharedVertices_ActionEnabled() { // check that selecting two shared vertices will enable collapse vertices Assert.That(m_PBMesh, Is.Not.Null); var sharedVertices = m_PBMesh.sharedVerticesInternal; Assert.That(sharedVertices, Is.Not.Null); Assert.That(sharedVertices.Length, Is.GreaterThanOrEqualTo(2)); var selectedVertices = sharedVertices[0].Union(sharedVertices[1]); Assert.That(selectedVertices.Count(), Is.GreaterThan(1)); // Set the selected vertices to two different shared vertices (collapsable) m_PBMesh.SetSelectedVertices(selectedVertices); Assert.That(m_PBMesh.selectedIndexesInternal.Length, Is.EqualTo(selectedVertices.Count())); MeshSelection.SetSelection(m_PBMesh.gameObject); MeshSelection.OnObjectSelectionChanged(); UnityEditor.ProBuilder.Actions.CollapseVertices collapseVertices = new UnityEditor.ProBuilder.Actions.CollapseVertices(); Assert.That(collapseVertices.enabled, Is.True); }
public void DuplicateFaces_ToObject() { //Make first faces selected ProBuilderMesh mesh = selectables[0]; Assume.That(mesh.faces, Is.Not.Null); Face face = selectables[0].faces[0]; List <Face> selectedFaces = new List <Face>(); selectedFaces.Add(face); mesh.SetSelectedFaces(selectedFaces); Assert.AreEqual(mesh.selectedFaceCount, 1); MeshSelection.SetSelection(mesh.gameObject); MeshSelection.OnObjectSelectionChanged(); UnityEditor.ProBuilder.Actions.DuplicateFaces duplicateFaces = new UnityEditor.ProBuilder.Actions.DuplicateFaces(); ProBuilderSettings.Set <UnityEditor.ProBuilder.Actions.DuplicateFaces.DuplicateFaceSetting>("DuplicateFaces.target", UnityEditor.ProBuilder.Actions.DuplicateFaces.DuplicateFaceSetting.GameObject); duplicateFaces.DoAction(); //selectable object should keep all faces selected Assert.AreEqual(selectables[0].faces.Count, 6); Assert.AreEqual(MeshSelection.selectedObjectCount, 1); Assert.AreNotEqual(UnityEditor.Selection.objects[0], mesh.gameObject); //This needs to be called explicitly in the case of unit test so that the internal representation of ProBuilder MeshSelection //gets updated prior to accessing it MeshSelection.OnObjectSelectionChanged(); ProBuilderMesh newMesh = MeshSelection.activeMesh; Assert.AreEqual(newMesh.faces.Count, 1); }
public void SelectFaces_WithoutColor() { Setup(); //Make first faces selected ProBuilderMesh mesh = selectables[0]; Assert.IsNotNull(mesh.faces); Face face = selectables[0].faces[0]; List <Face> selectedFaces = new List <Face>(); selectedFaces.Add(face); mesh.SetSelectedFaces(selectedFaces); Assert.AreEqual(mesh.selectedFaceCount, 1); MeshSelection.SetSelection(mesh.gameObject); MeshSelection.OnObjectSelectionChanged(); foreach (var currObject in selectables) { //Validate that prior not all faces are selected Assert.AreNotEqual(currObject.selectedFacesInternal.Length, 6); } UnityEditor.ProBuilder.Actions.SelectVertexColor selectColorAction = new UnityEditor.ProBuilder.Actions.SelectVertexColor(); selectColorAction.DoAction(); foreach (var currObject in selectables) { //All selectable object should have all faces selected Assert.AreEqual(currObject.selectedFacesInternal.Length, 6); } }
protected override ActionResult PerformActionImplementation() { ProBuilderEditor.selectMode = SelectMode.Object; MeshSelection.SetSelection((GameObject)null); m_Tool = ScriptableObject.CreateInstance <DrawShapeTool>(); ToolManager.SetActiveTool(m_Tool); MenuAction.onPerformAction += ActionPerformed; ToolManager.activeToolChanging += LeaveTool; ProBuilderEditor.selectModeChanged += OnSelectModeChanged; return(new ActionResult(ActionResult.Status.Success, "Draw Shape Tool Starts")); }
public void CollapseVertices_SelectedSharedVertices_ActionEnabled() { Assume.That(m_PBMesh, Is.Not.Null); MeshSelection.SetSelection(m_PBMesh.gameObject); int[] vertexSelection = new[] { 0, 1, 2, 3 }; m_PBMesh.SetSelectedVertices(vertexSelection); Assume.That(m_PBMesh.selectedIndexesInternal, Is.EquivalentTo(vertexSelection)); Assume.That(MeshSelection.selectedVertexCount, Is.EqualTo(vertexSelection.Length)); var collapseAction = new UnityEditor.ProBuilder.Actions.CollapseVertices(); Assert.That(collapseAction.enabled, Is.True); }
protected override ActionResult PerformActionImplementation() { GameObject go = new GameObject(); var bezier = go.AddComponent <BezierShape>(); go.GetComponent <MeshRenderer>().sharedMaterial = EditorMaterialUtility.GetUserMaterial(); bezier.Init(); bezier.Refresh(); EditorUtility.InitObject(bezier.GetComponent <ProBuilderMesh>()); MeshSelection.SetSelection(go); UndoUtility.RegisterCreatedObjectUndo(go, "Create Bezier Shape"); bezier.isEditing = true; return(new ActionResult(ActionResult.Status.Success, "Create Bezier Shape")); }
public void Setup() { // make sure the ProBuilder window is open if (ProBuilderEditor.instance == null) { ProBuilderEditor.MenuOpenWindow(); } Assume.That(ProBuilderEditor.instance, Is.Not.Null); m_PBMesh = ShapeGenerator.CreateShape(ShapeType.Plane); MeshSelection.SetSelection(m_PBMesh.gameObject); MeshSelection.OnObjectSelectionChanged(); m_PreviousSelectMode = ProBuilderEditor.selectMode; ProBuilderEditor.selectMode = SelectMode.Object; }
public void Setup() { // make sure the ProBuilder window is open if (ProBuilderEditor.instance == null) { ProBuilderEditor.MenuOpenWindow(); } Assume.That(ProBuilderEditor.instance, Is.Not.Null); m_PBMesh = ShapeFactory.Instantiate(typeof(UnityEngine.ProBuilder.Shapes.Plane)); MeshSelection.SetSelection(m_PBMesh.gameObject); MeshSelection.OnObjectSelectionChanged(); m_PreviousSelectMode = ProBuilderEditor.selectMode; ProBuilderEditor.selectMode = SelectMode.Object; }
protected override ActionResult PerformActionImplementation() { if (!CanCreateNewPolyShape()) { return(new ActionResult(ActionResult.Status.Canceled, "Canceled Create Poly Shape")); } GameObject go = new GameObject("PolyShape"); UndoUtility.RegisterCreatedObjectUndo(go, "Create Poly Shape"); PolyShape poly = Undo.AddComponent <PolyShape>(go); ProBuilderMesh pb = Undo.AddComponent <ProBuilderMesh>(go); pb.CreateShapeFromPolygon(poly.m_Points, poly.extrude, poly.flipNormals); EditorUtility.InitObject(pb); // Special case - we don't want to reset the grid pivot because we rely on it to set the active plane for // interaction, regardless of whether snapping is enabled or not. if (ProGridsInterface.SnapEnabled() || ProGridsInterface.GridVisible()) { Vector3 pivot; if (ProGridsInterface.GetPivot(out pivot)) { go.transform.position = pivot; } } MeshSelection.SetSelection(go); poly.polyEditMode = PolyShape.PolyEditMode.Path; ProBuilderEditor.selectMode = SelectMode.Object; m_Tool = ScriptableObject.CreateInstance <PolyShapeTool>(); ((PolyShapeTool)m_Tool).polygon = poly; ToolManager.SetActiveTool(m_Tool); Undo.RegisterCreatedObjectUndo(m_Tool, "Open PolyShape Tool"); MenuAction.onPerformAction += ActionPerformed; ToolManager.activeToolChanging += LeaveTool; ProBuilderEditor.selectModeChanged += OnSelectModeChanged; MeshSelection.objectSelectionChanged += OnObjectSelectionChanged; return(new ActionResult(ActionResult.Status.Success, "Create Poly Shape")); }
public void SelectFaces_WithColor() { Setup(true /*with color*/); //Make first faces selected ProBuilderMesh mesh = selectables[0]; Assert.IsNotNull(mesh.faces); Face face = selectables[0].faces[0]; List <Face> selectedFaces = new List <Face>(); selectedFaces.Add(face); mesh.SetSelectedFaces(selectedFaces); Assert.AreEqual(mesh.selectedFaceCount, 1); MeshSelection.SetSelection(mesh.gameObject); MeshSelection.OnObjectSelectionChanged(); //Validate that prior only a face on first cube is selected Assert.AreEqual(selectables[0].selectedFacesInternal.Length, 1); Assert.AreEqual(selectables[1].selectedFacesInternal.Length, 0); UnityEditor.ProBuilder.Actions.SelectVertexColor selectColorAction = new UnityEditor.ProBuilder.Actions.SelectVertexColor(); selectColorAction.DoAction(); //Validate that after a face is selected on both cube Color[] colors0 = selectables[0].colorsInternal; Color[] colors1 = selectables[1].colorsInternal; Assert.AreEqual(selectables[0].selectedFacesInternal.Length, 1); Assert.AreEqual(selectables[1].selectedFacesInternal.Length, 1); int[] tris0 = selectables[0].selectedFacesInternal[0].distinctIndexesInternal; int[] tris1 = selectables[1].selectedFacesInternal[0].distinctIndexesInternal; Assert.AreEqual(tris0.Length, tris1.Length); //Validate that the face match for (int n = 0; n < tris0.Length; n++) { Assert.AreEqual(colors0[tris0[n]], colors1[tris1[n]]); Assert.AreEqual(colors0[tris0[n]], faceColors[0]); } }
public static void DetachFaceUndoTest() { var cube = ShapeFactory.Instantiate <Cube>(); var duplicate = UnityEngine.Object.Instantiate(cube.gameObject).GetComponent <ProBuilderMesh>(); duplicate.MakeUnique(); // Select the mesh MeshSelection.SetSelection(cube.gameObject); MeshSelection.OnObjectSelectionChanged(); Assume.That(MeshSelection.selectedObjectCount, Is.EqualTo(1)); // Select a face cube.SetSelectedFaces(new Face[] { cube.facesInternal[0] }); Assume.That(cube.selectedFacesInternal.Length, Is.EqualTo(1)); // Perform `Detach Faces` action var detachAction = new DetachFaces(); var result = detachAction.PerformAction(); Assume.That(result.status, Is.EqualTo(ActionResult.Status.Success)); UnityEditor.Undo.PerformUndo(); // this is usually caught by UndoUtility cube.InvalidateCaches(); cube.ToMesh(); cube.Refresh(); // After undo, previously edited mesh should match the duplicate TestUtility.AssertAreEqual(duplicate.mesh, cube.mesh); UnityEngine.Object.DestroyImmediate(cube.gameObject); UnityEngine.Object.DestroyImmediate(duplicate.gameObject); }
public void CollapseVertices_SelectSharedVertex_ActionDisabled() { Assert.That(m_PBMesh, Is.Not.Null); var sharedVertices = m_PBMesh.sharedVerticesInternal; Assert.That(sharedVertices, Is.Not.Null); Assert.That(sharedVertices.Length, Is.GreaterThanOrEqualTo(1)); var sharedVertex = sharedVertices[0]; Assert.That(sharedVertex.Count, Is.GreaterThan(1)); // Set the selected vertices to all vertices belonging to a single shared vertex m_PBMesh.SetSelectedVertices(sharedVertex); Assert.That(m_PBMesh.selectedIndexesInternal.Length, Is.EqualTo(sharedVertex.Count)); MeshSelection.SetSelection(m_PBMesh.gameObject); MeshSelection.OnObjectSelectionChanged(); UnityEditor.ProBuilder.Actions.CollapseVertices collapseVertices = new UnityEditor.ProBuilder.Actions.CollapseVertices(); Assert.That(collapseVertices.enabled, Is.False); }
public override ActionResult DoAction() { Vector3 scale = new Vector3( (m_MirrorAxes & MirrorSettings.X) > 0 ? -1f : 1f, (m_MirrorAxes & MirrorSettings.Y) > 0 ? -1f : 1f, (m_MirrorAxes & MirrorSettings.Z) > 0 ? -1f : 1f); bool duplicate = (m_MirrorAxes & MirrorSettings.Duplicate) > 0; List <GameObject> res = new List <GameObject>(); foreach (ProBuilderMesh pb in MeshSelection.topInternal) { res.Add(Mirror(pb, scale, duplicate).gameObject); } MeshSelection.SetSelection(res); ProBuilderEditor.Refresh(); return(res.Count > 0 ? new ActionResult(ActionResult.Status.Success, string.Format("Mirror {0} {1}", res.Count, res.Count > 1 ? "Objects" : "Object")) : new ActionResult(ActionResult.Status.NoChange, "No Objects Selected")); }
static ActionResult DuplicateFacesToObject() { int duplicatedFaceCount = 0; List <GameObject> duplicated = new List <GameObject>(); foreach (ProBuilderMesh mesh in MeshSelection.topInternal) { if (mesh.selectedFaceCount < 1) { continue; } var primary = mesh.selectedFaceIndexes; duplicatedFaceCount += primary.Count; List <int> inverse = new List <int>(); for (int i = 0; i < mesh.facesInternal.Length; i++) { if (!primary.Contains(i)) { inverse.Add(i); } } ProBuilderMesh copy = Object.Instantiate(mesh.gameObject, mesh.transform.parent).GetComponent <ProBuilderMesh>(); EditorUtility.SynchronizeWithMeshFilter(copy); if (copy.transform.childCount > 0) { for (int i = copy.transform.childCount - 1; i > -1; i--) { Object.DestroyImmediate(copy.transform.GetChild(i).gameObject); } foreach (var child in mesh.transform.GetComponentsInChildren <ProBuilderMesh>()) { EditorUtility.SynchronizeWithMeshFilter(child); } } Undo.RegisterCreatedObjectUndo(copy.gameObject, "Duplicate Selection"); copy.DeleteFaces(inverse); copy.Rebuild(); copy.Optimize(); mesh.ClearSelection(); copy.ClearSelection(); copy.SetSelectedFaces(copy.faces); copy.gameObject.name = GameObjectUtility.GetUniqueNameForSibling(mesh.transform.parent, mesh.gameObject.name); duplicated.Add(copy.gameObject); } MeshSelection.SetSelection(duplicated); ProBuilderEditor.Refresh(); if (duplicatedFaceCount > 0) { return(new ActionResult(ActionResult.Status.Success, "Duplicate " + duplicatedFaceCount + " faces to new Object")); } return(new ActionResult(ActionResult.Status.Failure, "No Faces Selected")); }
public static IEnumerator ExtrudeOrthogonally_OneElementManyTimes_NoYOffsetAccumulates() { // Generate single face plane var pb = ShapeGenerator.GeneratePlane(PivotLocation.Center, 1f, 1f, 0, 0, Axis.Up); try { pb.transform.position = Vector3.zero; pb.transform.rotation = Quaternion.identity; ProBuilderEditor.MenuOpenWindow(); EditorApplication.ExecuteMenuItem("Window/General/Scene"); var sceneView = UnityEngine.Resources.FindObjectsOfTypeAll <UnityEditor.SceneView>()[0]; sceneView.orthographic = true; sceneView.drawGizmos = false; sceneView.pivot = new Vector3(0, 0, 0); sceneView.rotation = Quaternion.AngleAxis(90f, Vector3.right); sceneView.size = 2.0f; sceneView.Focus(); var e = new Event(); e.type = EventType.MouseEnterWindow; sceneView.SendEvent(e); Assume.That(pb.facesInternal.Length, Is.EqualTo(1)); var face = pb.facesInternal[0]; // Select face var selectedFaces = new List <Face>(); selectedFaces.Add(face); Tools.current = Tool.Move; ProBuilderEditor.toolManager.SetSelectMode(SelectMode.Face); pb.SetSelectedFaces(selectedFaces); MeshSelection.SetSelection(pb.gameObject); // Center mouse position var bounds = SceneView.focusedWindow.rootVisualElement.worldBound; var mousePos = (bounds.size * 0.5f + bounds.position) + new Vector2Int(1, 1); e = new UnityEngine.Event() { type = EventType.MouseDown, mousePosition = mousePos, modifiers = EventModifiers.None, clickCount = 1, delta = Vector2.zero, }; sceneView.SendEvent(e); e = new UnityEngine.Event() { type = EventType.MouseUp, mousePosition = mousePos, modifiers = EventModifiers.None, clickCount = 0, delta = Vector2.zero, }; sceneView.SendEvent(e); yield return(null); const int k_ExtrudeCount = 100; for (int i = 0; i < k_ExtrudeCount; i++) { // Press down at the center of the face e = new UnityEngine.Event() { type = EventType.MouseDown, mousePosition = mousePos, modifiers = EventModifiers.None, clickCount = 1, delta = Vector2.zero, }; sceneView.SendEvent(e); // Do lateral 1px drag and release var mouseDelta = new Vector2(i % 2 == 0 ? 1f : -1f, 0f); mousePos += mouseDelta; e.type = EventType.MouseDrag; e.mousePosition = mousePos; e.modifiers = EventModifiers.Shift; e.clickCount = 0; e.delta = mouseDelta; sceneView.SendEvent(e); e.type = EventType.MouseUp; e.mousePosition = mousePos; e.delta = Vector2.zero; sceneView.SendEvent(e); yield return(null); } // Check that our face count is correct after all extrusions Assume.That(pb.facesInternal.Length, Is.EqualTo(k_ExtrudeCount * 4 + 1)); // We should have the last extruded face in selection var postExtrudeSelectedFaces = pb.GetSelectedFaces(); Assume.That(postExtrudeSelectedFaces.Length, Is.EqualTo(1)); var lastExtrudedFace = postExtrudeSelectedFaces[0]; var faceVertices = pb.GetVertices(lastExtrudedFace.indexes); // After many orthogonal extrusions, the last face should still be at y=0 coordinate for (int i = 0; i < faceVertices.Length; i++) { Assert.That(faceVertices[i].position.y, Is.EqualTo(0f)); } } finally { UObject.DestroyImmediate(pb.gameObject); } }
static ActionResult DetachFacesToObject() { int detachedFaceCount = 0; List <GameObject> detached = new List <GameObject>(); foreach (ProBuilderMesh mesh in MeshSelection.topInternal) { if (mesh.selectedFaceCount < 1 || mesh.selectedFaceCount == mesh.facesInternal.Length) { continue; } var primary = mesh.selectedFaceIndexes; detachedFaceCount += primary.Count; List <int> inverse = new List <int>(); for (int i = 0; i < mesh.facesInternal.Length; i++) { if (!primary.Contains(i)) { inverse.Add(i); } } ProBuilderMesh copy = Object.Instantiate(mesh.gameObject, mesh.transform.parent).GetComponent <ProBuilderMesh>(); EditorUtility.SynchronizeWithMeshFilter(copy); #if !UNITY_2018_3_OR_NEWER // if is prefab, break connection and destroy children if (EditorUtility.IsPrefabInstance(copy.gameObject) || EditorUtility.IsPrefabAsset(copy.gameObject)) { PrefabUtility.DisconnectPrefabInstance(copy.gameObject); } #endif if (copy.transform.childCount > 0) { for (int i = copy.transform.childCount - 1; i > -1; i--) { Object.DestroyImmediate(copy.transform.GetChild(i).gameObject); } foreach (var child in mesh.transform.GetComponentsInChildren <ProBuilderMesh>()) { EditorUtility.SynchronizeWithMeshFilter(child); } } Undo.RegisterCreatedObjectUndo(copy.gameObject, "Detach Selection"); mesh.DeleteFaces(primary); copy.DeleteFaces(inverse); mesh.Rebuild(); copy.Rebuild(); mesh.Optimize(); copy.Optimize(); mesh.ClearSelection(); copy.ClearSelection(); copy.SetSelectedFaces(copy.faces); copy.gameObject.name = GameObjectUtility.GetUniqueNameForSibling(mesh.transform.parent, mesh.gameObject.name);; detached.Add(copy.gameObject); } MeshSelection.SetSelection(detached); ProBuilderEditor.Refresh(); if (detachedFaceCount > 0) { return(new ActionResult(ActionResult.Status.Success, "Detach " + detachedFaceCount + " faces to new Object")); } return(new ActionResult(ActionResult.Status.Failure, "No Faces Selected")); }