public List <BrushBase> ExtractBrushBases(List <Brush> sourceBrushes) { // Generate a list of editable brushes (in the case of compound brush's child brushes this would be the root controller) List <BrushBase> brushBases = new List <BrushBase>(); for (int i = 0; i < sourceBrushes.Count; i++) { if (sourceBrushes[i].GetType() == typeof(PrimitiveBrush)) { // Get any controller (e.g. compound brush) that is driving the selected brush BrushBase controller = ((PrimitiveBrush)sourceBrushes[i]).BrushController; if (controller != null) { // Controller found, add it instead if it's not already in the list if (!brushBases.Contains(controller)) { brushBases.Add(controller); } } else { // No controller found just add the brush brushBases.Add(sourceBrushes[i]); } } else { // Not a primitive brush, so just add it brushBases.Add(sourceBrushes[i]); } } return(brushBases); }
/// <summary> /// Overrides the built in selection duplication to maintain sibling order of the selection. But only if at least one of the selection is under a CSG Model. /// </summary> /// <returns><c>true</c>, if our custom duplication took place (and one of the selection was under a CSG Model), <c>false</c> otherwise in which case the duplication event should not be consumed so that Unity will duplicate for us.</returns> public static bool DuplicateSelection() { List <Transform> selectedTransforms = Selection.transforms.ToList(); // Whether any of the selection objects are under a CSG Model bool shouldCustomDuplicationOccur = false; for (int i = 0; i < selectedTransforms.Count; i++) { if (selectedTransforms[i].GetComponentInParent <CSGModel>() != null) { shouldCustomDuplicationOccur = true; } } if (shouldCustomDuplicationOccur) // Some of the objects are under a CSG Model, so peform our special duplication override { // Sort the selected transforms in order of sibling index selectedTransforms.Sort((x, y) => x.GetSiblingIndex().CompareTo(y.GetSiblingIndex())); GameObject[] newObjects = new GameObject[Selection.gameObjects.Length]; // Walk through each selected object in the correct order, duplicating them one by one for (int i = 0; i < selectedTransforms.Count; i++) { // Temporarily set the selection to the single entry Selection.activeGameObject = selectedTransforms[i].gameObject; // Seems to be a bug in Unity where we need to set the objects array too otherwise it won't be set straight away Selection.objects = new Object[] { selectedTransforms[i].gameObject }; // Duplicate the single entry Unsupported.DuplicateGameObjectsUsingPasteboard(); // Cache the new entry, so when we're done we reselect all new objects newObjects[i] = Selection.activeGameObject; // Remove the 'Brush (1)', 'Brush (2)', etc. from the name. newObjects[i].name = Regex.Replace(newObjects[i].name, " \\(\\d+\\)$", ""); // If we are dealing with a brush, properly duplicate the volume type. BrushBase brush = newObjects[i].GetComponent <BrushBase>(); if (brush != null && brush.Volume != null) { brush.Volume = ScriptableObject.Instantiate(brush.Volume); brush.RebuildVolume(); } } // Finished duplicating, select all new objects Selection.objects = newObjects; } // Whether custom duplication took place and whether the Duplicate event should be consumed return(shouldCustomDuplicationOccur); }
protected override void Update() { base.Update(); // encapsulate all of the child objects in our bounds. Bounds csgBounds = new Bounds(); foreach (Transform childTransform in transform) { BrushBase child = childTransform.GetComponent <BrushBase>(); if (child == null) { continue; } csgBounds.Encapsulate(child.GetBoundsLocalTo(transform)); } // apply the generated csg bounds. localBounds = csgBounds; // update the generated name in the hierarchy. UpdateGeneratedHierarchyName(); }
public override void Invalidate(bool polygonsChanged) { //////////////////////////////////////////////////////////////////// // a little hack to detect the user manually resizing the bounds. // // we use this to automatically add steps for barnaby. // // it's probably good to build a more 'official' way to detect // // user scaling events in compound brushes sometime. // if (m_LastKnownExtents != localBounds.extents) // { // // undo any position movement. // transform.localPosition = m_LastKnownPosition; // } // //////////////////////////////////////////////////////////////////// Bounds csgBounds = new Bounds(); // nothing to do except copy csg information to our child brushes. foreach (Transform childTransform in transform) { BrushBase child = childTransform.GetComponent <BrushBase>(); if (child == null) { continue; } // we do not override these properties in a group. // it wouldn't make much sense and break whatever the user grouped. //child.Mode = this.Mode; //child.IsNoCSG = this.IsNoCSG; //child.IsVisible = this.IsVisible; //child.HasCollision = this.HasCollision; child.Invalidate(polygonsChanged); csgBounds.Encapsulate(child.GetBoundsLocalTo(transform)); } // apply the generated csg bounds. localBounds = csgBounds; m_LastKnownExtents = localBounds.extents; m_LastKnownPosition = transform.localPosition; // update name in hierarchy. base.Invalidate(polygonsChanged); }
public void SetBrushController(BrushBase brushController) { this.brushController = brushController; }
private static void OnBottomToolbarGUI(int windowID) { GUILayout.BeginHorizontal(); GUIStyle createBrushStyle = new GUIStyle(EditorStyles.toolbarButton); createBrushStyle.fixedHeight = 20; if (GUI.Button(new Rect(0, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCubeTexture, createBrushStyle)) { CreatePrimitiveBrush(PrimitiveBrushType.Cube); } if (GUI.Button(new Rect(30, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonPrismTexture, createBrushStyle)) { CreatePrimitiveBrush(PrimitiveBrushType.Prism); } //if(GUI.Button(new Rect(60,0, 30, createBrushStyle.fixedHeight), "", createBrushStyle)) //{ //} if (GUI.Button(new Rect(60, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonStairsTexture, createBrushStyle)) { CreateCompoundBrush <StairBrush>(); } if (GUI.Button(new Rect(90, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCurvedStairsTexture, createBrushStyle)) { CreateCompoundBrush <CurvedStairBrush>(); } GUILayout.Space(92 + 30); #if DEBUG_SABRECSG_PERF // For debugging frame rate GUILayout.Label(((int)(1 / csgModel.CurrentFrameDelta)).ToString(), SabreGUILayout.GetLabelStyle()); #endif if (SabreGUILayout.Button("Rebuild")) { csgModel.Build(false, false); } if (SabreGUILayout.Button("Force Rebuild")) { csgModel.Build(true, false); } GUI.color = Color.white; if (csgModel.AutoRebuild) { GUI.color = Color.green; } csgModel.AutoRebuild = SabreGUILayout.Toggle(csgModel.AutoRebuild, "Auto Rebuild"); GUI.color = Color.white; GUILayout.Label(csgModel.BuildMetrics.BuildMetaData.ToString(), SabreGUILayout.GetForeStyle(), GUILayout.Width(140)); bool lastBrushesHidden = CurrentSettings.BrushesHidden; if (lastBrushesHidden) { GUI.color = Color.red; } CurrentSettings.BrushesHidden = SabreGUILayout.Toggle(CurrentSettings.BrushesHidden, "Brushes Hidden"); if (CurrentSettings.BrushesHidden != lastBrushesHidden) { // Has changed CSGModel.UpdateAllBrushesVisibility(); SceneView.RepaintAll(); } GUI.color = Color.white; bool lastMeshHidden = CurrentSettings.MeshHidden; if (lastMeshHidden) { GUI.color = Color.red; } CurrentSettings.MeshHidden = SabreGUILayout.Toggle(CurrentSettings.MeshHidden, "Mesh Hidden"); if (CurrentSettings.MeshHidden != lastMeshHidden) { // Has changed CSGModel.UpdateAllBrushesVisibility(); SceneView.RepaintAll(); } GUI.color = Color.white; if (GUILayout.Button("Grid " + CurrentSettings.GridMode.ToString(), EditorStyles.toolbarDropDown, GUILayout.Width(90))) { GenericMenu menu = new GenericMenu(); string[] names = Enum.GetNames(typeof(GridMode)); for (int i = 0; i < names.Length; i++) { GridMode value = (GridMode)Enum.Parse(typeof(GridMode), names[i]); bool selected = false; if (CurrentSettings.GridMode == value) { selected = true; } menu.AddItem(new GUIContent(names[i]), selected, OnSelectedGridOption, value); } menu.DropDown(gridRect); } if (Event.current.type == EventType.Repaint) { gridRect = GUILayoutUtility.GetLastRect(); gridRect.width = 100; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); // Line Two GUILayout.BeginHorizontal(); if (GUI.Button(new Rect(0, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCylinderTexture, createBrushStyle)) { CreatePrimitiveBrush(PrimitiveBrushType.Cylinder); } if (GUI.Button(new Rect(30, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonSphereTexture, createBrushStyle)) { CreatePrimitiveBrush(PrimitiveBrushType.Sphere); } if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonConeTexture, createBrushStyle)) { CreatePrimitiveBrush(PrimitiveBrushType.Cone); } //if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "", createBrushStyle)) //{ //} if (GUI.Button(new Rect(90, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "...", createBrushStyle)) { GenericMenu menu = new GenericMenu(); List <Type> compoundBrushTypes = CompoundBrush.FindAllInAssembly(); for (int i = 0; i < compoundBrushTypes.Count; i++) { menu.AddItem(new GUIContent(compoundBrushTypes[i].Name), false, CreateCompoundBrush, compoundBrushTypes[i]); } menu.DropDown(new Rect(60, createBrushStyle.fixedHeight, 100, createBrushStyle.fixedHeight)); } GUILayout.Space(92 + 30); // Display brush count GUILayout.Label(csgModel.BrushCount.ToStringWithSuffix(" brush", " brushes"), SabreGUILayout.GetLabelStyle()); // CurrentSettings.GridMode = (GridMode)EditorGUILayout.EnumPopup(CurrentSettings.GridMode, EditorStyles.toolbarPopup, GUILayout.Width(80)); if (Selection.activeGameObject != null) { BrushBase primaryBrush = Selection.activeGameObject.GetComponent <BrushBase>(); List <BrushBase> brushes = new List <BrushBase>(); for (int i = 0; i < Selection.gameObjects.Length; i++) { BrushBase brush = Selection.gameObjects[i].GetComponent <BrushBase>(); if (brush != null) { brushes.Add(brush); } } if (primaryBrush != null) { CSGMode brushMode = (CSGMode)EditorGUILayout.EnumPopup(primaryBrush.Mode, EditorStyles.toolbarPopup, GUILayout.Width(80)); if (brushMode != primaryBrush.Mode) { bool anyChanged = false; foreach (BrushBase brush in brushes) { Undo.RecordObject(brush, "Change Brush To " + brushMode); brush.Mode = brushMode; anyChanged = true; } if (anyChanged) { // Need to update the icon for the csg mode in the hierarchy EditorApplication.RepaintHierarchyWindow(); } } bool[] noCSGStates = brushes.Select(brush => brush.IsNoCSG).Distinct().ToArray(); bool isNoCSG = (noCSGStates.Length == 1) ? noCSGStates[0] : false; bool newIsNoCSG = SabreGUILayout.ToggleMixed(noCSGStates, "NoCSG", GUILayout.Width(53)); bool[] collisionStates = brushes.Select(item => item.HasCollision).Distinct().ToArray(); bool hasCollision = (collisionStates.Length == 1) ? collisionStates[0] : false; bool newHasCollision = SabreGUILayout.ToggleMixed(collisionStates, "Collision", GUILayout.Width(53)); bool[] visibleStates = brushes.Select(item => item.IsVisible).Distinct().ToArray(); bool isVisible = (visibleStates.Length == 1) ? visibleStates[0] : false; bool newIsVisible = SabreGUILayout.ToggleMixed(visibleStates, "Visible", GUILayout.Width(53)); if (newIsNoCSG != isNoCSG) { foreach (BrushBase brush in brushes) { Undo.RecordObject(brush, "Change Brush NoCSG Mode"); brush.IsNoCSG = newIsNoCSG; } // Tell the brushes that they have changed and need to recalc intersections foreach (BrushBase brush in brushes) { brush.Invalidate(true); } EditorApplication.RepaintHierarchyWindow(); } if (newHasCollision != hasCollision) { foreach (BrushBase brush in brushes) { Undo.RecordObject(brush, "Change Brush Collision Mode"); brush.HasCollision = newHasCollision; } // Tell the brushes that they have changed and need to recalc intersections foreach (BrushBase brush in brushes) { brush.Invalidate(true); } } if (newIsVisible != isVisible) { foreach (BrushBase brush in brushes) { Undo.RecordObject(brush, "Change Brush Visible Mode"); brush.IsVisible = newIsVisible; } // Tell the brushes that they have changed and need to recalc intersections foreach (BrushBase brush in brushes) { brush.Invalidate(true); } if (newIsVisible == false) { csgModel.NotifyPolygonsRemoved(); } } } } GUILayout.Space(10); // Position snapping UI CurrentSettings.PositionSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.PositionSnappingEnabled, "Pos Snapping"); CurrentSettings.PositionSnapDistance = EditorGUILayout.FloatField(CurrentSettings.PositionSnapDistance, GUILayout.Width(50)); if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft)) { CurrentSettings.ChangePosSnapDistance(.5f); } if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight)) { CurrentSettings.ChangePosSnapDistance(2f); } // Rotation snapping UI CurrentSettings.AngleSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.AngleSnappingEnabled, "Ang Snapping"); CurrentSettings.AngleSnapDistance = EditorGUILayout.FloatField(CurrentSettings.AngleSnapDistance, GUILayout.Width(50)); if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft)) { if (CurrentSettings.AngleSnapDistance > 15) { CurrentSettings.AngleSnapDistance -= 15; } else { CurrentSettings.AngleSnapDistance -= 5; } } if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight)) { if (CurrentSettings.AngleSnapDistance >= 15) { CurrentSettings.AngleSnapDistance += 15; } else { CurrentSettings.AngleSnapDistance += 5; } } GUILayout.FlexibleSpace(); if (SabreGUILayout.Button("Prefs")) { SabreCSGPreferences.CreateAndShow(); } if (SabreGUILayout.Button("Disable")) { Selection.activeGameObject = null; csgModel.EditMode = false; } GUILayout.EndHorizontal(); }
public void SetSelection(GameObject selectedGameObject, GameObject[] selectedGameObjects) { // Find the selected brush bases List <BrushBase> brushBases = new List <BrushBase>(); for (int i = 0; i < Selection.gameObjects.Length; i++) { BrushBase matchedBrushBase = Selection.gameObjects[i].GetComponent <BrushBase>(); // If we've selected a brush base that isn't a prefab in the project if (matchedBrushBase != null #if UNITY_2018_2_OR_NEWER && !(PrefabUtility.GetCorrespondingObjectFromSource(matchedBrushBase.gameObject) == null #else && !(PrefabUtility.GetPrefabParent(matchedBrushBase.gameObject) == null #endif #if !UNITY_2018_3_OR_NEWER && PrefabUtility.GetPrefabObject(matchedBrushBase.transform) != null)) #else && PrefabUtility.GetPrefabInstanceHandle(selectedGameObject.transform) != null)) #endif { brushBases.Add(matchedBrushBase); } } // Also find an array of brushes (brush bases that aren't primitive brushes will have a null entry) PrimitiveBrush[] primitiveBrushes = brushBases.Select(item => item.GetComponent <PrimitiveBrush>()).ToArray(); // Pick out the first brush base and primitive brush (or null if none) BrushBase newPrimaryBrushBase = null; PrimitiveBrush newPrimaryBrush = null; // Make sure it's not null and that it isn't a prefab in the project if (selectedGameObject != null #if UNITY_2018_2_OR_NEWER && !(PrefabUtility.GetCorrespondingObjectFromSource(selectedGameObject) == null #else && !(PrefabUtility.GetPrefabParent(selectedGameObject) == null #endif #if !UNITY_2018_3_OR_NEWER && PrefabUtility.GetPrefabObject(selectedGameObject.transform) != null)) #else && PrefabUtility.GetPrefabInstanceHandle(selectedGameObject.transform) != null)) #endif { newPrimaryBrushBase = selectedGameObject.GetComponent <BrushBase>(); // brushBases.FirstOrDefault(); newPrimaryBrush = selectedGameObject.GetComponent <PrimitiveBrush>(); // primitiveBrushes.Where(item => item != null).FirstOrDefault(); } // If the primary brush base has changed if (primaryTargetBrushBase != newPrimaryBrushBase || (primaryTargetBrushBase == null && newPrimaryBrushBase != null)) // Special case for undo where references are equal but one is null { primaryTargetBrushBase = newPrimaryBrushBase; if (newPrimaryBrushBase != null) { primaryTargetBrushTransform = newPrimaryBrushBase.transform; } else { primaryTargetBrushTransform = null; } ResetTool(); } BrushBase[] brushBasesArray = brushBases.ToArray(); primaryTargetBrush = newPrimaryBrush; if (!targetBrushBases.ContentsEquals(brushBasesArray)) { OnSelectionChanged(); targetBrushBases = brushBasesArray; targetBrushes = primitiveBrushes; targetBrushTransforms = new Transform[brushBasesArray.Length]; for (int i = 0; i < brushBasesArray.Length; i++) { if (brushBasesArray[i] != null) { targetBrushTransforms[i] = brushBasesArray[i].transform; } else { targetBrushTransforms[i] = null; } } } }
/// <summary> /// Flips brushes along the provided axis /// </summary> /// <param name="primaryTargetBrush">The brush considered to be the pivot brush, for use when localToPrimaryBrush is true</param> /// <param name="targetBrushes">All brushes to be flipped</param> /// <param name="axisIndex">Index of the axis component to flip along, 0 = X, 1 = Y, 2 = Z</param> /// <param name="localToPrimaryBrush">Whether the axis to flip in is local to the primary brush's rotation, if false global orientation is used</param> /// <param name="flipCenter">The point in world space at which to flip the geometry around</param> public static void Flip(BrushBase primaryTargetBrush, BrushBase[] targetBrushes, int axisIndex, bool localToPrimaryBrush, Vector3 flipCenter) { foreach (Brush brush in targetBrushes) { Polygon[] polygons = brush.GetPolygons(); for (int i = 0; i < polygons.Length; i++) { for (int j = 0; j < polygons[i].Vertices.Length; j++) { Vertex vertex = polygons[i].Vertices[j]; Vector3 position = vertex.Position; Vector3 normal = vertex.Normal; if (localToPrimaryBrush) { // Rotate the position and normal to be relative to the primary brush's local space position = primaryTargetBrush.transform.InverseTransformDirection(brush.transform.TransformDirection(position)); normal = primaryTargetBrush.transform.InverseTransformDirection(brush.transform.TransformDirection(normal)); } else { // Rotate the position and normal to be relative to the global axis orientation position = brush.transform.TransformDirection(position); normal = brush.transform.TransformDirection(normal); } // Flip in relevant axis position[axisIndex] = -position[axisIndex]; normal[axisIndex] = -normal[axisIndex]; if (localToPrimaryBrush) { // Rotate the position and normal from the primary brush's local space back to the brush's local space position = brush.transform.InverseTransformDirection(primaryTargetBrush.transform.TransformDirection(position)); normal = brush.transform.InverseTransformDirection(primaryTargetBrush.transform.TransformDirection(normal)); } else { // Rotate the position and normal from the global axis orientation back to the brush's original local space position = brush.transform.InverseTransformDirection(position); normal = brush.transform.InverseTransformDirection(normal); } // Set the vertex position and normal to their new values vertex.Position = position; vertex.Normal = normal; } // Because a flip has occurred we need to reverse the winding order Array.Reverse(polygons[i].Vertices); // Polygon plane has probably changed so it should now be recalculated polygons[i].CalculatePlane(); } if (targetBrushes.Length > 0) // Only need to move brushes if there's more than one { // Calculate the difference between the brush position and the center of flipping Vector3 deltaFromCenter = brush.transform.position - flipCenter; if (localToPrimaryBrush) { // Rotate the delta so that it's in the primary brush's local space deltaFromCenter = primaryTargetBrush.transform.InverseTransformDirection(deltaFromCenter); } // Negate the delta, so that the brush position will be flipped to the other side deltaFromCenter[axisIndex] = -deltaFromCenter[axisIndex]; if (localToPrimaryBrush) { // Rotate the delta back to its original space deltaFromCenter = primaryTargetBrush.transform.TransformDirection(deltaFromCenter); } // Set the brush's new position brush.transform.position = flipCenter + deltaFromCenter; } // Notify the brush that it has changed brush.Invalidate(true); } }
public sealed override void OnInspectorGUI() { // group editing: if (ShowGroupInspector) { using (new NamedVerticalScope("Group")) { GUILayout.BeginHorizontal(); // find whether we are currently inside of a group: GroupBrush group = null; if (BrushTarget.transform.parent) { group = BrushTarget.transform.parent.GetComponent <GroupBrush>(); } // we are in a group: if (group != null) { if (GUILayout.Button("Select Group")) { // select the group. Selection.objects = new Object[] { BrushTarget.transform.parent.gameObject }; } } if (GUILayout.Button("Create Group")) { // create a group. TransformHelper.GroupSelection(); } GUILayout.EndHorizontal(); } } // volume editing: if (BrushTargets.Any(b => b.Mode == CSGMode.Volume)) { using (new NamedVerticalScope("Volume")) { // find all of the volume types in the project: List <System.Type> volumeTypes = Volume.FindAllInAssembly(); if (volumeTypes.Count == 0) { EditorGUILayout.LabelField("No volume types could be found!"); } else { // find all of the volume brushes that are currently selected. BrushBase[] volumeBrushes = BrushTargets.Where(b => b.Mode == CSGMode.Volume).ToArray(); BrushBase volumeTarget = volumeBrushes.Contains(BrushTarget) ? BrushTarget : volumeBrushes.Last(); // make sure all volume brushes are of the same type (for multi-editing). object brushTargetVolumeType = volumeTarget.Volume ? volumeTarget.Volume.GetType() : null; if (volumeBrushes.Length > 1 && !volumeBrushes.All(b => b.Volume.GetType() == brushTargetVolumeType)) { EditorGUILayout.LabelField("Cannot multi-edit volumes of different types!"); } else { // let the user pick a volume type: int selected = 0; if (volumeTarget.Volume != null) { for (int i = 0; i < volumeTypes.Count; i++) { selected = i; if (volumeTarget.Volume.GetType() == volumeTypes[i]) { break; } } } selected = EditorGUILayout.Popup("Volume Type", selected, volumeTypes.Select(v => v.Name + " (" + v.Namespace + ")").ToArray()); // set the brush volume type: for (int i = 0; i < volumeBrushes.Length; i++) { BrushBase target = volumeBrushes[i]; // if the brush does not have a volume yet or the wrong one, create the selected type now: if (target.Volume == null || target.Volume.GetType() != volumeTypes[selected]) { target.Volume = (Volume)ScriptableObject.CreateInstance(volumeTypes[selected]); if (serializedObject.targetObject != null) { serializedObject.ApplyModifiedProperties(); System.Array.ForEach(volumeBrushes, item => item.Invalidate(true)); } } } // custom volume inspector: if (volumeTarget.Volume.OnInspectorGUI(volumeBrushes.Select(b => b.Volume).ToArray())) { if (serializedObject.targetObject != null) { serializedObject.ApplyModifiedProperties(); System.Array.ForEach(volumeBrushes, item => item.Invalidate(true)); } } } } } } // custom inspector: DoInspectorGUI(); // generic brush editing: using (new NamedVerticalScope("Order")) { List <BrushBase> orderedTargets = BrushTargets.ToList(); orderedTargets.RemoveAll(item => (item == null)); orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex())); if (GUILayout.Button("Set As First")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsFirstSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Earlier")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); if (siblingIndex > 0) { Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex--; thisBrush.transform.SetSiblingIndex(siblingIndex); } } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Later")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex++; thisBrush.transform.SetSiblingIndex(siblingIndex); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Set As Last")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsLastSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (serializedObject.targetObject != null) { serializedObject.ApplyModifiedProperties(); } } }
public sealed override void OnInspectorGUI() { // group editing: if (ShowGroupInspector) { using (new NamedVerticalScope("Group")) { GUILayout.BeginHorizontal(); // find whether we are currently inside of a group: GroupBrush group = null; if (BrushTarget.transform.parent) { group = BrushTarget.transform.parent.GetComponent <GroupBrush>(); } // we are in a group: if (group != null) { if (GUILayout.Button("Select Group")) { // select the group. Selection.objects = new Object[] { BrushTarget.transform.parent.gameObject }; } } if (GUILayout.Button("Create Group")) { // create a group. TransformHelper.GroupSelection(); } GUILayout.EndHorizontal(); } } // custom inspector: DoInspectorGUI(); // generic brush editing: using (new NamedVerticalScope("Order")) { List <BrushBase> orderedTargets = BrushTargets.ToList(); orderedTargets.RemoveAll(item => (item == null)); orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex())); if (GUILayout.Button("Set As First")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsFirstSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Earlier")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); if (siblingIndex > 0) { Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex--; thisBrush.transform.SetSiblingIndex(siblingIndex); } } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Later")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex++; thisBrush.transform.SetSiblingIndex(siblingIndex); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Set As Last")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsLastSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (serializedObject.targetObject != null) { serializedObject.ApplyModifiedProperties(); } } }
public override void OnInspectorGUI() { using (new NamedVerticalScope("Order")) { List <BrushBase> orderedTargets = BrushTargets.ToList(); orderedTargets.RemoveAll(item => (item == null)); orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex())); if (GUILayout.Button("Set As First")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsFirstSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Earlier")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); if (siblingIndex > 0) { Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex--; thisBrush.transform.SetSiblingIndex(siblingIndex); } } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Send Later")) { for (int i = 0; i < orderedTargets.Count; i++) { // REVERSED BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i]; int siblingIndex = thisBrush.transform.GetSiblingIndex(); Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); siblingIndex++; thisBrush.transform.SetSiblingIndex(siblingIndex); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (GUILayout.Button("Set As Last")) { for (int i = 0; i < orderedTargets.Count; i++) { BrushBase thisBrush = orderedTargets[i]; Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order"); thisBrush.transform.SetAsLastSibling(); } // Force all the brushes to recalculate their intersections and get ready for rebuilding for (int i = 0; i < orderedTargets.Count; i++) { if (orderedTargets[i] is PrimitiveBrush) { ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections(); ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt(); } } } if (serializedObject.targetObject != null) { serializedObject.ApplyModifiedProperties(); } } }