private static void SetScale(Vector2 scale, Axis2D axis, ProBuilderMesh[] sel) { UndoUtility.RecordSelection(sel, "Scale UVs"); for (int i = 0; i < sel.Length; i++) { foreach (Face q in sel[i].GetSelectedFaces()) { switch (axis) { case Axis2D.XY: { var uv = q.uv; uv.scale = scale; q.uv = uv; break; } case Axis2D.X: { var uv = q.uv; uv.scale = new Vector2(scale.x, q.uv.scale.y); q.uv = uv; break; } case Axis2D.Y: { var uv = q.uv; uv.scale = new Vector2(q.uv.scale.x, scale.y); q.uv = uv; break; } } sel[i].SetGroupUV(q.uv, q.textureGroup); } } }
private static void SetOffset(Vector2 offset, Axis2D axis, ProBuilderMesh[] sel) { UndoUtility.RecordSelection(sel, "Offset UVs"); for (int i = 0; i < sel.Length; i++) { foreach (Face q in sel[i].GetSelectedFaces()) { switch (axis) { case Axis2D.XY: { var uv = q.uv; uv.offset = offset; q.uv = uv; break; } case Axis2D.X: { var uv = q.uv; uv.offset = new Vector2(offset.x, q.uv.offset.y); q.uv = uv; break; } case Axis2D.Y: { var uv = q.uv; uv.offset = new Vector2(q.uv.offset.x, offset.y); q.uv = uv; break; } } sel[i].SetGroupUV(q.uv, q.textureGroup); } } }
protected void BeginEdit(string undoMessage) { if (m_IsEditing) { return; } // Disable iterative lightmapping Lightmapping.PushGIWorkflowMode(); var selection = MeshSelection.topInternal.ToArray(); UndoUtility.RegisterCompleteObjectUndo(selection, string.IsNullOrEmpty(undoMessage) ? "Modify Vertices" : undoMessage); if (beforeMeshModification != null) { beforeMeshModification(selection); } if (currentEvent.shift) { Extrude(); } m_IsEditing = true; m_WorldSnapEnabled = ProBuilderSnapSettings.snapMode == SnapMode.World; m_SnapAxisConstraint = ProBuilderSnapSettings.snapMethod == SnapAxis.ActiveAxis; ProGridsInterface.UseAxisConstraints(); m_MoveSnapValue = m_WorldSnapEnabled ? ProBuilderSnapSettings.worldSnapMoveValue : ProBuilderSnapSettings.incrementalSnapMoveValue; foreach (var mesh in selection) { mesh.ToMesh(); mesh.Refresh(); } OnToolEngaged(); }
void DeselectAll() { if (MeshSelection.selectedObjectCount < 1) { return; } UndoUtility.RecordSelection("Deselect All"); switch (selectMode) { case SelectMode.Vertex: foreach (var mesh in MeshSelection.topInternal) { mesh.SetSelectedVertices(null); } break; case SelectMode.Face: case SelectMode.TextureFace: foreach (var mesh in MeshSelection.topInternal) { mesh.SetSelectedFaces((IEnumerable <Face>)null); } break; case SelectMode.Edge: foreach (var mesh in MeshSelection.topInternal) { mesh.SetSelectedEdges(null); } break; } Refresh(); SceneView.RepaintAll(); }
public void CreateLastShape() { var shape = ShapeFactory.Instantiate(DrawShapeTool.activeShapeType, (PivotLocation)DrawShapeTool.s_LastPivotLocation.value).GetComponent <ShapeComponent>(); shape.gameObject.name = shape.gameObject.name + "-Copy"; DrawShapeTool.ApplyPrefsSettings(shape); UndoUtility.RegisterCreatedObjectUndo(shape.gameObject, "Create Shape Copy"); EditorShapeUtility.CopyLastParams(shape.shape, shape.shape.GetType()); shape.Rebuild(tool.m_Bounds, tool.m_PlaneRotation); ProBuilderEditor.Refresh(false); tool.m_ShapeComponent = null; tool.m_LastShapeCreated = shape; if (tool.m_DuplicateGO != null) { GameObject.DestroyImmediate(tool.m_DuplicateGO); } MeshSelection.SetSelection(shape.gameObject); }
private static void SetRotation(float rot, ProBuilderMesh[] sel) { UndoUtility.RecordSelection(sel, "Rotate UVs"); for (int i = 0; i < sel.Length; i++) { foreach (Face q in sel[i].GetSelectedFaces()) { var uv = q.uv; uv.rotation = rot; if (uv.rotation > 360f) { uv.rotation = uv.rotation % 360f; } else if (uv.rotation < 0f) { uv.rotation = 360f + (uv.rotation % 360f); } q.uv = uv; sel[i].SetGroupUV(uv, q.textureGroup); } } }
internal static void SetSelection(IList <GameObject> newSelection) { UndoUtility.RecordSelection(topInternal.ToArray(), "Change Selection"); ClearElementAndObjectSelection(); // if the previous tool was set to none, use Tool.Move if (Tools.current == Tool.None) { Tools.current = Tool.Move; } var newCount = newSelection != null ? newSelection.Count : 0; if (newCount > 0) { Selection.activeTransform = newSelection[newCount - 1].transform; Selection.objects = newSelection.ToArray(); } else { Selection.activeTransform = null; } }
static void ApplyMaterial(IEnumerable <ProBuilderMesh> selection, Material mat) { if (mat == null) { return; } UndoUtility.RecordComponents <MeshRenderer, ProBuilderMesh>(selection, "Set Material"); foreach (var mesh in selection) { var applyPerFace = ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Face) && mesh.faceCount > 0; mesh.SetMaterial(applyPerFace ? mesh.GetSelectedFaces() : mesh.facesInternal, mat); InternalMeshUtility.FilterUnusedSubmeshIndexes(mesh); mesh.Rebuild(); mesh.Optimize(); } if (ProBuilderEditor.instance != null && MeshSelection.selectedFaceCount > 0) { EditorUtility.ShowNotification("Set Material\n" + mat.name); } }
internal void RebuildShape() { RecalculateBounds(); if (m_Bounds.size.sqrMagnitude < .01f || Mathf.Abs(m_Bounds.extents.x) < 0.001f || Mathf.Abs(m_Bounds.extents.z) < 0.001f) { if (m_ProBuilderShape != null && m_ProBuilderShape.mesh.vertexCount > 0) { m_ProBuilderShape.mesh.Clear(); m_ProBuilderShape.mesh.Rebuild(); ProBuilderEditor.Refresh(true); } return; } if (!m_IsShapeInit) { var shapeComponent = currentShapeInOverlay; EditorShapeUtility.CopyLastParams(shapeComponent.shape, shapeComponent.shape.GetType()); shapeComponent.gameObject.hideFlags = HideFlags.HideInHierarchy; shapeComponent.mesh.renderer.sharedMaterial = EditorMaterialUtility.GetUserMaterial(); shapeComponent.rotation = Quaternion.identity; shapeComponent.gameObject.name = EditorShapeUtility.GetName(shapeComponent.shape); UndoUtility.RegisterCreatedObjectUndo(shapeComponent.gameObject, "Draw Shape"); EditorUtility.InitObject(shapeComponent.mesh); m_IsShapeInit = true; } m_ProBuilderShape.Rebuild(m_Bounds, m_PlaneRotation, m_BB_Origin); ProBuilderEditor.Refresh(false); SceneView.RepaintAll(); }
protected void BeginEdit(string undoMessage) { if (m_IsEditing) { return; } // Disable iterative lightmapping Lightmapping.PushGIWorkflowMode(); var selection = MeshSelection.topInternal.ToArray(); UndoUtility.RegisterCompleteObjectUndo(selection, string.IsNullOrEmpty(undoMessage) ? "Modify Vertices" : undoMessage); if (beforeMeshModification != null) { beforeMeshModification(selection); } if (currentEvent.shift) { Extrude(); } m_IsEditing = true; m_SnapAxisConstraint = EditorSnapping.snapMethod == SnapAxis.ActiveAxis; foreach (var mesh in selection) { mesh.ToMesh(); mesh.Refresh(); } OnToolEngaged(); }
void DoPointPlacement() { Event evt = Event.current; EventType eventType = evt.type; if (m_PlacingPoint) { Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (eventType == EventType.MouseDrag) { float hitDistance = Mathf.Infinity; if (plane.Raycast(ray, out hitDistance)) { evt.Use(); polygon.m_Points[m_SelectedIndex] = GetPointInLocalSpace(ray.GetPoint(hitDistance)); RebuildPolyShapeMesh(false); SceneView.RepaintAll(); } } if (eventType == EventType.MouseUp || eventType == EventType.Ignore || eventType == EventType.KeyDown || eventType == EventType.KeyUp) { evt.Use(); m_PlacingPoint = false; m_SelectedIndex = -1; SceneView.RepaintAll(); } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Path) { if (eventType == EventType.MouseDown && HandleUtility.nearestControl == m_ControlId) { if (polygon.m_Points.Count < 1) { SetupInputPlane(evt.mousePosition); } float hitDistance = Mathf.Infinity; Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (plane.Raycast(ray, out hitDistance)) { UndoUtility.RecordObject(polygon, "Add Polygon Shape Point"); Vector3 hit = ray.GetPoint(hitDistance); if (polygon.m_Points.Count < 1) { // this monstrosity exists so that grid and incremental snap work when possible, and // incremental is enabled when grid is not available. polygon.transform.position = m_Polygon.isOnGrid ? EditorSnapping.MoveSnap(hit) : EditorSnapping.snapMode == SnapMode.Relative ? ProBuilderSnapping.Snap(hit, EditorSnapping.incrementalSnapMoveValue) : hit; Vector3 cameraFacingPlaneNormal = plane.normal; if (Vector3.Dot(cameraFacingPlaneNormal, SceneView.lastActiveSceneView.camera.transform.forward) > 0f) { cameraFacingPlaneNormal *= -1; } polygon.transform.rotation = Quaternion.LookRotation(cameraFacingPlaneNormal) * Quaternion.Euler(new Vector3(90f, 0f, 0f)); } Vector3 point = GetPointInLocalSpace(hit); if (polygon.m_Points.Count > 2 && Math.Approx3(polygon.m_Points[0], point)) { m_NextMouseUpAdvancesMode = true; return; } polygon.m_Points.Add(point); m_PlacingPoint = true; m_SelectedIndex = polygon.m_Points.Count - 1; RebuildPolyShapeMesh(polygon); evt.Use(); } } else { float hitDistance = Mathf.Infinity; Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (plane.Raycast(ray, out hitDistance)) { Vector3 hit = ray.GetPoint(hitDistance); m_CurrentPosition = GetPointInLocalSpace(hit); } } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Edit) { if (polygon.m_Points.Count < 3) { SetPolyEditMode(PolyShape.PolyEditMode.Path); return; } if (m_DistanceFromHeightHandle > PreferenceKeys.k_MaxPointDistanceFromControl) { // point insertion Vector2 mouse = evt.mousePosition; Ray ray = HandleUtility.GUIPointToWorldRay(mouse); float hitDistance = Mathf.Infinity; if (plane.Raycast(ray, out hitDistance)) { Vector3 hit = ray.GetPoint(hitDistance); Vector3 point = GetPointInLocalSpace(hit); int polyCount = polygon.m_Points.Count; float distToLineInGUI; int index; Vector3 pInGUI = EditorHandleUtility.ClosestPointToPolyLine(polygon.m_Points, out index, out distToLineInGUI, true, polygon.transform); Vector3 aToPoint = point - polygon.m_Points[index - 1]; Vector3 aToB = polygon.m_Points[index % polyCount] - polygon.m_Points[index - 1]; float ratio = Vector3.Dot(aToPoint, aToB.normalized) / aToB.magnitude; Vector3 wp = Vector3.Lerp(polygon.m_Points[index - 1], polygon.m_Points[index % polyCount], ratio); wp = polygon.transform.TransformPoint(wp); Vector2 aInGUI = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[index - 1])); Vector2 bInGUI = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[index % polyCount])); float distanceToVertex = Mathf.Min(Vector2.Distance(mouse, aInGUI), Vector2.Distance(mouse, bInGUI)); if (distanceToVertex > PreferenceKeys.k_MaxPointDistanceFromControl && distToLineInGUI < PreferenceKeys.k_MaxPointDistanceFromControl) { m_MouseCursor = MouseCursor.ArrowPlus; if (evt.type == EventType.Repaint) { Handles.color = Color.green; Handles.DotHandleCap(-1, wp, Quaternion.identity, HandleUtility.GetHandleSize(wp) * k_HandleSize, evt.type); } if (evt.type == EventType.MouseDown && HandleUtility.nearestControl == m_ControlId) { evt.Use(); UndoUtility.RecordObject(polygon, "Insert Point"); polygon.m_Points.Insert(index, point); m_SelectedIndex = index; m_PlacingPoint = true; RebuildPolyShapeMesh(true); OnBeginVertexMovement(); } Handles.color = Color.white; } if (evt.type != EventType.Repaint) { SceneView.RepaintAll(); } } } } }
internal static void OnObjectSelectionChanged() { // GameObjects returns both parent and child when both are selected, where transforms only returns the // top-most transform. s_UnitySelectionChangeMeshes.Clear(); s_ElementSelection.Clear(); s_ActiveMesh = null; var gameObjects = Selection.gameObjects; for (int i = 0, c = gameObjects.Length; i < c; i++) { #if UNITY_2019_3_OR_NEWER ProBuilderMesh mesh; if (gameObjects[i].TryGetComponent <ProBuilderMesh>(out mesh)) #else var mesh = gameObjects[i].GetComponent <ProBuilderMesh>(); if (mesh != null) #endif { if (gameObjects[i] == Selection.activeGameObject) { s_ActiveMesh = mesh; } s_UnitySelectionChangeMeshes.Add(mesh); } } for (int i = 0, c = s_TopSelection.Count; i < c; i++) { if (!s_UnitySelectionChangeMeshes.Contains(s_TopSelection[i])) { if (s_TopSelection[i] != null) { UndoUtility.RecordSelection(s_TopSelection[i], "Selection Change"); } s_TopSelection[i].ClearSelection(); } } s_TopSelection.Clear(); foreach (var mesh in s_UnitySelectionChangeMeshes) { // don't add prefabs or assets to the mesh selection if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(mesh.gameObject))) { EditorUtility.SynchronizeWithMeshFilter(mesh); s_TopSelection.Add(mesh); } } InvalidateCaches(); if (objectSelectionChanged != null) { objectSelectionChanged(); } s_UnitySelectionChangeMeshes.Clear(); }
/// <summary> /// Overlay GUI /// </summary> /// <param name="target">the target of this overlay</param> /// <param name="view">the current SceneView where to display the overlay</param> void OnOverlayGUI(UObject target, SceneView view) { var currentPolygon = polygon; if (currentPolygon == null) { return; } switch (currentPolygon.polyEditMode) { case PolyShape.PolyEditMode.Path: { EditorGUILayout.HelpBox("Click To Add Points\nPress 'Enter' or 'Space' to Set Height", MessageType.Info); break; } case PolyShape.PolyEditMode.Height: { EditorGUILayout.HelpBox("Move Mouse to Set Height\nPress 'Enter' or 'Space' to Finalize", MessageType.Info); break; } case PolyShape.PolyEditMode.Edit: { if (GUILayout.Button("Quit Editing", UI.EditorGUIUtility.GetActiveStyle("Button"))) { LeaveTool(); } EditorGUILayout.HelpBox("Move Poly Shape points to update the shape\nPress 'Enter' or 'Space' to Finalize", MessageType.Info); break; } } EditorGUI.BeginChangeCheck(); float extrude = currentPolygon.extrude; extrude = EditorGUILayout.FloatField("Extrusion", extrude); bool flipNormals = currentPolygon.flipNormals; flipNormals = EditorGUILayout.Toggle("Flip Normals", flipNormals); if (EditorGUI.EndChangeCheck()) { if (currentPolygon.polyEditMode == PolyShape.PolyEditMode.None) { if (ProBuilderEditor.instance != null) { ProBuilderEditor.instance.ClearElementSelection(); } UndoUtility.RecordObject(currentPolygon, "Change Polygon Shape Settings"); UndoUtility.RecordObject(currentPolygon.mesh, "Change Polygon Shape Settings"); } else { UndoUtility.RecordObject(currentPolygon, "Change Polygon Shape Settings"); } currentPolygon.extrude = extrude; currentPolygon.flipNormals = flipNormals; RebuildPolyShapeMesh(currentPolygon); } }
public override void OnInspectorGUI() { switch (polygon.polyEditMode) { case PolyShape.PolyEditMode.None: { if (GUILayout.Button("Edit Poly Shape")) { ProBuilderEditor.selectMode = SelectMode.Object; polygon.polyEditMode = PolyShape.PolyEditMode.Edit; PolyShapeTool tool = CreateInstance <PolyShapeTool>(); tool.polygon = polygon; ToolManager.SetActiveTool(tool); Undo.RegisterCreatedObjectUndo(tool, "Open Polyshape Tool"); } EditorGUILayout.HelpBox( "Editing a poly shape will erase any modifications made to the mesh!\n\nIf you accidentally enter Edit Mode you can Undo to get your changes back.", MessageType.Warning); break; } case PolyShape.PolyEditMode.Path: { EditorGUILayout.HelpBox("\nClick To Add Points\n\nPress 'Enter' or 'Space' to Set Height\n", MessageType.Info); break; } case PolyShape.PolyEditMode.Height: { EditorGUILayout.HelpBox("\nMove Mouse to Set Height\n\nPress 'Enter' or 'Space' to Finalize\n", MessageType.Info); break; } case PolyShape.PolyEditMode.Edit: { EditorGUILayout.HelpBox("\nMove Poly Shape points to update the shape\n\nPress 'Enter' or 'Space' to Finalize\n", MessageType.Info); break; } } EditorGUI.BeginChangeCheck(); float extrude = polygon.extrude; extrude = EditorGUILayout.FloatField("Extrusion", extrude); bool flipNormals = polygon.flipNormals; flipNormals = EditorGUILayout.Toggle("Flip Normals", flipNormals); if (EditorGUI.EndChangeCheck()) { if (polygon.polyEditMode == PolyShape.PolyEditMode.None) { if (ProBuilderEditor.instance != null) { ProBuilderEditor.instance.ClearElementSelection(); } UndoUtility.RecordComponents <ProBuilderMesh, PolyShape>(polygon.GetComponents(typeof(Component)), "Edit Polygon Shape"); } else { UndoUtility.RecordObject(polygon, "Change Polygon Shape Settings"); } polygon.extrude = extrude; polygon.flipNormals = flipNormals; RebuildPolyShapeMesh(polygon); } }
internal static void SetSelection(GameObject go) { UndoUtility.RecordSelection(topInternal.ToArray(), "Change Selection"); ClearElementAndObjectSelection(); AddToSelection(go); }
void OnGUI() { GUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.FlexibleSpace(); GUIStyle style = m_WorldSpace ? EditorStyles.toolbarButton : UI.EditorGUIUtility.GetOnStyle(EditorStyles.toolbarButton); if (GUILayout.Button(m_WorldSpace ? "World Space" : "Model Space", style)) { m_WorldSpace = !m_WorldSpace; } GUILayout.EndHorizontal(); if (m_Selection == null || m_Selection.Count < 1 || !m_Selection.Any(x => x.Key.selectedVertexCount > 0)) { GUILayout.FlexibleSpace(); GUILayout.Label("Select a ProBuilder Mesh", UI.EditorGUIUtility.CenteredGreyMiniLabel); GUILayout.FlexibleSpace(); return; } Event e = Event.current; if (m_IsActive) { if (e.type == EventType.Ignore || e.type == EventType.MouseUp) { OnVertexMovementFinish(); } } m_Scroll = EditorGUILayout.BeginScrollView(m_Scroll); foreach (var kvp in m_Selection) { ProBuilderMesh mesh = kvp.Key; VertexEditorSelection sel = kvp.Value; bool open = sel.isVisible; EditorGUI.BeginChangeCheck(); open = EditorGUILayout.Foldout(open, mesh.name); if (EditorGUI.EndChangeCheck()) { sel.isVisible = open; } if (open) { int index = 0; bool wasWideMode = EditorGUIUtility.wideMode; EditorGUIUtility.wideMode = true; Color background = GUI.backgroundColor; Transform transform = mesh.transform; foreach (int u in sel.common) { GUI.backgroundColor = index % 2 == 0 ? s_EvenColor : s_OddColor; GUILayout.BeginHorizontal(UI.EditorGUIUtility.solidBackgroundStyle); GUI.backgroundColor = background; GUILayout.Label(u.ToString(), GUILayout.MinWidth(32), GUILayout.MaxWidth(32)); Vector3 v = mesh.positionsInternal[mesh.sharedVerticesInternal[u][0]]; if (m_WorldSpace) { v = transform.TransformPoint(v); } EditorGUI.BeginChangeCheck(); v = EditorGUILayout.Vector3Field("", v); if (EditorGUI.EndChangeCheck()) { if (!m_IsActive) { OnVertexMovementBegin(mesh); } UndoUtility.RecordObject(mesh, "Set Vertex Postion"); mesh.SetSharedVertexPosition(u, m_WorldSpace ? transform.InverseTransformPoint(v) : v); if (ProBuilderEditor.instance != null) { mesh.RefreshUV(MeshSelection.selectedFacesInEditZone[mesh]); mesh.Refresh(RefreshMask.Normals); mesh.mesh.RecalculateBounds(); ProBuilderEditor.Refresh(); } } index++; GUILayout.EndHorizontal(); } GUI.backgroundColor = background; EditorGUIUtility.wideMode = wasWideMode; } } EditorGUILayout.EndScrollView(); }
public static ProBuilderMesh DoMouseClick(Event evt, SelectMode selectionMode, ScenePickerPreferences pickerPreferences) { bool appendModifier = EditorHandleUtility.IsAppendModifier(evt.modifiers); if (!appendModifier) { MeshSelection.SetSelection((GameObject)null); } float pickedElementDistance = Mathf.Infinity; if (selectionMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge)) { pickedElementDistance = EdgeRaycast(evt.mousePosition, pickerPreferences, true, s_Selection); } else if (selectionMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex)) { pickedElementDistance = VertexRaycast(evt.mousePosition, pickerPreferences, true, s_Selection); } else { pickedElementDistance = FaceRaycast(evt.mousePosition, pickerPreferences, true, s_Selection, evt.clickCount > 1 ? -1 : 0, false); } evt.Use(); if (pickedElementDistance > pickerPreferences.maxPointerDistance) { if (appendModifier && Selection.gameObjects.Contains(s_Selection.gameObject)) { MeshSelection.RemoveFromSelection(s_Selection.gameObject); } else { MeshSelection.AddToSelection(s_Selection.gameObject); } return(null); } MeshSelection.AddToSelection(s_Selection.gameObject); if (s_Selection.mesh != null) { var mesh = s_Selection.mesh; if (s_Selection.face != null) { // Check for other editor mouse shortcuts first (todo proper event handling for mouse shortcuts) MaterialEditor matEditor = MaterialEditor.instance; if (matEditor != null && matEditor.ClickShortcutCheck(Event.current.modifiers, mesh, s_Selection.face)) { return(null); } UVEditor uvEditor = UVEditor.instance; if (uvEditor != null && uvEditor.ClickShortcutCheck(mesh, s_Selection.face)) { return(null); } var faces = mesh.faces as Face[] ?? mesh.faces.ToArray(); var ind = Array.IndexOf <Face>(faces, s_Selection.face); var sel = mesh.selectedFaceIndexes.IndexOf(ind); UndoUtility.RecordSelection(mesh, "Select Face"); if (sel > -1) { mesh.RemoveFromFaceSelectionAtIndex(sel); } else { mesh.AddToFaceSelection(ind); } } else if (s_Selection.edge != Edge.Empty) { int ind = mesh.IndexOf(mesh.selectedEdges, s_Selection.edge); UndoUtility.RecordSelection(mesh, "Select Edge"); if (ind > -1) { mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().RemoveAt(ind)); } else { mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().Add(s_Selection.edge)); } } else if (s_Selection.vertex > -1) { int ind = Array.IndexOf(mesh.selectedIndexesInternal, s_Selection.vertex); UndoUtility.RecordSelection(mesh, "Select Vertex"); if (ind > -1) { mesh.SetSelectedVertices(mesh.selectedIndexesInternal.RemoveAt(ind)); } else { mesh.SetSelectedVertices(mesh.selectedIndexesInternal.Add(s_Selection.vertex)); } } return(mesh); } return(null); }
public static void SetFaceColors(Color col) { col = PlayerSettings.colorSpace == ColorSpace.Linear ? col.linear : col; ProBuilderMesh[] selection = InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms); UndoUtility.RecordSelection(selection, "Apply Vertex Colors"); ProBuilderEditor editor = ProBuilderEditor.instance; if (editor && ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.Edge | SelectMode.Face)) { switch (ProBuilderEditor.selectMode) { case SelectMode.Face: case SelectMode.TextureFace: foreach (ProBuilderMesh mesh in selection) { Color[] colors = mesh.GetColors(); foreach (int i in mesh.selectedIndexesInternal) { colors[i] = col; } mesh.colors = colors; } break; case SelectMode.Edge: case SelectMode.Vertex: foreach (var mesh in selection) { Color[] colors = mesh.GetColors(); foreach (int i in mesh.GetCoincidentVertices(mesh.selectedIndexesInternal)) { colors[i] = col; } mesh.colors = colors; } break; } } else { foreach (ProBuilderMesh pb in selection) { foreach (Face face in pb.facesInternal) { pb.SetFaceColor(face, col); } } } foreach (ProBuilderMesh pb in selection) { pb.ToMesh(); pb.Refresh(); pb.Optimize(); } EditorUtility.ShowNotification("Set Vertex Colors\n" + ColorUtility.GetColorName(col)); }
void DoPointPlacement() { Event evt = Event.current; EventType eventType = evt.type; if (m_PlacingPoint) { Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (eventType == EventType.MouseDrag) { float hitDistance = Mathf.Infinity; if (m_Plane.Raycast(ray, out hitDistance)) { evt.Use(); polygon.m_Points[m_SelectedIndex] = ProGridsInterface.ProGridsSnap(polygon.transform.InverseTransformPoint(ray.GetPoint(hitDistance)), Vector3.one); RebuildPolyShapeMesh(false); SceneView.RepaintAll(); } } if (eventType == EventType.MouseUp || eventType == EventType.Ignore || eventType == EventType.KeyDown || eventType == EventType.KeyUp) { evt.Use(); m_PlacingPoint = false; m_SelectedIndex = -1; SceneView.RepaintAll(); } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Path) { if (eventType == EventType.MouseDown) { if (polygon.m_Points.Count < 1) { SetupInputPlane(evt.mousePosition); } float hitDistance = Mathf.Infinity; Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (m_Plane.Raycast(ray, out hitDistance)) { UndoUtility.RecordObject(polygon, "Add Polygon Shape Point"); Vector3 hit = ray.GetPoint(hitDistance); if (polygon.m_Points.Count < 1) { polygon.transform.position = polygon.isOnGrid ? ProGridsInterface.ProGridsSnap(hit) : hit; polygon.transform.rotation = Quaternion.LookRotation(m_Plane.normal) * Quaternion.Euler(new Vector3(90f, 0f, 0f)); } Vector3 point = ProGridsInterface.ProGridsSnap(polygon.transform.InverseTransformPoint(hit), Vector3.one); if (polygon.m_Points.Count > 2 && Math.Approx3(polygon.m_Points[0], point)) { m_NextMouseUpAdvancesMode = true; return; } polygon.m_Points.Add(point); m_PlacingPoint = true; m_SelectedIndex = polygon.m_Points.Count - 1; RebuildPolyShapeMesh(polygon); evt.Use(); } } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Edit) { if (polygon.m_Points.Count < 3) { SetPolyEditMode(PolyShape.PolyEditMode.Path); return; } if (m_DistanceFromHeightHandle > PreferenceKeys.k_MaxPointDistanceFromControl) { // point insertion int index; float distanceToLine; Vector3 p = EditorHandleUtility.ClosestPointToPolyLine(polygon.m_Points, out index, out distanceToLine, true, polygon.transform); Vector3 wp = polygon.transform.TransformPoint(p); Vector2 ga = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[index % polygon.m_Points.Count])); Vector2 gb = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[(index - 1)])); Vector2 mouse = evt.mousePosition; float distanceToVertex = Mathf.Min(Vector2.Distance(mouse, ga), Vector2.Distance(mouse, gb)); if (distanceToVertex > PreferenceKeys.k_MaxPointDistanceFromControl && distanceToLine < PreferenceKeys.k_MaxPointDistanceFromControl) { Handles.color = Color.green; Handles.DotHandleCap(-1, wp, Quaternion.identity, HandleUtility.GetHandleSize(wp) * k_HandleSize, evt.type); if (evt.type == EventType.MouseDown) { evt.Use(); UndoUtility.RecordObject(polygon, "Insert Point"); polygon.m_Points.Insert(index, p); m_SelectedIndex = index; m_PlacingPoint = true; RebuildPolyShapeMesh(true); OnBeginVertexMovement(); } Handles.color = Color.white; } } } }
void HandleKeyEvent(Event evt) { KeyCode key = evt.keyCode; switch (key) { case KeyCode.Space: case KeyCode.Return: { if (polygon.polyEditMode == PolyShape.PolyEditMode.Path) { if (SceneCameraIsAlignedWithPolyUp()) { SetPolyEditMode(PolyShape.PolyEditMode.Edit); } else { SetPolyEditMode(PolyShape.PolyEditMode.Height); } evt.Use(); } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Height) { SetPolyEditMode(PolyShape.PolyEditMode.Edit); evt.Use(); } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Edit) { SetPolyEditMode(PolyShape.PolyEditMode.None); evt.Use(); } break; } case KeyCode.Backspace: { if (m_SelectedIndex > -1) { UndoUtility.RecordObject(polygon, "Delete Selected Points"); polygon.m_Points.RemoveAt(m_SelectedIndex); m_SelectedIndex = -1; RebuildPolyShapeMesh(polygon); evt.Use(); } break; } case KeyCode.Escape: { if (polygon.polyEditMode == PolyShape.PolyEditMode.Path || polygon.polyEditMode == PolyShape.PolyEditMode.Height) { DiscardIncompleteShape(); evt.Use(); } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Edit) { SetPolyEditMode(PolyShape.PolyEditMode.None); evt.Use(); } break; } } }
public static bool OnGUI(ProBuilderMesh[] selection, float width) { UpdateDiffDictionary(selection); s_ScrollPosition = EditorGUILayout.BeginScrollView(s_ScrollPosition); float tempFloat = 0f; EditorGUI.BeginChangeCheck(); /** * Set Tile mode */ GUILayout.Label("Tiling & Alignment", EditorStyles.boldLabel); GUILayout.BeginHorizontal(); EditorGUI.showMixedValue = s_AutoUVSettingsDiff["fill"]; GUILayout.Label("Fill Mode", GUILayout.MaxWidth(80), GUILayout.MinWidth(80)); EditorGUI.BeginChangeCheck(); s_AutoUVSettings.fill = (AutoUnwrapSettings.Fill)EditorGUILayout.EnumPopup(s_AutoUVSettings.fill); if (EditorGUI.EndChangeCheck()) { SetFill(s_AutoUVSettings.fill, selection); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); bool enabled = GUI.enabled; GUI.enabled = !s_AutoUVSettings.useWorldSpace; EditorGUI.showMixedValue = s_AutoUVSettingsDiff["anchor"]; EditorGUI.BeginChangeCheck(); GUILayout.Label("Anchor", GUILayout.MaxWidth(80), GUILayout.MinWidth(80)); s_AutoUVSettings.anchor = (AutoUnwrapSettings.Anchor)EditorGUILayout.EnumPopup(s_AutoUVSettings.anchor); if (EditorGUI.EndChangeCheck()) { SetAnchor(s_AutoUVSettings.anchor, selection); } GUI.enabled = enabled; GUILayout.EndHorizontal(); GUI.backgroundColor = PreferenceKeys.proBuilderLightGray; UI.EditorGUIUtility.DrawSeparator(1); GUI.backgroundColor = Color.white; GUILayout.Label("Transform", EditorStyles.boldLabel); /** * Offset */ EditorGUI.showMixedValue = s_AutoUVSettingsDiff["offsetx"] || s_AutoUVSettingsDiff["offsety"]; var tempVec2 = s_AutoUVSettings.offset; UnityEngine.GUI.SetNextControlName("offset"); s_AutoUVSettings.offset = EditorGUILayout.Vector2Field("Offset", s_AutoUVSettings.offset, GUILayout.MaxWidth(width)); if (tempVec2.x != s_AutoUVSettings.offset.x) { SetOffset(s_AutoUVSettings.offset, Axis2D.X, selection); } if (tempVec2.y != s_AutoUVSettings.offset.y) { SetOffset(s_AutoUVSettings.offset, Axis2D.Y, selection); } /** * Rotation */ tempFloat = s_AutoUVSettings.rotation; EditorGUI.showMixedValue = s_AutoUVSettingsDiff["rotation"]; GUILayout.Label(new GUIContent("Rotation", "Rotation around the center of face UV bounds."), GUILayout.MaxWidth(width - 64)); UnityEngine.GUI.SetNextControlName("rotation"); EditorGUI.BeginChangeCheck(); tempFloat = EditorGUILayout.Slider(tempFloat, 0f, 360f, GUILayout.MaxWidth(width)); if (EditorGUI.EndChangeCheck()) { SetRotation(tempFloat, selection); } /** * Scale */ EditorGUI.showMixedValue = s_AutoUVSettingsDiff["scalex"] || s_AutoUVSettingsDiff["scaley"]; tempVec2 = s_AutoUVSettings.scale; GUI.SetNextControlName("scale"); EditorGUI.BeginChangeCheck(); s_AutoUVSettings.scale = EditorGUILayout.Vector2Field("Tiling", s_AutoUVSettings.scale, GUILayout.MaxWidth(width)); if (EditorGUI.EndChangeCheck()) { if (tempVec2.x != s_AutoUVSettings.scale.x) { SetScale(s_AutoUVSettings.scale, Axis2D.X, selection); } if (tempVec2.y != s_AutoUVSettings.scale.y) { SetScale(s_AutoUVSettings.scale, Axis2D.Y, selection); } } // Draw tiling shortcuts GUILayout.BeginHorizontal(); if (GUILayout.Button(".5", EditorStyles.miniButtonLeft)) { SetScale(Vector2.one * 2f, Axis2D.XY, selection); } if (GUILayout.Button("1", EditorStyles.miniButtonMid)) { SetScale(Vector2.one, Axis2D.XY, selection); } if (GUILayout.Button("2", EditorStyles.miniButtonMid)) { SetScale(Vector2.one * .5f, Axis2D.XY, selection); } if (GUILayout.Button("4", EditorStyles.miniButtonMid)) { SetScale(Vector2.one * .25f, Axis2D.XY, selection); } if (GUILayout.Button("8", EditorStyles.miniButtonMid)) { SetScale(Vector2.one * .125f, Axis2D.XY, selection); } if (GUILayout.Button("16", EditorStyles.miniButtonRight)) { SetScale(Vector2.one * .0625f, Axis2D.XY, selection); } GUILayout.EndHorizontal(); GUILayout.Space(4); UnityEngine.GUI.backgroundColor = PreferenceKeys.proBuilderLightGray; UI.EditorGUIUtility.DrawSeparator(1); UnityEngine.GUI.backgroundColor = Color.white; /** * Special */ GUILayout.Label("Special", EditorStyles.boldLabel); EditorGUI.showMixedValue = s_AutoUVSettingsDiff["useWorldSpace"]; EditorGUI.BeginChangeCheck(); s_AutoUVSettings.useWorldSpace = EditorGUILayout.Toggle("World Space", s_AutoUVSettings.useWorldSpace); if (EditorGUI.EndChangeCheck()) { SetUseWorldSpace(s_AutoUVSettings.useWorldSpace, selection); } GUI.backgroundColor = PreferenceKeys.proBuilderLightGray; UI.EditorGUIUtility.DrawSeparator(1); GUI.backgroundColor = Color.white; // Flip U EditorGUI.showMixedValue = s_AutoUVSettingsDiff["flipU"]; EditorGUI.BeginChangeCheck(); s_AutoUVSettings.flipU = EditorGUILayout.Toggle("Flip U", s_AutoUVSettings.flipU); if (EditorGUI.EndChangeCheck()) { SetFlipU(s_AutoUVSettings.flipU, selection); } // Flip V EditorGUI.showMixedValue = s_AutoUVSettingsDiff["flipV"]; EditorGUI.BeginChangeCheck(); s_AutoUVSettings.flipV = EditorGUILayout.Toggle("Flip V", s_AutoUVSettings.flipV); if (EditorGUI.EndChangeCheck()) { SetFlipV(s_AutoUVSettings.flipV, selection); } EditorGUI.showMixedValue = s_AutoUVSettingsDiff["swapUV"]; EditorGUI.BeginChangeCheck(); s_AutoUVSettings.swapUV = EditorGUILayout.Toggle("Swap U/V", s_AutoUVSettings.swapUV); if (EditorGUI.EndChangeCheck()) { SetSwapUV(s_AutoUVSettings.swapUV, selection); } /** * Texture Groups */ GUILayout.Label("Texture Groups", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = s_AutoUVSettingsDiff["textureGroup"]; GUI.SetNextControlName("textureGroup"); textureGroup = UI.EditorGUIUtility.IntFieldConstrained(new GUIContent("Texture Group", "Faces in a texture group will be UV mapped as a group, just as though you had selected these faces and used the \"Planar Project\" action"), textureGroup, (int)width); if (EditorGUI.EndChangeCheck()) { SetTextureGroup(selection, textureGroup); foreach (var kvp in MeshSelection.selectedFacesInEditZone) { kvp.Key.RefreshUV(kvp.Value); } SceneView.RepaintAll(); s_AutoUVSettingsDiff["textureGroup"] = false; } if (GUILayout.Button(new GUIContent("Group Selected Faces", "This sets all selected faces to share a texture group. What that means is that the UVs on these faces will all be projected as though they are a single plane. Ideal candidates for texture groups are floors with multiple faces, walls with edge loops, flat surfaces, etc."))) { for (int i = 0; i < selection.Length; i++) { TextureGroupSelectedFaces(selection[i]); } ProBuilderEditor.Refresh(); } if (GUILayout.Button(new GUIContent("Break Selected Groups", "This resets all the selected face Texture Groups."))) { SetTextureGroup(selection, -1); foreach (var kvp in MeshSelection.selectedFacesInEditZone) { kvp.Key.ToMesh(); kvp.Key.Refresh(); kvp.Key.Optimize(); } SceneView.RepaintAll(); s_AutoUVSettingsDiff["textureGroup"] = false; ProBuilderEditor.Refresh(); } /* Select all in current texture group */ if (GUILayout.Button(new GUIContent("Select Texture Group", "Selects all faces contained in this texture group."))) { for (int i = 0; i < selection.Length; i++) { selection[i].SetSelectedFaces(System.Array.FindAll(selection[i].facesInternal, x => x.textureGroup == textureGroup)); } ProBuilderEditor.Refresh(); } if (GUILayout.Button(new GUIContent("Reset UVs", "Reset UV projection parameters."))) { UndoUtility.RecordSelection(selection, "Reset UVs"); for (int i = 0; i < selection.Length; i++) { foreach (Face face in selection[i].GetSelectedFaces()) { face.uv = AutoUnwrapSettings.tile; face.textureGroup = -1; face.elementGroup = -1; } UVEditing.SplitUVs(selection[i], selection[i].GetSelectedFaces()); } ProBuilderEditor.Refresh(); } GUI.backgroundColor = PreferenceKeys.proBuilderLightGray; UI.EditorGUIUtility.DrawSeparator(1); GUI.backgroundColor = Color.white; /** * Clean up */ GUILayout.EndScrollView(); EditorGUI.showMixedValue = false; return(EditorGUI.EndChangeCheck()); }
void OnBeginVertexModification() { m_IsMoving = true; UndoUtility.RecordObject(m_Target, "Modify Bezier Spline"); Lightmapping.PushGIWorkflowMode(); }
void OnSceneGUI() { Event e = Event.current; bool eventHasBeenUsed = false; if (m_IsMoving) { if (e.type == EventType.Ignore || e.type == EventType.MouseUp) { eventHasBeenUsed = true; OnFinishVertexModification(); } } bool sceneViewInUse = EditorHandleUtility.SceneViewInUse(e); if (e.type == EventType.KeyDown) { if (e.keyCode == KeyCode.Backspace && m_currentHandle > -1 && m_currentHandle < m_Points.Count) { UndoUtility.RecordObject(m_Target, "Delete Bezier Point"); m_Points.RemoveAt(m_currentHandle); UpdateMesh(true); } else if (e.keyCode == KeyCode.Escape) { SetIsEditing(false); } } int count = m_Points.Count; Matrix4x4 handleMatrix = Handles.matrix; Handles.matrix = m_Target.transform.localToWorldMatrix; EditorGUI.BeginChangeCheck(); for (int index = 0; index < count; index++) { if (index < count - 1 || m_CloseLoop) { Handles.DrawBezier(m_Points[index].position, m_Points[(index + 1) % count].position, m_Points[index].tangentOut, m_Points[(index + 1) % count].tangentIn, Color.green, EditorGUIUtility.whiteTexture, 1f); } if (!m_IsEditing) { continue; } // If the index is selected show the full transform gizmo, otherwise use free move handles if (m_currentHandle == index) { BezierPoint point = m_Points[index]; if (!m_currentHandle.isTangent) { Vector3 prev = point.position; prev = Handles.PositionHandle(prev, Quaternion.identity); if (!Math.Approx3(prev, point.position)) { if (!m_IsMoving) { OnBeginVertexModification(); } prev = EditorSnapping.MoveSnap(prev); Vector3 dir = prev - point.position; point.position = prev; point.tangentIn += dir; point.tangentOut += dir; } // rotation int prev_index = index > 0 ? index - 1 : (m_CloseLoop ? count - 1 : -1); int next_index = index < count - 1 ? index + 1 : (m_CloseLoop ? 0 : -1); Vector3 rd = BezierPoint.GetLookDirection(m_Points, index, prev_index, next_index); Quaternion look = Quaternion.LookRotation(rd); float size = HandleUtility.GetHandleSize(point.position); Matrix4x4 pm = Handles.matrix; Handles.matrix = pm * Matrix4x4.TRS(point.position, look, Vector3.one); point.rotation = Handles.Disc(point.rotation, Vector3.zero, Vector3.forward, size, false, 0f); Handles.matrix = pm; } else { Handles.color = bezierTangentHandleColor; if (m_currentHandle.tangent == BezierTangentDirection.In && (m_CloseLoop || index > 0)) { EditorGUI.BeginChangeCheck(); point.tangentIn = Handles.PositionHandle(point.tangentIn, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { if (!m_IsMoving) { OnBeginVertexModification(); } point.tangentIn = EditorSnapping.MoveSnap(point.tangentIn); point.EnforceTangentMode(BezierTangentDirection.In, m_TangentMode); } Handles.color = Color.blue; Handles.DrawLine(m_Points[index].position, m_Points[index].tangentIn); } if (m_currentHandle.tangent == BezierTangentDirection.Out && (m_CloseLoop || index < count - 1)) { EditorGUI.BeginChangeCheck(); point.tangentOut = Handles.PositionHandle(point.tangentOut, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { if (!m_IsMoving) { OnBeginVertexModification(); } point.tangentOut = EditorSnapping.MoveSnap(point.tangentOut); point.EnforceTangentMode(BezierTangentDirection.Out, m_TangentMode); } Handles.color = Color.red; Handles.DrawLine(m_Points[index].position, m_Points[index].tangentOut); } } m_Points[index] = point; } } if (!m_IsEditing) { return; } EventType eventType = e.type; if (!eventHasBeenUsed) { eventHasBeenUsed = eventType == EventType.Used; } for (int index = 0; index < count; index++) { Vector3 prev; BezierPoint point = m_Points[index]; // Position Handle float size = HandleUtility.GetHandleSize(point.position) * k_HandleSize; Handles.color = bezierPositionHandleColor; if (m_currentHandle == index && !m_currentHandle.isTangent) { Handles.DotHandleCap(0, point.position, Quaternion.identity, size, e.type); } else { prev = point.position; prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap); if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used) { eventHasBeenUsed = true; m_currentHandle = (BezierHandle)index; Repaint(); SceneView.RepaintAll(); } else if (!Math.Approx3(prev, point.position)) { if (!m_IsMoving) { OnBeginVertexModification(); } point.SetPosition(EditorSnapping.MoveSnap(prev)); } } // Tangent handles Handles.color = bezierTangentHandleColor; // Tangent In Handle if (m_CloseLoop || index > 0) { size = HandleUtility.GetHandleSize(point.tangentIn) * k_HandleSize; Handles.DrawLine(point.position, point.tangentIn); if (index == m_currentHandle && m_currentHandle.isTangent && m_currentHandle.tangent == BezierTangentDirection.In) { Handles.DotHandleCap(0, point.tangentIn, Quaternion.identity, size, e.type); } else { prev = point.tangentIn; prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap); if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used) { eventHasBeenUsed = true; m_currentHandle.SetIndexAndTangent(index, BezierTangentDirection.In); Repaint(); SceneView.RepaintAll(); } else if (!Math.Approx3(prev, point.tangentIn)) { if (!m_IsMoving) { OnBeginVertexModification(); } point.tangentIn = EditorSnapping.MoveSnap(prev); point.EnforceTangentMode(BezierTangentDirection.In, m_TangentMode); } } } // Tangent Out if (m_CloseLoop || index < count - 1) { size = HandleUtility.GetHandleSize(point.tangentOut) * k_HandleSize; Handles.DrawLine(point.position, point.tangentOut); if (index == m_currentHandle && m_currentHandle.isTangent && m_currentHandle.tangent == BezierTangentDirection.Out) { Handles.DotHandleCap(0, point.tangentOut, Quaternion.identity, size, e.type); } else { prev = point.tangentOut; prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap); if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used) { eventHasBeenUsed = true; m_currentHandle.SetIndexAndTangent(index, BezierTangentDirection.Out); Repaint(); SceneView.RepaintAll(); } else if (!Math.Approx3(prev, point.tangentOut)) { if (!m_IsMoving) { OnBeginVertexModification(); } point.tangentOut = EditorSnapping.MoveSnap(prev); point.EnforceTangentMode(BezierTangentDirection.Out, m_TangentMode); } } } m_Points[index] = point; } // Do control point insertion if (!eventHasBeenUsed && m_ControlPoints != null && m_ControlPoints.Count > 1) { int index = -1; float distanceToLine; Vector3 p = EditorHandleUtility.ClosestPointToPolyLine(m_ControlPoints, out index, out distanceToLine, false, null); if (!IsHoveringHandlePoint(e.mousePosition) && distanceToLine < PreferenceKeys.k_MaxPointDistanceFromControl) { Handles.color = Color.green; Handles.DotHandleCap(-1, p, Quaternion.identity, HandleUtility.GetHandleSize(p) * .05f, e.type); Handles.color = Color.white; if (!eventHasBeenUsed && eventType == EventType.MouseDown && e.button == 0) { UndoUtility.RecordObject(m_Target, "Add Point"); Vector3 dir = m_ControlPoints[(index + 1) % m_ControlPoints.Count] - m_ControlPoints[index]; m_Points.Insert((index / m_Columns) + 1, new BezierPoint(p, p - dir, p + dir, Quaternion.identity)); UpdateMesh(true); e.Use(); } SceneView.RepaintAll(); } } if (e.type == EventType.MouseUp && !sceneViewInUse) { m_currentHandle.SetIndex(-1); } Handles.matrix = handleMatrix; if (EditorGUI.EndChangeCheck()) { UpdateMesh(false); } }
public override void OnInspectorGUI() { if (!m_IsEditing) { if (GUILayout.Button("Edit Bezier Shape")) { SetIsEditing(true); } EditorGUILayout.HelpBox("Editing a Bezier Shape will erase any modifications made to the mesh!\n\nIf you accidentally enter Edit Mode you can Undo to get your changes back.", MessageType.Warning); return; } if (GUILayout.Button("Editing Bezier Shape", UI.EditorGUIUtility.GetActiveStyle("Button"))) { SetIsEditing(false); } Event e = Event.current; if (m_IsMoving) { if (e.type == EventType.Ignore || e.type == EventType.MouseUp) { OnFinishVertexModification(); } } EditorGUI.BeginChangeCheck(); bool handleIsValid = (m_currentHandle > -1 && m_currentHandle < m_Points.Count); BezierPoint inspectorPoint = handleIsValid ? m_Points[m_currentHandle] : new BezierPoint(Vector3_Zero, Vector3_Backward, Vector3_Forward, Quaternion.identity); inspectorPoint = DoBezierPointGUI(inspectorPoint); if (handleIsValid && EditorGUI.EndChangeCheck()) { if (!m_IsMoving) { OnBeginVertexModification(); } m_Points[m_currentHandle] = inspectorPoint; UpdateMesh(false); } EditorGUI.BeginChangeCheck(); if (GUILayout.Button("Clear Points")) { UndoUtility.RecordObject(m_Target, "Clear Bezier Spline Points"); m_Points.Clear(); UpdateMesh(true); } if (GUILayout.Button("Add Point")) { UndoUtility.RecordObject(m_Target, "Add Bezier Spline Point"); if (m_Points.Count > 0) { m_Points.Add(new BezierPoint(m_Points[m_Points.Count - 1].position, m_Points[m_Points.Count - 1].tangentIn, m_Points[m_Points.Count - 1].tangentOut, Quaternion.identity)); UpdateMesh(true); } else { m_Target.Init(); } m_currentHandle = (BezierHandle)(m_Points.Count - 1); SceneView.RepaintAll(); } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); m_TangentMode = (BezierTangentMode)GUILayout.Toolbar((int)m_TangentMode, s_TangentModeIcons, commandStyle); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); m_CloseLoop = EditorGUILayout.Toggle("Close Loop", m_CloseLoop); m_Smooth = EditorGUILayout.Toggle("Smooth", m_Smooth); m_Radius = Mathf.Max(.001f, EditorGUILayout.FloatField("Radius", m_Radius)); m_Rows = Math.Clamp(EditorGUILayout.IntField("Rows", m_Rows), 3, 512); m_Columns = Math.Clamp(EditorGUILayout.IntField("Columns", m_Columns), 3, 512); if (EditorGUI.EndChangeCheck()) { UpdateMesh(true); } }
static void OnSceneGUI(SceneView sceneView) { var evt = Event.current; if (evt.type == EventType.DragUpdated) { if (!s_IsSceneViewDragAndDrop) { s_IsSceneViewDragAndDrop = true; } int submeshIndex; GameObject go = HandleUtility.PickGameObject(evt.mousePosition, out submeshIndex); SetMeshPreview(go != null ? go.GetComponent <ProBuilderMesh>() : null); if (s_IsFaceDragAndDropOverrideEnabled) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; evt.Use(); } } else if (evt.type == EventType.DragExited) { if (s_IsFaceDragAndDropOverrideEnabled) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; evt.Use(); SetMeshPreview(null); } s_IsSceneViewDragAndDrop = false; } else if (evt.type == EventType.DragPerform) { s_IsSceneViewDragAndDrop = false; int submeshIndex; GameObject go = HandleUtility.PickGameObject(evt.mousePosition, out submeshIndex); SetMeshPreview(go != null ? go.GetComponent <ProBuilderMesh>() : null); if (s_CurrentPreview != null && s_IsFaceDragAndDropOverrideEnabled) { UndoUtility.RecordObject(s_CurrentPreview, "Set Face Material"); UndoUtility.RecordObject(s_CurrentPreview.renderer, "Set Face Material"); s_CurrentPreview.SetMaterial(s_CurrentPreview.selectedFacesInternal, s_PreviewMaterial); InternalMeshUtility.FilterUnusedSubmeshIndexes(s_CurrentPreview); s_CurrentPreview.ToMesh(); s_CurrentPreview.Refresh(); s_CurrentPreview.Optimize(); evt.Use(); } SetMeshPreview(null); } else if (evt.type == EventType.Repaint && s_IsFaceDragAndDropOverrideEnabled) { if (s_PreviewMaterial.SetPass(0)) { Graphics.DrawMeshNow(s_PreviewMesh, s_Matrix, 0); } } }
public static ProBuilderMesh DoMouseClick(Event evt, SelectMode selectionMode, ScenePickerPreferences pickerPreferences) { bool appendModifier = EditorHandleUtility.IsAppendModifier(evt.modifiers); bool addToSelectionModifier = EditorHandleUtility.IsSelectionAddModifier(evt.modifiers); bool addOrRemoveIfPresentFromSelectionModifier = EditorHandleUtility.IsSelectionAppendOrRemoveIfPresentModifier(evt.modifiers); bool pathSelectionModifier = EditorHandleUtility.IsSelectionPathModifier(evt.modifiers); float pickedElementDistance; if (selectionMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge)) { pickedElementDistance = EdgeRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection); } else if (selectionMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex)) { pickedElementDistance = VertexRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection); } else { pickedElementDistance = FaceRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection, evt.clickCount > 1 ? -1 : 0, false); } evt.Use(); if (!appendModifier) { if (s_Selection.mesh != null) { s_Selection.mesh.ClearSelection(); } MeshSelection.SetSelection((GameObject)null); } if (pickedElementDistance > ScenePickerPreferences.maxPointerDistance) { if (appendModifier && Selection.gameObjects.Contains(s_Selection.gameObject)) { MeshSelection.RemoveFromSelection(s_Selection.gameObject); } else { MeshSelection.AddToSelection(s_Selection.gameObject); } return(null); } GameObject candidateNewActiveObject = s_Selection.gameObject; bool activeObjectSelectionChanged = Selection.gameObjects.Contains(s_Selection.gameObject) && s_Selection.gameObject != Selection.activeGameObject; if (s_Selection.mesh != null) { var mesh = s_Selection.mesh; foreach (var face in s_Selection.faces) { // Check for other editor mouse shortcuts first (todo proper event handling for mouse shortcuts) MaterialEditor matEditor = MaterialEditor.instance; if (matEditor != null && matEditor.ClickShortcutCheck(Event.current.modifiers, mesh, face)) { return(null); } UVEditor uvEditor = UVEditor.instance; if (uvEditor != null && uvEditor.ClickShortcutCheck(mesh, face)) { return(null); } var faces = mesh.faces as Face[] ?? mesh.faces.ToArray(); var ind = Array.IndexOf <Face>(faces, face); var sel = mesh.selectedFaceIndexes.IndexOf(ind); UndoUtility.RecordSelection(mesh, "Select Face"); if (sel > -1) { if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier || (addToSelectionModifier && face == mesh.GetActiveFace() && !activeObjectSelectionChanged)) { mesh.RemoveFromFaceSelectionAtIndex(sel); if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged) { candidateNewActiveObject = Selection.activeGameObject; } else if (mesh.selectedFaceCount == 0) { for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--) { if (MeshSelection.topInternal[i].selectedFaceCount > 0) { candidateNewActiveObject = MeshSelection.topInternal[i].gameObject; activeObjectSelectionChanged = true; break; } } } } else { mesh.selectedFaceIndicesInternal = mesh.selectedFaceIndicesInternal.Remove(ind); mesh.SetSelectedFaces(mesh.selectedFaceIndicesInternal.Add(ind)); } } else if (pathSelectionModifier && mesh.GetActiveFace() != null) { var pathFaces = SelectPathFaces.GetPath(mesh, Array.IndexOf <Face>(faces, mesh.GetActiveFace()), Array.IndexOf <Face>(faces, face)); foreach (var pathFace in pathFaces) { mesh.AddToFaceSelection(pathFace); } } else { mesh.AddToFaceSelection(ind); } } foreach (var edge in s_Selection.edges) { int ind = mesh.IndexOf(mesh.selectedEdges, edge); UndoUtility.RecordSelection(mesh, "Select Edge"); if (ind > -1) { if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier || (addToSelectionModifier && edge == mesh.GetActiveEdge() && !activeObjectSelectionChanged)) { mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().RemoveAt(ind)); if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged) { candidateNewActiveObject = Selection.activeGameObject; } else if (mesh.selectedEdgeCount == 0) { for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--) { if (MeshSelection.topInternal[i].selectedEdgeCount > 0) { candidateNewActiveObject = MeshSelection.topInternal[i].gameObject; activeObjectSelectionChanged = true; break; } } } } else { mesh.selectedEdgesInternal = mesh.selectedEdgesInternal.Remove(edge); mesh.SetSelectedEdges(mesh.selectedEdgesInternal.Add(edge)); } } else { mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().Add(edge)); } } foreach (var vertex in s_Selection.vertexes) { int ind = Array.IndexOf(mesh.selectedIndexesInternal, vertex); UndoUtility.RecordSelection(mesh, "Select Vertex"); if (ind > -1) { var sharedIndex = mesh.sharedVertexLookup[vertex]; var sharedVertex = mesh.sharedVerticesInternal[sharedIndex]; s_IndexBuffer.Clear(); foreach (var sVertex in sharedVertex) { var index = Array.IndexOf(mesh.selectedIndexesInternal, sVertex); if (index < 0) { continue; } s_IndexBuffer.Add(index); } s_IndexBuffer.Sort(); if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier || (addToSelectionModifier && vertex == mesh.GetActiveVertex() && !activeObjectSelectionChanged)) { mesh.selectedIndexesInternal = mesh.selectedIndexesInternal.SortedRemoveAt(s_IndexBuffer); mesh.SetSelectedVertices(mesh.selectedIndexesInternal); if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged) { candidateNewActiveObject = Selection.activeGameObject; } else if (mesh.selectedIndexesInternal.Length == 0) { for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--) { if (MeshSelection.topInternal[i].selectedIndexesInternal.Length > 0) { candidateNewActiveObject = MeshSelection.topInternal[i].gameObject; activeObjectSelectionChanged = true; break; } } } } else { mesh.selectedIndexesInternal = mesh.selectedIndexesInternal.SortedRemoveAt(s_IndexBuffer); mesh.SetSelectedVertices(mesh.selectedIndexesInternal.Add(vertex)); } } else { mesh.SetSelectedVertices(mesh.selectedIndexesInternal.Add(vertex)); } } if (activeObjectSelectionChanged) { MeshSelection.MakeActiveObject(candidateNewActiveObject); } else { MeshSelection.AddToSelection(candidateNewActiveObject); } return(mesh); } return(null); }
void DoExistingPointsGUI() { Transform trs = polygon.transform; int len = polygon.m_Points.Count; Vector3 up = polygon.transform.up; Vector3 right = polygon.transform.right; Vector3 forward = polygon.transform.forward; Vector3 center = Vector3.zero; Event evt = Event.current; bool used = evt.type == EventType.Used; if (!used && (evt.type == EventType.MouseDown && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers))) { m_SelectedIndex = -1; Repaint(); } if (polygon.polyEditMode == PolyShape.PolyEditMode.Height) { if (!used && evt.type == EventType.MouseUp && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers)) { evt.Use(); SetPolyEditMode(PolyShape.PolyEditMode.Edit); } bool sceneInUse = EditorHandleUtility.SceneViewInUse(evt); Ray r = HandleUtility.GUIPointToWorldRay(evt.mousePosition); Vector3 origin = polygon.transform.TransformPoint(Math.Average(polygon.m_Points)); float extrude = polygon.extrude; if (evt.type == EventType.MouseMove && !sceneInUse) { Vector3 p = Math.GetNearestPointRayRay(origin, up, r.origin, r.direction); extrude = ProGridsInterface.ProGridsSnap(s_HeightMouseOffset + Vector3.Distance(origin, p) * Mathf.Sign(Vector3.Dot(p - origin, up))); } Vector3 extrudePoint = origin + (extrude * up); Handles.color = k_HandleColor; Handles.DotHandleCap(-1, origin, Quaternion.identity, HandleUtility.GetHandleSize(origin) * k_HandleSize, evt.type); Handles.color = k_HandleColorGreen; Handles.DrawLine(origin, extrudePoint); Handles.DotHandleCap(-1, extrudePoint, Quaternion.identity, HandleUtility.GetHandleSize(extrudePoint) * k_HandleSize, evt.type); Handles.color = Color.white; if (!sceneInUse && polygon.extrude != extrude) { OnBeginVertexMovement(); polygon.extrude = extrude; RebuildPolyShapeMesh(false); } } else { // vertex dots for (int ii = 0; ii < len; ii++) { Vector3 point = trs.TransformPoint(polygon.m_Points[ii]); center.x += point.x; center.y += point.y; center.z += point.z; float size = HandleUtility.GetHandleSize(point) * k_HandleSize; Handles.color = ii == m_SelectedIndex ? k_HandleSelectedColor : k_HandleColor; EditorGUI.BeginChangeCheck(); point = Handles.Slider2D(point, up, right, forward, size, Handles.DotHandleCap, Vector2.zero, true); if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Move Polygon Shape Point"); Vector3 snapMask = Snapping.GetSnappingMaskBasedOnNormalVector(m_Plane.normal); polygon.m_Points[ii] = ProGridsInterface.ProGridsSnap(trs.InverseTransformPoint(point), snapMask); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } // "clicked" a button if (!used && evt.type == EventType.Used) { if (ii == 0 && polygon.m_Points.Count > 2 && polygon.polyEditMode == PolyShape.PolyEditMode.Path) { m_NextMouseUpAdvancesMode = true; return; } else { used = true; m_SelectedIndex = ii; } } } Handles.color = Color.white; // height setting if (polygon.polyEditMode != PolyShape.PolyEditMode.Path && polygon.m_Points.Count > 2) { center.x /= (float)len; center.y /= (float)len; center.z /= (float)len; Vector3 extrude = center + (up * polygon.extrude); m_DistanceFromHeightHandle = Vector2.Distance(HandleUtility.WorldToGUIPoint(extrude), evt.mousePosition); EditorGUI.BeginChangeCheck(); Handles.color = k_HandleColor; Handles.DotHandleCap(-1, center, Quaternion.identity, HandleUtility.GetHandleSize(center) * k_HandleSize, evt.type); Handles.DrawLine(center, extrude); Handles.color = k_HandleColorGreen; extrude = Handles.Slider(extrude, up, HandleUtility.GetHandleSize(extrude) * k_HandleSize, Handles.DotHandleCap, 0f); Handles.color = Color.white; if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Set Polygon Shape Height"); polygon.extrude = ProGridsInterface.ProGridsSnap(Vector3.Distance(extrude, center) * Mathf.Sign(Vector3.Dot(up, extrude - center))); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } } } }
public static void DoMouseDrag(Rect mouseDragRect, SelectMode selectionMode, ScenePickerPreferences scenePickerPreferences) { var pickingOptions = new PickerOptions() { depthTest = scenePickerPreferences.cullMode == CullingMode.Back, rectSelectMode = scenePickerPreferences.rectSelectMode }; UndoUtility.RecordSelection("Drag Select"); bool isAppendModifier = EditorHandleUtility.IsAppendModifier(Event.current.modifiers); if (!isAppendModifier) { MeshSelection.ClearElementSelection(); } bool elementsInDragRect = false; switch (selectionMode) { case SelectMode.Vertex: case SelectMode.TextureVertex: { Dictionary <ProBuilderMesh, HashSet <int> > selected = SelectionPicker.PickVerticesInRect( SceneView.lastActiveSceneView.camera, mouseDragRect, MeshSelection.topInternal, pickingOptions, EditorGUIUtility.pixelsPerPoint); foreach (var kvp in selected) { var mesh = kvp.Key; SharedVertex[] sharedIndexes = mesh.sharedVerticesInternal; HashSet <int> common; if (isAppendModifier) { common = mesh.GetSharedVertexHandles(mesh.selectedIndexesInternal); if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add) { common.UnionWith(kvp.Value); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract) { common.RemoveWhere(x => kvp.Value.Contains(x)); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference) { common.SymmetricExceptWith(kvp.Value); } } else { common = kvp.Value; } elementsInDragRect |= kvp.Value.Any(); mesh.SetSelectedVertices(common.SelectMany(x => sharedIndexes[x])); } break; } case SelectMode.Face: case SelectMode.TextureFace: { Dictionary <ProBuilderMesh, HashSet <Face> > selected = SelectionPicker.PickFacesInRect( SceneView.lastActiveSceneView.camera, mouseDragRect, MeshSelection.topInternal, pickingOptions, EditorGUIUtility.pixelsPerPoint); foreach (var kvp in selected) { HashSet <Face> current; if (isAppendModifier) { current = new HashSet <Face>(kvp.Key.selectedFacesInternal); if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add) { current.UnionWith(kvp.Value); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract) { current.RemoveWhere(x => kvp.Value.Contains(x)); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference) { current.SymmetricExceptWith(kvp.Value); } } else { current = kvp.Value; } elementsInDragRect |= kvp.Value.Any(); kvp.Key.SetSelectedFaces(current); } break; } case SelectMode.Edge: case SelectMode.TextureEdge: { var selected = SelectionPicker.PickEdgesInRect( SceneView.lastActiveSceneView.camera, mouseDragRect, MeshSelection.topInternal, pickingOptions, EditorGUIUtility.pixelsPerPoint); foreach (var kvp in selected) { ProBuilderMesh mesh = kvp.Key; Dictionary <int, int> common = mesh.sharedVertexLookup; HashSet <EdgeLookup> selectedEdges = EdgeLookup.GetEdgeLookupHashSet(kvp.Value, common); HashSet <EdgeLookup> current; if (isAppendModifier) { current = EdgeLookup.GetEdgeLookupHashSet(mesh.selectedEdges, common); if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add) { current.UnionWith(selectedEdges); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract) { current.RemoveWhere(x => selectedEdges.Contains(x)); } else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference) { current.SymmetricExceptWith(selectedEdges); } } else { current = selectedEdges; } elementsInDragRect |= kvp.Value.Any(); mesh.SetSelectedEdges(current.Select(x => x.local)); } break; } } // if nothing was selected in the drag rect, clear the object selection too if (!elementsInDragRect && !isAppendModifier) { MeshSelection.ClearElementAndObjectSelection(); } ProBuilderEditor.Refresh(); SceneView.RepaintAll(); }
public override void OnInspectorGUI() { switch (polygon.polyEditMode) { case PolyShape.PolyEditMode.None: { if (GUILayout.Button("Edit Poly Shape")) { SetPolyEditMode(PolyShape.PolyEditMode.Edit); } EditorGUILayout.HelpBox( "Editing a poly shape will erase any modifications made to the mesh!\n\nIf you accidentally enter Edit Mode you can Undo to get your changes back.", MessageType.Warning); break; } case PolyShape.PolyEditMode.Path: { EditorGUILayout.HelpBox("\nClick To Add Points\n\nPress 'Enter' or 'Space' to Set Height\n", MessageType.Info); break; } case PolyShape.PolyEditMode.Height: { EditorGUILayout.HelpBox("\nMove Mouse to Set Height\n\nPress 'Enter' or 'Space' to Finalize\n", MessageType.Info); break; } case PolyShape.PolyEditMode.Edit: { if (GUILayout.Button("Editing Poly Shape", UI.EditorGUIUtility.GetActiveStyle("Button"))) { SetPolyEditMode(PolyShape.PolyEditMode.None); } break; } } EditorGUI.BeginChangeCheck(); float extrude = polygon.extrude; extrude = EditorGUILayout.FloatField("Extrusion", extrude); bool flipNormals = polygon.flipNormals; flipNormals = EditorGUILayout.Toggle("Flip Normals", flipNormals); if (EditorGUI.EndChangeCheck()) { if (polygon.polyEditMode == PolyShape.PolyEditMode.None) { if (ProBuilderEditor.instance != null) { ProBuilderEditor.instance.ClearElementSelection(); } UndoUtility.RecordObject(polygon, "Change Polygon Shape Settings"); UndoUtility.RecordObject(polygon.mesh, "Change Polygon Shape Settings"); } else { UndoUtility.RecordObject(polygon, "Change Polygon Shape Settings"); } polygon.extrude = extrude; polygon.flipNormals = flipNormals; RebuildPolyShapeMesh(polygon); } // GUILayout.Label("selected : " + m_SelectedIndex); }
public void DrawShapeParametersGUI(DrawShapeTool tool = null) { if (target == null || serializedObject == null) { return; } serializedObject.Update(); var foldoutEnabled = tool == null ? s_foldoutEnabled : DrawShapeTool.s_SettingsEnabled.value; foldoutEnabled = EditorGUILayout.Foldout(foldoutEnabled, m_ShapePropertyLabel, true); if (tool == null) { s_foldoutEnabled = foldoutEnabled; } else { DrawShapeTool.s_SettingsEnabled.value = foldoutEnabled; } if (foldoutEnabled) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); m_ActiveShapeIndex = HasMultipleShapeTypes ? -1 : Mathf.Max(-1, Array.IndexOf(EditorShapeUtility.availableShapeTypes, m_CurrentShapeType)); m_ActiveShapeIndex = EditorGUILayout.Popup(m_ActiveShapeIndex, EditorShapeUtility.shapeTypes); if (EditorGUI.EndChangeCheck()) { var type = EditorShapeUtility.availableShapeTypes[m_ActiveShapeIndex]; foreach (var comp in targets) { ShapeComponent shapeComponent = ((ShapeComponent)comp); Shape shape = shapeComponent.shape; if (shape.GetType() != type) { if (tool != null) { DrawShapeTool.s_ActiveShapeIndex.value = m_ActiveShapeIndex; } UndoUtility.RecordComponents <Transform, ProBuilderMesh, ShapeComponent>(shapeComponent.GetComponents(typeof(Component)), "Change Shape"); shapeComponent.SetShape(EditorShapeUtility.CreateShape(type), shapeComponent.pivotLocation); ProBuilderEditor.Refresh(); } } } if (tool) { EditorGUILayout.PropertyField(m_ShapePivotProperty, k_ShapePivotLabel); } EditorGUILayout.PropertyField(m_ShapeSizeXProperty, k_ShapeSizeXLabel); if (HasMultipleShapeTypes || (m_CurrentShapeType != typeof(Plane) && m_CurrentShapeType != typeof(Sprite))) { EditorGUILayout.PropertyField(m_ShapeSizeYProperty, k_ShapeSizeYLabel); } EditorGUILayout.PropertyField(m_ShapeSizeZProperty, k_ShapeSizeZLabel); EditorGUI.indentLevel--; } if (!HasMultipleShapeTypes) { EditorGUILayout.PropertyField(m_ShapeProperty, new GUIContent("Shape Properties"), true); } if (serializedObject.ApplyModifiedProperties()) { foreach (var comp in targets) { var shapeComponent = comp as ShapeComponent; if (shapeComponent.isEditable) { UndoUtility.RecordComponents <Transform, ProBuilderMesh, ShapeComponent>(shapeComponent.GetComponents(typeof(Component)), "Resize Shape"); shapeComponent.UpdateComponent(); if (tool != null) { tool.SetBounds(shapeComponent.size); DrawShapeTool.SaveShapeParams(shapeComponent); } ProBuilderEditor.Refresh(); } } } GUI.enabled = true; }