public void GoPrefab()
 {
     currMode = BrushMode.PREFAB;
     ItemList.SetActive(true);
     activeObj = holders[(int)currObj];
     activeObj.SetActive(true);
 }
Exemplo n.º 2
0
 private void BrushModeConnect(SpriteButton spriteButton, BrushMode brushMode)
 {
     spriteButton.Button.Connect("pressed", this, nameof(SetBrushModeInternal),
                                 new Godot.Collections.Array {
         brushMode
     });
 }
Exemplo n.º 3
0
        private void pictureFfRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (pictureFfRadioButton.Checked == false)
            {
                return;
            }

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                bMode            = BrushMode.FillWithPicture;
                floodFillPicture = new Bitmap(openFileDialog1.FileName);
            }
            else
            {
                pictureFfRadioButton.Checked = false;
                switch (bMode)
                {
                case BrushMode.Paint:
                    paintingRadioButton.Checked = true;
                    break;

                case BrushMode.Fill:
                    fillRadioButton.Checked = true;
                    break;

                case BrushMode.FillWithPicture:
                    pictureFfRadioButton.Checked = true;
                    break;

                default:
                    break;
                }
            }
        }
Exemplo n.º 4
0
        public bool OnSceneGUI(BrushMode brushMode, RaycastHit raycastHit, out bool applyPhysics)
        {
            applyPhysics = false;

            switch (brushMode)
            {
            case BrushMode.ShiftPressed:

                Attract(raycastHit);

                // don't consume event; mustn't be consumed during layout or repaint
                //Event.current.Use();

                applyPhysics = true;
                return(true);

            case BrushMode.ShiftCtrlPressed:

                Repell(raycastHit);

                // don't consume event; mustn't be consumed during layout or repaint
                //Event.current.Use();

                applyPhysics = true;
                return(true);
            }

            return(false);
        }
Exemplo n.º 5
0
 private void paintingRadioButton_CheckedChanged(object sender, EventArgs e)
 {
     if (paintingRadioButton.Checked)
     {
         bMode = BrushMode.Paint;
     }
 }
Exemplo n.º 6
0
        private void brushItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var clickedItem = (ToolStripMenuItem)sender;

            foreach (var item in brushToolStripMenuItem.DropDownItems.OfType <ToolStripMenuItem>())
            {
                item.Checked = false;
            }

            clickedItem.Checked = true;

            if (clickedItem == noneToolStripMenuItem)
            {
                _brush = BrushMode.None;
            }
            else if (clickedItem == drawToolStripMenuItem)
            {
                _brush = BrushMode.Draw;
            }
            else if (clickedItem == removeToolStripMenuItem)
            {
                _brush = BrushMode.Remove;
            }
            else if (clickedItem == originToolStripMenuItem)
            {
                _brush = BrushMode.Origin;
            }
            else if (clickedItem == obstacleToolStripMenuItem)
            {
                _brush = BrushMode.Obstacle;
            }
        }
Exemplo n.º 7
0
 public Brush(BrushMode m, float r, Color c, float a)
 {
     mode   = m;
     radius = r;
     color  = c;
     anim   = a;
 }
Exemplo n.º 8
0
        private void MapEditorMain_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
            case Keys.Q:
                CurrentBrush = BrushMode.Select;
                break;

            case Keys.W:
                CurrentBrush = BrushMode.Paint;
                break;

            case Keys.E:
                CurrentBrush = BrushMode.Move;
                break;

            case Keys.R:
                CurrentBrush = BrushMode.Rotate;
                break;

            case Keys.D:
                CurrentBrush = BrushMode.Delete;
                break;

            case Keys.Escape:
                Manager.Project.SelectedInstance = null;
                break;
            }
        }
Exemplo n.º 9
0
 private void fillRadioButton_CheckedChanged(object sender, EventArgs e)
 {
     if (fillRadioButton.Checked)
     {
         bMode = BrushMode.Fill;
     }
 }
Exemplo n.º 10
0
 public void SelectBrushMode(int mode)
 {
     for (var i = 0; i < BrushOptions.Length; i++)
     {
         BrushOptions[i].SetActive(i == mode);
     }
     Mode = (BrushMode)mode;
     Debug.Log("Mode is now " + Mode);
 }
Exemplo n.º 11
0
 private void StartListening(BrushMode brushMode)
 {
     StopListening();
     gameObject.SetActive(true);
     buttonB_down = StartCoroutine(WaitForButtonB_Down(brushMode));
     if (brushMode != BrushMode.Color)
     {
         buttonA_down = StartCoroutine(WaitForButtonA_Down()); // automaticaly delele
     }
 }
Exemplo n.º 12
0
 /// <summary>
 /// Sets the starting and ending points of the radial gradient, and forces <c>MarkerBrushMode</c> to <c>BrushMode.RadialGradient</c>.
 /// </summary>
 /// <param name="startPoint">Starting point.</param>
 /// <param name="endPoint">Outer color.</param>
 public void SetRadialGradientPoints(PointF startPoint, PointF endPoint)
 {
     if (brushMode != BrushMode.LinearGradient || this.point1 != startPoint || this.point2 != endPoint)
     {
         this.point1 = startPoint;
         this.point2 = endPoint;
         brushMode   = BrushMode.RadialGradient;
         ClearBrush();
         Redraw();
     }
 }
Exemplo n.º 13
0
 /// <summary>
 /// Sets the hatched foreground and background colors, and forces <c>MarkerBrushMode</c> to <c>BrushMode.Hatch</c>.
 /// </summary>
 /// <param name="foreColor">Foreground color.</param>
 /// <param name="backColor">Background color.</param>
 public void SetHatchColors(Color foreColor, Color backColor)
 {
     if (brushMode != BrushMode.Hatch || foreColor.ToArgb() != color1.ToArgb() || backColor.ToArgb() != color2.ToArgb())
     {
         color1    = foreColor;
         color2    = backColor;
         brushMode = BrushMode.Hatch;
         ClearBrush();
         Redraw();
     }
 }
Exemplo n.º 14
0
 private void brushChangeToEraser()
 {
     //すでに消しゴムが選択されていたら何もしない
     if (brushMode == BrushMode.ERASER)
     {
         return;
     }
     playerPainter.erase  = true;
     brushMode            = BrushMode.ERASER;
     targetImageUI.sprite = eraserSprite;
 }
Exemplo n.º 15
0
 /// <summary>
 /// Sets the radial gradient starting and ending colors, and forces <c>MarkerBrushMode</c> to <c>BrushMode.RadialGradient</c>.
 /// </summary>
 /// <param name="startColor">Color of marker at starting point of gradient.</param>
 /// <param name="endColor">Color of marker at ending point of gradient.</param>
 public void SetRadialGradientColors(Color startColor, Color endColor)
 {
     if (brushMode != BrushMode.RadialGradient || startColor.ToArgb() != color1.ToArgb() || endColor.ToArgb() != color2.ToArgb())
     {
         color1    = startColor;
         color2    = endColor;
         brushMode = BrushMode.RadialGradient;
         ClearBrush();
         Redraw();
     }
 }
Exemplo n.º 16
0
 private void brushChangeToPen()
 {
     //すでにペンが選択されていたら何もしない
     if (brushMode == BrushMode.PEN)
     {
         return;
     }
     playerPainter.erase  = false;
     brushMode            = BrushMode.PEN;
     targetImageUI.sprite = penSprite;
 }
Exemplo n.º 17
0
 /// <summary>
 /// Sets the linear gradient start and end colors, and forces <c>MarkerBrushMode</c> to <c>BrushMode.LinearGradient</c>.
 /// </summary>
 /// <param name="startColor">Start color.</param>
 /// <param name="endColor">End color.</param>
 public void SetLinearGradientColors(Color startColor, Color endColor)
 {
     if (brushMode != BrushMode.LinearGradient || startColor.ToArgb() != color1.ToArgb() || endColor.ToArgb() != color2.ToArgb())
     {
         this.color1 = startColor;
         this.color2 = endColor;
         brushMode   = BrushMode.LinearGradient;
         ClearBrush();
         Redraw();
     }
 }
Exemplo n.º 18
0
        private void brushItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var clickedItem = (ToolStripMenuItem) sender;
            foreach (var item in brushToolStripMenuItem.DropDownItems.OfType<ToolStripMenuItem>())
                item.Checked = false;

            clickedItem.Checked = true;

            if (clickedItem == selectToolStripMenuItem) _brush = BrushMode.Select;
            else if (clickedItem == drawToolStripMenuItem) _brush = BrushMode.Draw;
            else if (clickedItem == obstacleToolStripMenuItem) _brush = BrushMode.Obstacle;
        }
Exemplo n.º 19
0
        private IEnumerator WaitForButtonB_Down(BrushMode brushMode)
        {
            while (true)
            {
                if (OVRInput.GetDown(buttonB))
                {
                    StopCoroutine(buttonB_down);
                    mode       = brushMode;
                    buttonB_up = StartCoroutine(WaitForButtonB_Up(brushMode));
                }

                yield return(new WaitForEndOfFrame());
            }
        }
Exemplo n.º 20
0
        private IEnumerator WaitForButtonA_Up()
        {
            while (true)
            {
                if (OVRInput.GetUp(buttonA))
                {
                    StopCoroutine(buttonA_up);
                    mode         = BrushMode.Inactive;
                    buttonA_down = StartCoroutine(WaitForButtonA_Down());
                }

                yield return(new WaitForEndOfFrame());
            }
        }
Exemplo n.º 21
0
 public void SetBrushOptions(LineData LineData)
 {
     brushType          = LineData.brushType;
     brushMode          = LineData.brushMode;
     OneSided           = LineData.isOneSided;
     Flat               = LineData.isFlat;
     taperOpacity       = LineData.taperOpacity;
     taperShape         = LineData.taperShape;
     ConstantSize       = LineData.constantWidth;
     MultiLine          = LineData.multiLine;
     Web                = LineData.isWeb;
     ObjectSpaceTexture = LineData.isObjectSpaceTex;
     TextureIndex       = LineData.textureIndex;
     FacingDir          = LineData.cameraOrientations.Count > 0 ? LineData.cameraOrientations[0].Q * Vector3.forward : Vector3.forward;
 }
Exemplo n.º 22
0
 private void lbPlaceables_MouseClick(object sender, MouseEventArgs e)
 {
     if (e.Button == MouseButtons.Left)
     {
         if (CurrentBrush == BrushMode.Paint && lbPlaceables.SelectedIndex > -1)
         {
             if (Manager.Room != null)
             {
                 Manager.Project.Instance = Manager.Project.GmsResourceObjectList[lbPlaceables.SelectedIndex];
                 CurrentBrush             = BrushMode.Paint;
                 brushObjectLabel.Text    = Manager.Project.Instance.name;
                 //brushObjectSprite.Image = GraphicsManager.Sprites[Manager.Project.Instance.textureId];
             }
         }
     }
 }
Exemplo n.º 23
0
        internal void changeBrush(BrushMode nextMode)
        {
            switch (nextMode)
            {
            case BrushMode.PEN:
                brushChangeToPen();
                break;

            case BrushMode.ERASER:
                brushChangeToEraser();
                break;

            default:
                break;
            }
        }
Exemplo n.º 24
0
        public void ChangeBrushMode(BrushMode mode)
        {
            CurrentBrushMode = mode;
            switch (mode)
            {
            case BrushMode.Build:
                LevelEditor.ButtonBar.OnBrushButtonClicked();
                break;

            case BrushMode.Erase:
                LevelEditor.ButtonBar.OnEraserButtonClicked();
                break;

            case BrushMode.Select:
                LevelEditor.ButtonBar.OnSelectButtonClicked();
                break;

            default:
                break;
            }
        }
Exemplo n.º 25
0
        private void lbRooms_DoubleClick(object sender, EventArgs e)
        {
            int select = lbRooms.SelectedIndex;

            if (select > -1)
            {
                if (Manager.Room != null)
                {
                    if (Manager.Project.GmsResourceRoomList[select] == Manager.Project.Room)
                    {
                        return;
                    }
                    if (MessageBox.Show("Do you want to close current room?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                    {
                        return;
                    }
                }

                Manager.Project.Room = Manager.Project.GmsResourceRoomList[select];
                //if (Manager.Project.Room.LastUsedLayer > -1 && Manager.Project.Room.LastUsedLayer < tbLayerDropDown.Items.Count)
                //{
                Manager.Project.Room.LastUsedLayer = Math.Max(0, Math.Min(Manager.Project.Room.LastUsedLayer, tbLayerDropDown.Items.Count - 1));
                tbLayerDropDown.SelectedIndex      = Manager.Project.Room.LastUsedLayer;

                //}

                if (Manager.Project.GmsResourceObjectList.Count > 0)
                {
                    Manager.Project.Instance = Manager.Project.GmsResourceObjectList[0];
                }
                roomEditor1.Invalidate();
                roomEditor1._rPanel.Invalidate();
                ensureButtonsDisabled();
                CurrentBrush = BrushMode.Select;
                Manager.Project.regenerateInstanceList();

                _afterRoomChange();
            }
        }
Exemplo n.º 26
0
	void EnableMenu()
	{
		brushDirection = true;
		brushMode = BrushMode.Off;
		brushSettingsFoldout = false;
		rotationFoldout = false;
		scaleFoldout = false;
		groupObjects = false;
		selectedPrefabIndex = -1;
		
		LoadSettings();
	}
Exemplo n.º 27
0
 public static Offset <BrushSettings> CreateBrushSettings(FlatBufferBuilder builder, BrushType BrushType, BrushMode BrushMode, bool IsOneSided, bool IsFlat, bool TaperOpacity, bool TaperShape, bool ConstantWidth, bool MultiLine, bool IsWeb, bool IsObjectSpaceTex, int TextureIndex)
 {
     builder.Prep(4, 16);
     builder.PutInt(TextureIndex);
     builder.PutBool(IsObjectSpaceTex);
     builder.PutBool(IsWeb);
     builder.PutBool(MultiLine);
     builder.PutBool(ConstantWidth);
     builder.PutBool(TaperShape);
     builder.PutBool(TaperOpacity);
     builder.PutBool(IsFlat);
     builder.PutBool(IsOneSided);
     builder.PutShort((short)BrushMode);
     builder.PutShort((short)BrushType);
     return(new Offset <BrushSettings>(builder.Offset));
 }
Exemplo n.º 28
0
        void BrushMode_PrecisionPlacement() // Mode for the precise placement of single meshes.
        {
            for (int i = 0; i < _mp.setOfMeshesToPaint.Count; i++)
            {
                // Here the user can choose to cancel the precision placement mode and return to 
                // the regular painting mode by pressing escape. The same happens (in conjuction
                // with an error dialog) if the user forgets to assign one or more fields in the set of meshes to paint.
                if (_mp.setOfMeshesToPaint[i] == null || (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape))
                {
                    if (_mp.setOfMeshesToPaint[i] == null)
                        EditorUtility.DisplayDialog("Warning!", "One or more fields in the set of meshes to paint is empty. Please assign something to all fields before painting.", "Okay");

                    if (previewObj != null)
                    {
                        DestroyImmediate(previewObj);
                        previewObj = null;
                    }
                    _phase = 0;
                    lastMousePos = Vector2.zero;
                    brushMode = BrushMode.MeshPaint;

                    Repaint();
                    return;
                }
            }

            if (Selection.gameObjects.Length == 1 && Selection.activeGameObject.transform == thisTransform)
            {
                int layer = _mp.setOfMeshesToPaint[_i].layer;
                scRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

                if (_mp.globalPaintingMode ? Physics.Raycast(scRay, out scHit, Mathf.Infinity, globalPaintLayerMask) : thisCollider.Raycast(scRay, out scHit, Mathf.Infinity))
                {
                    SceneView.RepaintAll();

                    // Initiate the preview mesh object...
                    if (previewObj == null)
                    {
                        previewObj = (GameObject)PrefabUtility.InstantiatePrefab(_mp.setOfMeshesToPaint[_i]);
                        previewObj.transform.position = scHit.point;
                        previewObj.transform.rotation = Quaternion.identity;

                        previewObj.name = "Preview";
                        previewObj.layer = 2;
                        previewObj.transform.parent = _mp.holderObj;

                        if (_mp.autoStatic) previewObj.isStatic = true;
                    }

                    // Cycle through the set of meshes to paint 
                    // and select a GameObject to place with the left and right arrow keys.
                    if (_mp.setOfMeshesToPaint.Count > 1)
                    {
                        if (Event.current.type == EventType.KeyDown && _phase < 1)
                            switch (Event.current.keyCode)
                            {
                                case KeyCode.B:
                                    _i--;
                                    if (previewObj != null)
                                    {
                                        DestroyImmediate(previewObj);
                                        previewObj = null;
                                    }
                                    break;
                                case KeyCode.N:
                                    _i++;
                                    if (previewObj != null)
                                    {
                                        DestroyImmediate(previewObj);
                                        previewObj = null;
                                    }
                                    break;
                            }

                        if (_i < 0) _i = _mp.setOfMeshesToPaint.Count - 1;
                        if (_i >= _mp.setOfMeshesToPaint.Count) _i = 0;
                    }
                    else _i = 0;
                    _i = Mathf.Clamp(_i, 0, _mp.setOfMeshesToPaint.Count - 1);
                }

                switch (_phase)
                {
                    case 0:
                        // Choose a precise location for the mesh inside the scene view.
                        if (previewObj != null)
                        {
                            previewObj.transform.position = scHit.point;
                            Handles.Label(scHit.point + Vector3.right + Vector3.up, "Currently selected: " + _mp.setOfMeshesToPaint[_i].name + "\nSelect next: [N]  /  Select previous: [B]\nConfirm location: [" + _mp.paintKey + "]  /  Cancel placement: [ESC]", EditorStyles.helpBox);
                        }

                        // Confirm placement location and go to the next phase.
                        if (Event.current.type == EventType.KeyDown && Event.current.keyCode == _mp.paintKey)
                        {
                            previewY = scHit.point.y;
                            lastMousePos = Event.current.mousePosition;
                            _phase = 1;
                        }

                        break;
                    case 1:
                        // Adjust the scale by dragging around the mouse.
                        if (previewObj != null)
                        {
                            previewObj.transform.localScale = Vector3.one * (lastMousePos - Event.current.mousePosition).magnitude * 0.01f;
                            Handles.Label(scHit.point + Vector3.right + Vector3.up, "Currently selected: " + _mp.setOfMeshesToPaint[_i].name + "\nAdjust the scale by dragging the mouse away from the center\nConfirm scale: [" + _mp.paintKey + "]  /  Cancel placement: [ESC]", EditorStyles.helpBox);
                        }

                        // Confirm the adjusted scale and move over to the rotation phase.
                        if (Event.current.type == EventType.KeyDown && Event.current.keyCode == _mp.paintKey)
                        {
                            lastMousePos = Event.current.mousePosition;
                            _phase = 2;
                        }

                        break;
                    case 2:
                        // Adjust the rotation (along the Y axis) by dragging aroung the mouse. 
                        if (previewObj != null)
                        {
                            float yRot = (lastMousePos - Event.current.mousePosition).x;
                            if (yRot < -360.0f) yRot += 360.0f;
                            if (yRot > 360.0f) yRot -= 360.0f;

                            previewObj.transform.eulerAngles = new Vector3(previewObj.transform.eulerAngles.x, yRot, previewObj.transform.eulerAngles.z);

                            Handles.Label(scHit.point + Vector3.right + Vector3.up, "Currently selected: " + _mp.setOfMeshesToPaint[_i].name + "\nAdjust the rotation along the Y-Axis by dragging your mouse horizontally\nConfirm rotation: [" + _mp.paintKey + "]  /  Cancel placement: [ESC]", EditorStyles.helpBox);
                        }

                        // Confirm the adjusted rotation and move to the last phase: vertical offset.
                        if (Event.current.type == EventType.KeyDown && Event.current.keyCode == _mp.paintKey)
                        {
                            lastMousePos = Event.current.mousePosition;
                            _phase = 3;
                        }

                        break;
                    case 3:
                        // In this step of the placement we adjust the vertical offset along the local Y axis.
                        if (previewObj != null)
                        {
                            previewObj.transform.position = new Vector3(previewObj.transform.position.x, previewY + ((lastMousePos - Event.current.mousePosition) * 0.01f).y, previewObj.transform.position.z);
                            Handles.Label(scHit.point + Vector3.right + Vector3.up, "Currently selected: " + _mp.setOfMeshesToPaint[_i].name + "\nAdjust the offset along the Y-axis by dragging your mouse vertically\nConfirm offset: [" + _mp.paintKey + "]  /  Cancel placement: [ESC]", EditorStyles.helpBox);
                        }

                        // Final placement confirmation
                        if (Event.current.type == EventType.KeyDown && Event.current.keyCode == _mp.paintKey)
                        {
                            GameObject finalObj = (GameObject)PrefabUtility.InstantiatePrefab(_mp.setOfMeshesToPaint[_i]);

                            finalObj.transform.position = previewObj.transform.position;
                            finalObj.transform.rotation = previewObj.transform.rotation;

                            finalObj.transform.localScale = previewObj.transform.localScale;
                            finalObj.name = _mp.setOfMeshesToPaint[_i].name;
                            finalObj.layer = layer;
                            finalObj.transform.parent = _mp.holderObj;

                            if (_mp.autoStatic) finalObj.isStatic = true;

                            if (previewObj != null)
                            {
                                DestroyImmediate(previewObj);
                                previewObj = null;
                            }

                            _phase = 0;
                            lastMousePos = Vector2.zero;
                            brushMode = BrushMode.MeshPaint;

                            Repaint();
                        }
                        break;
                }
            }
        }
Exemplo n.º 29
0
        public override void OnInspectorGUI() // Works like OnGUI, except that it updates only the inspector view.
        {
            EditorGUILayout.Space();

            #region Global Painting 
            if (_mp.globalPaintingMode)
            {
                // Global painting interface:
                EditorGUILayout.BeginVertical("Box");
                {
                    // Title
                    GUI.color = new Color(3f, 1f, 0f, 1f);
                    EditorGUILayout.LabelField("MeshBrush - Global Painting Mode", EditorStyles.boldLabel);
                    GUI.color = Color.white;

                    EditorGUILayout.LabelField(new GUIContent("Layer based painting", "You have the control over where MeshBrush is allowed to paint your meshes and where not.\nMeshBrush will only paint onto objects in the scene whose layers are enabled here inside this layer selection."));

                    // Scrollbar for the layer selection
                    layersScroll = EditorGUILayout.BeginScrollView(layersScroll, false, false, GUILayout.Height(166f));
                    {
                        EditorGUILayout.BeginHorizontal();
                        {
                            EditorGUILayout.BeginVertical();
                            {
                                // Always leave the Unity built-in Ignore Raycast layer unticked.
                                _mp.globalPaintingLayers[2] = false;

                                // First column of layers (these are the built-in standard Unity layers).
                                for (int i = 0; i < 8; i++)
                                {
                                    EditorGUILayout.BeginHorizontal();
                                    {
                                        GUI.enabled = i != 2;
                                        _mp.globalPaintingLayers[i] = EditorGUILayout.Toggle(_mp.globalPaintingLayers[i], GUILayout.Width(15f));
                                        EditorGUILayout.LabelField(LayerMask.LayerToName(i), GUILayout.Width(90f));
                                        GUI.enabled = true;
                                    }
                                    EditorGUILayout.EndHorizontal();
                                }
                            }
                            EditorGUILayout.EndVertical();

                            // The next 3 vertical groups represent the second, third and fourth column of the layer selection.
                            EditorGUILayout.BeginVertical();
                            {
                                for (int i = 8; i < 16; i++)
                                {
                                    EditorGUILayout.BeginHorizontal();
                                    {
                                        _mp.globalPaintingLayers[i] = EditorGUILayout.Toggle(_mp.globalPaintingLayers[i], GUILayout.Width(15f));
                                        GUI.color = string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? new Color(0.65f, 0.65f, 0.65f, 1.0f) : Color.white;
                                        EditorGUILayout.LabelField(string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? "Layer " + i : LayerMask.LayerToName(i), GUILayout.Width(90f));
                                        GUI.color = Color.white;
                                    }
                                    EditorGUILayout.EndHorizontal();
                                }
                            }
                            EditorGUILayout.EndVertical();
                            EditorGUILayout.BeginVertical();
                            {
                                for (int i = 16; i < 24; i++)
                                {
                                    EditorGUILayout.BeginHorizontal();
                                    {
                                        _mp.globalPaintingLayers[i] = EditorGUILayout.Toggle(_mp.globalPaintingLayers[i], GUILayout.Width(15f));
                                        GUI.color = string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? new Color(0.65f, 0.65f, 0.65f, 1.0f) : Color.white;
                                        EditorGUILayout.LabelField(string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? "Layer " + i : LayerMask.LayerToName(i), GUILayout.Width(90f));
                                        GUI.color = Color.white;
                                    }
                                    EditorGUILayout.EndHorizontal();
                                }
                            }
                            EditorGUILayout.EndVertical();
                            EditorGUILayout.BeginVertical();
                            {
                                for (int i = 24; i < 32; i++)
                                {
                                    EditorGUILayout.BeginHorizontal();
                                    {
                                        _mp.globalPaintingLayers[i] = EditorGUILayout.Toggle(_mp.globalPaintingLayers[i], GUILayout.Width(15f));
                                        GUI.color = string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? new Color(0.65f, 0.65f, 0.65f, 1.0f) : Color.white;
                                        EditorGUILayout.LabelField(string.CompareOrdinal(LayerMask.LayerToName(i), string.Empty) == 0 ? "Layer " + i : LayerMask.LayerToName(i), GUILayout.Width(90f));
                                        GUI.color = Color.white;
                                    }
                                    EditorGUILayout.EndHorizontal();
                                }
                            }
                            EditorGUILayout.EndVertical();
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    EditorGUILayout.EndScrollView();

                    // Buttons to automatically select/deselect all layers.
                    EditorGUILayout.BeginHorizontal();
                    {
                        if (GUILayout.Button("All", GUILayout.Width(55f), GUILayout.Height(20f)))
                        {
                            for (int i = 0; i < _mp.globalPaintingLayers.Length; i++)
                                _mp.globalPaintingLayers[i] = true;
                        }
                        if (GUILayout.Button("None", GUILayout.Width(55f), GUILayout.Height(20f)))
                        {
                            for (int i = 0; i < _mp.globalPaintingLayers.Length; i++)
                                _mp.globalPaintingLayers[i] = false;
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();

                // If there are changes in the inspector (the toggles in the layer selection!), 
                // update the layer mask for global painting.
                if (GUI.changed)
                {
                    UpdatePaintLayerMask();
                }
            }
            #endregion

            EditorGUILayout.Space();

            // MAIN TOGGLE (this one can entirely turn the meshbrush on and off)
            EditorGUILayout.BeginHorizontal();
            {
                _mp.isActive = EditorGUILayout.Toggle(_mp.isActive, GUILayout.Width(15f));
                EditorGUILayout.LabelField("Enabled", GUILayout.Width(70f), GUILayout.ExpandWidth(false));
            }
            EditorGUILayout.EndHorizontal();

            // Useful textfield to name and organize your groups.
            _mp.groupName = EditorGUILayout.TextField(_mp.groupName);
            if (_mp.holderObj) _mp.holderObj.name = _mp.groupName;
            EditorGUILayout.Space();

            #region Help section
            // Foldout menu for the help section, see below for further information
            _mp.b_Help = EditorGUILayout.Foldout(_mp.b_Help, "Help");

            // The help foldout menu in the inspector.
            if (_mp.b_Help)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.HelpBox("Paint meshes onto your GameObject's surface.\n_______\n\nKeyBoard shortcuts:\n\nPaint meshes:\tpress or hold    " + _mp.paintKey + "\nDelete meshes:\tpress or hold    " + _mp.deleteKey + "\nCombine meshes:\tpress or hold    " + _mp.combineAreaKey + "\nIncrease radius:\tpress or hold    " + _mp.increaseRadiusKey + "\nDecrease radius:\tpress or hold    " + _mp.decreaseRadiusKey + "\n_______\n", MessageType.None);

                _mp.b_Help_GeneralUsage = EditorGUILayout.Foldout(_mp.b_Help_GeneralUsage, "General usage");
                if (_mp.b_Help_GeneralUsage)
                {
                    EditorGUILayout.HelpBox("Assign one or more prefab objects to the 'Set of meshes to paint' array below and press " + _mp.paintKey + " while hovering your mouse above your GameObject to start painting meshes. Press " + _mp.deleteKey + " to delete painted meshes." +
                    "\n\nMake sure that the local Y-axis of each prefab mesh is the one pointing away from the surface on which you are painting (to avoid weird rotation errors).\n\n" +
                    "Check the documentation text file that comes with MeshBrush (or the YouTube tutorials) to find out more about the individual brush parameters (but most of them should be quite self explainatory, or at least supplied with a tooltip text label after hovering your mouse over them for a couple of seconds).\n\nFeel free to add multiple MeshBrush script instances to one GameObject for multiple mesh painting sets, with defineable group names and parameters for each of them;\n" +
                    "MeshBrush will then randomly cycle through all of your MeshBrush instances and paint your meshes within the corresponding circle brush based on the corresponding parameters for that set.", MessageType.None);
                }

                _mp.b_Help_Templates = EditorGUILayout.Foldout(_mp.b_Help_Templates, "Templates");
                if (_mp.b_Help_Templates)
                {
                    EditorGUILayout.HelpBox("In the templates foldout menu you can save your favourite brush settings and setups to MeshBrush template files for later reusage.\n\nJust press the save button and name your file and path.\nTo load a template file, press the load button and load up your .meshbrush template file from disk; it's as simple as that.\n\nMeshBrush template files are xml formatted text files, so if you want, you can also open them up with notepad (or some other text editor) and change the settings from there.", MessageType.None);
                }

                _mp.b_Help_Optimization = EditorGUILayout.Foldout(_mp.b_Help_Optimization, "Optimization");
                if (_mp.b_Help_Optimization)
                {
                    EditorGUILayout.HelpBox("You can press 'Flag/Unflag all painted meshes as static' to mark/unmark as static all the meshes you've painted so far.\nFlagging painted meshes as static will improve performance overhead thanks to Unity's built-in static batching functionality, " +
                    "as long as the meshes obviously don't move (and as long as they share the same material).\nSo don't flag meshes as static if you have fancy looking animations on your prefab meshes (like, for instance, swaying animations for vegetation or similar properties that make the mesh move, rotate or scale in any way).\n_______\n\n" +
                    "Once you're done painting you can combine your meshes either with the 'Combine all painted meshes button' or by pressing " + _mp.combineAreaKey + " (this will combine all the meshes inside the brush area).\nCheck out the documentation for further information.\n\n" +
                    "If you are painting grass or other kinds of small vegetation, I recommend using the '2-Sided Vegetation' shader that comes with the MeshBrush package. It's the " +
                    "built-in Unity transparent cutout diffuse shader, just without backface culling, so that you get 2-sided materials.\nYou can obviously also use your own custom shaders if you want.", MessageType.None);
                }

                EditorGUI.indentLevel = 0;
            }
            #endregion
            GUI.enabled = _mp.isActive;

            // Templates foldout
            _mp.b_Templates = EditorGUILayout.Foldout(_mp.b_Templates, "Templates");
            if (_mp.b_Templates)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(new GUIContent((Texture)Resources.Load("MeshBrushSaveIcon"), "Save these current MeshBrush settings to a .meshbrush template file."), GUILayout.Height(55f), GUILayout.Width(55f)))
                    {
                        MeshBrushTemplate.SaveTemplate(_mp);
                    }

                    if (GUILayout.Button(new GUIContent((Texture)Resources.Load("MeshBrushLoadIcon"), "Load up a template file."), GUILayout.Height(55f), GUILayout.Width(55f)))
                    {
                        MeshBrushTemplate.LoadTemplate(_mp);
                    }
                    GUILayout.Space(2);

                    // This vertical box is dedicated to the MeshBrush templates and favourites.
                    GUILayout.BeginVertical("Box");
                    {
                        templatesScroll = EditorGUILayout.BeginScrollView(templatesScroll, false, false);
                        {
                            if (MeshBrush.favourites.Count < 1)
                                EditorGUILayout.LabelField("Favourites list is empty", EditorStyles.wordWrappedLabel);

                            for (int i = 0; i < MeshBrush.favourites.Count; i++)
                            {
                                EditorGUILayout.BeginHorizontal();
                                {
                                    if (GUILayout.Button(System.IO.Path.GetFileNameWithoutExtension(MeshBrush.favourites[i])))
                                    {
                                        if (System.IO.File.Exists(MeshBrush.favourites[i]))
                                        {
                                            if (!MeshBrushTemplate.LoadTemplate(_mp, MeshBrush.favourites[i]))
                                            {
                                                MeshBrush.favourites.RemoveAt(i);
                                                MeshBrushTemplate.SaveFavourites();
                                            }
                                        }
                                        else
                                        {
                                            EditorUtility.DisplayDialog("Failed to load template!", "The selected template file couldn't be loaded.\n\nIt's probably been renamed, deleted or moved elsewhere.\n\nThe corresponding entry in the list of favourite templates will be removed.", "Okay");

                                            MeshBrush.favourites.RemoveAt(i);
                                            MeshBrushTemplate.SaveFavourites();
                                        }
                                    }

                                    if (GUILayout.Button(new GUIContent("...", "Reassign this template"), GUILayout.Width(27f)))
                                    {
                                        string oldPath = MeshBrush.favourites[i];
                                        MeshBrush.favourites[i] = EditorUtility.OpenFilePanel("Reassignment - Select MeshBrush Template", "Assets/MeshBrush/Saved Templates", "meshbrush");

                                        // Revert back to the previous template in case the user cancels the reassignment.
                                        if (string.CompareOrdinal(MeshBrush.favourites[i], string.Empty) == 0)
                                            MeshBrush.favourites[i] = oldPath;

                                        MeshBrushTemplate.SaveFavourites();
                                    }

                                    if (GUILayout.Button(new GUIContent("-", "Removes this template from the list."), GUILayout.Width(27f)))
                                    {
                                        MeshBrush.favourites.RemoveAt(i);
                                        MeshBrushTemplate.SaveFavourites();
                                    }
                                }
                                EditorGUILayout.EndHorizontal();
                            }

                            EditorGUILayout.BeginHorizontal();
                            {
                                if (GUILayout.Button(new GUIContent("+", "You can add your favourite MeshBrush Templates here to this list."), GUILayout.Width(30f), GUILayout.Height(22f), GUILayout.ExpandWidth(false)))
                                {
                                    string path = EditorUtility.OpenFilePanel("Select favourite MeshBrush Template", "Assets/MeshBrush/Saved Templates", "meshbrush");
                                    if (string.CompareOrdinal(path, string.Empty) != 0)
                                    {
                                        MeshBrush.favourites.Add(path);
                                        MeshBrushTemplate.SaveFavourites();
                                    }
                                }

                                GUI.enabled = MeshBrush.favourites.Count > 0;
                                if (GUILayout.Button(new GUIContent("-", "Removes the bottom-most template from the list."), GUILayout.Width(30f), GUILayout.Height(22f)))
                                {
                                    if (MeshBrush.favourites.Count > 0)
                                    {
                                        MeshBrush.favourites.RemoveAt(MeshBrush.favourites.Count - 1);
                                        MeshBrushTemplate.SaveFavourites();
                                    }
                                }
                                GUI.enabled = _mp.isActive;

                                GUI.enabled = MeshBrush.favourites.Count > 0;
                                if (GUILayout.Button(new GUIContent("C", "Clears the entire favourites list."), GUILayout.Width(30f), GUILayout.Height(22f)))
                                {
                                    MeshBrush.favourites.Clear();
                                    MeshBrushTemplate.SaveFavourites();
                                }
                                GUI.enabled = _mp.isActive;
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        EditorGUILayout.EndScrollView();
                    }
                    GUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.Space(1.5f);
            }

            // The next big block of code is responsible for the set of meshes to paint ui.
            _mp.b_SetOfMeshesToPaint = EditorGUILayout.Foldout(_mp.b_SetOfMeshesToPaint, "Set of meshes to paint");
            if (_mp.b_SetOfMeshesToPaint)
            {
                // Never allow an empty set of meshes to paint.
                if (_mp.setOfMeshesToPaint.Count < 1)
                    _mp.setOfMeshesToPaint.Add(null);

                EditorGUILayout.BeginVertical("Box");
                {
                    setScroll = EditorGUILayout.BeginScrollView(setScroll, false, false, GUILayout.ExpandWidth(false), GUILayout.Height(193f));
                    {
                        for (int i = 0; i < _mp.setOfMeshesToPaint.Count; i++)
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                GUI.enabled = _mp.isActive && _mp.setOfMeshesToPaint.Count > 1;
                                if (GUILayout.Button(new GUIContent("-", "Removes this entry from the list."), GUILayout.Width(30f), GUILayout.Height(16.5f)))
                                {
                                    _mp.setOfMeshesToPaint.RemoveAt(i);
                                    continue;
                                }
                                GUI.enabled = _mp.isActive;

                                _mp.setOfMeshesToPaint[i] = (GameObject)EditorGUILayout.ObjectField(_mp.setOfMeshesToPaint[i], typeof(GameObject), false, GUILayout.Height(16.35f));
                            }
                            EditorGUILayout.EndHorizontal();
                            GUILayout.Space(2.75f);
                        }
                        EditorGUILayout.Space();
                    }
                    EditorGUILayout.EndScrollView();
                    EditorGUILayout.BeginHorizontal();
                    {
                        if (GUILayout.Button(new GUIContent("+", "Adds an entry to the list."), GUILayout.Width(30f), GUILayout.Height(22f)))
                        {
                            _mp.setOfMeshesToPaint.Add(null);
                        }

                        GUI.enabled = _mp.isActive && _mp.setOfMeshesToPaint.Count > 1;
                        if (GUILayout.Button(new GUIContent("-", "Removes the bottom row from the list."), GUILayout.Width(30f), GUILayout.Height(22f)))
                        {
                            if (_mp.setOfMeshesToPaint.Count > 1)
                            {
                                _mp.setOfMeshesToPaint.RemoveAt(_mp.setOfMeshesToPaint.Count - 1);
                            }
                        }
                        GUI.enabled = _mp.isActive;

                        GUI.enabled = _mp.isActive && _mp.setOfMeshesToPaint.Count > 0;
                        if (GUILayout.Button(new GUIContent("X", "Clears all values from all rows in the list."), GUILayout.Width(30f), GUILayout.Height(22f)))
                        {
                            if (_mp.setOfMeshesToPaint.Count > 0)
                            {
                                for (int i = 0; i < _mp.setOfMeshesToPaint.Count; i++)
                                {
                                    _mp.setOfMeshesToPaint[i] = null;
                                }
                            }
                        }
                        GUI.enabled = _mp.isActive;

                        GUI.enabled = _mp.isActive && _mp.setOfMeshesToPaint.Count > 1;
                        if (GUILayout.Button(new GUIContent("C", "Clears the list (deleting all rows at once)."), GUILayout.Width(30f), GUILayout.Height(22f)))
                        {
                            if (_mp.setOfMeshesToPaint.Count > 1)
                            {
                                _mp.setOfMeshesToPaint.Clear();
                                _mp.setOfMeshesToPaint.Add(null);
                            }
                        }
                        GUI.enabled = _mp.isActive;
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal(); // Editor version of the GUILayout.BeginHorizontal().
                    {
                        _mp.autoStatic = EditorGUILayout.Toggle(_mp.autoStatic, GUILayout.Width(15f));
                        EditorGUILayout.LabelField("Automatically flag meshes as static", GUILayout.Width(210f), GUILayout.ExpandWidth(false));
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();
                GUILayout.Space(2);

                GUI.color = brushMode == BrushMode.PrecisionPlacement ? Color.yellow : Color.white;
                if (GUILayout.Button(toolTipPrecisionPlacementMode, GUILayout.Height(38f)))
                {
                    brushMode = BrushMode.PrecisionPlacement;
                }
                GUI.color = Color.white;
            }

            _mp.b_CustomKeys = EditorGUILayout.Foldout(_mp.b_CustomKeys, "Customize Keyboard Shortcuts");
            if (_mp.b_CustomKeys)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Paint");
                    _mp.paintKey = (KeyCode)EditorGUILayout.EnumPopup(_mp.paintKey);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Delete");
                    _mp.deleteKey = (KeyCode)EditorGUILayout.EnumPopup(_mp.deleteKey);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Combine meshes");
                    _mp.combineAreaKey = (KeyCode)EditorGUILayout.EnumPopup(_mp.combineAreaKey);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Increase radius");
                    _mp.increaseRadiusKey = (KeyCode)EditorGUILayout.EnumPopup(_mp.increaseRadiusKey);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Decrease radius");
                    _mp.decreaseRadiusKey = (KeyCode)EditorGUILayout.EnumPopup(_mp.decreaseRadiusKey);
                }
                EditorGUILayout.EndHorizontal();

                if (GUILayout.Button("Reset to default keys"))
                {
                    _mp.paintKey = KeyCode.P;
                    _mp.increaseRadiusKey = KeyCode.O;
                    _mp.decreaseRadiusKey = KeyCode.I;
                }
                EditorGUILayout.Space();
            }

            if (thisCollider == null && !_mp.globalPaintingMode)
            {
                EditorGUILayout.HelpBox("This GameObject has no collider attached to it.\nMeshBrush needs a collider in order to work properly! Do you want to add a collider now?", MessageType.Error);

                if (GUILayout.Button("Yes, add a MeshCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<MeshCollider>();
                }
                if (GUILayout.Button("Yes, add a BoxCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<BoxCollider>();
                }
                if (GUILayout.Button("Yes, add a SphereCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<SphereCollider>();
                }
                if (GUILayout.Button("Yes, add a CapsuleCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<CapsuleCollider>();
                }
                if (GUILayout.Button("No, switch to global painting mode now please", GUILayout.Height(27f)))
                {
                    _mp.globalPaintingMode = true;
                }
                EditorGUILayout.Space();

                GUI.enabled = false;
            }

            // Avoid having unassigned keys in MeshBrush; 
            // reset to the default value in case the user tries to set the button to "None"
            _mp.paintKey = (_mp.paintKey == KeyCode.None) ? KeyCode.P : _mp.paintKey;
            _mp.deleteKey = (_mp.deleteKey == KeyCode.None) ? KeyCode.L : _mp.deleteKey;

            _mp.combineAreaKey = (_mp.combineAreaKey == KeyCode.None) ? KeyCode.K : _mp.combineAreaKey;

            _mp.increaseRadiusKey = (_mp.increaseRadiusKey == KeyCode.None) ? KeyCode.O : _mp.increaseRadiusKey;
            _mp.decreaseRadiusKey = (_mp.decreaseRadiusKey == KeyCode.None) ? KeyCode.I : _mp.decreaseRadiusKey;

            _mp.b_BrushSettings = EditorGUILayout.Foldout(_mp.b_BrushSettings, "Brush settings");
            if (_mp.b_BrushSettings)
            {
                // Color picker for our circle brush.
                _mp.hColor = EditorGUILayout.ColorField(toolTipColor, _mp.hColor);

                EditorGUILayout.BeginHorizontal();
                {
                    // Radius value
                    _mp.hRadius = EditorGUILayout.FloatField(toolTipRadius, _mp.hRadius, GUILayout.Width(175f), GUILayout.ExpandWidth(true));

                    // Random mesh count toggle
                    _mp.useRandomMeshCount = EditorGUILayout.Toggle(_mp.useRandomMeshCount, GUILayout.Width(15f));

                    EditorGUILayout.LabelField(new GUIContent("Use random number", "Paint a random amount of meshes per stroke (within a defined range)."), GUILayout.Width(140f));
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                // Clamp the meshcount so that it never goes below 1 or above 100.
                if (_mp.useRandomMeshCount)
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.BeginHorizontal();
                        {
                            EditorGUILayout.LabelField("Min. nr. of meshes:", GUILayout.Width(115f));
                            _mp.minNrOfMeshes = EditorGUILayout.IntField(Mathf.Clamp(_mp.minNrOfMeshes, 1, 100), GUILayout.Width(50f));
                            GUILayout.Space(3f);
                            EditorGUILayout.LabelField("Max. nr. of meshes:", GUILayout.Width(117f));
                            _mp.maxNrOfMeshes = EditorGUILayout.IntField(Mathf.Clamp(_mp.maxNrOfMeshes, 1, 100), GUILayout.Width(50f));
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    EditorGUILayout.EndHorizontal();
                }
                else
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField(toolTipNR, GUILayout.Width(140f));
                        _mp.meshCount = EditorGUILayout.IntField(Mathf.Clamp(_mp.meshCount, 1, 100), GUILayout.Width(50f));
                    }
                    EditorGUILayout.EndHorizontal();
                }

                // Avoid negative or null radii.
                if (_mp.hRadius < 0.01f) _mp.hRadius = 0.01f;
                EditorGUILayout.Space();

                // Slider for the delay between paint strokes.
                _mp.delay = EditorGUILayout.Slider(toolTipFreq, _mp.delay, 0.05f, 1.0f);
                EditorGUILayout.Space(); EditorGUILayout.Space();

                // Slider for the offset amount.
                EditorGUILayout.LabelField(toolTipOffset);
                _mp.meshOffset = EditorGUILayout.Slider(_mp.meshOffset, -50.0f, 50.0f);

                EditorGUILayout.Space();

                // Self-explanatory.
                if (_mp.meshCount <= 1 && !_mp.useRandomMeshCount)
                    GUI.enabled = false;

                // Slider for the scattering.
                EditorGUILayout.LabelField(toolTipInset);
                _mp.scattering = EditorGUILayout.Slider(_mp.scattering, 0, 100.0f);
                EditorGUILayout.Space();

                GUI.enabled = _mp.isActive;

                EditorGUILayout.BeginHorizontal();
                {
                    _mp.yAxisIsTangent = EditorGUILayout.Toggle(_mp.yAxisIsTangent, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipTangentY, GUILayout.Width(150f));
                    _mp.invertY = EditorGUILayout.Toggle(_mp.invertY, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipInvertY, GUILayout.Width(150f));
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();
            }

            _mp.b_Slopes = EditorGUILayout.Foldout(_mp.b_Slopes, "Slopes");
            if (_mp.b_Slopes)
            {
                EditorGUILayout.LabelField(toolTipSlopeInfluence);
                _mp.slopeInfluence = EditorGUILayout.Slider(_mp.slopeInfluence, 0f, 100f); // Slider for slope influence.
                EditorGUILayout.Space();

                EditorGUILayout.BeginHorizontal();
                {
                    _mp.activeSlopeFilter = EditorGUILayout.Toggle(_mp.activeSlopeFilter, GUILayout.Width(15f));
                    EditorGUILayout.LabelField("Use slope filter");
                }
                EditorGUILayout.EndHorizontal();

                if (_mp.activeSlopeFilter == false)
                    GUI.enabled = false;

                EditorGUILayout.LabelField(toolTipSlopeFilter);
                _mp.maxSlopeFilterAngle = EditorGUILayout.Slider(_mp.maxSlopeFilterAngle, 1f, 180f);


                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.inverseSlopeFilter = EditorGUILayout.Toggle(_mp.inverseSlopeFilter, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipInvSlope, GUILayout.Width(120f));
                    _mp.manualRefVecSampling = EditorGUILayout.Toggle(_mp.manualRefVecSampling, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipManualRefVecS, GUILayout.Width(200f));
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                if (_mp.manualRefVecSampling == false)
                    GUI.enabled = false;

                EditorGUILayout.BeginHorizontal();
                {
                    _mp.showRefVecInSceneGUI = EditorGUILayout.Toggle(_mp.showRefVecInSceneGUI, GUILayout.Width(15f));
                    EditorGUILayout.LabelField("Show sampled vector", GUILayout.Width(130f));

                    GUI.color = brushMode == BrushMode.Sample ? Color.yellow : Color.white;
                    if (GUILayout.Button(toolTipRefVecSample, GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                        brushMode = BrushMode.Sample;
                    GUI.color = Color.white;
                }
                EditorGUILayout.EndHorizontal();

                GUI.enabled = _mp.isActive;
                EditorGUILayout.Space();

                if (GUILayout.Button("Reset all slope settings", GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    _mp.ResetSlopeSettings();
            }

            _mp.b_Randomizers = EditorGUILayout.Foldout(_mp.b_Randomizers, "Randomize"); // This makes the little awesome arrow for the foldout menu in the inspector view appear...

            // ...and this below here makes it actually fold stuff in and out 
            // (the menu is closed if the arrow points to the right and thus rScale is false).
            if (_mp.b_Randomizers)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.uniformScale = EditorGUILayout.Toggle("", _mp.uniformScale, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipUniformly, GUILayout.Width(100f));

                    _mp.rWithinRange = EditorGUILayout.Toggle("", _mp.rWithinRange, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipWithinRange);
                }
                EditorGUILayout.EndHorizontal();

                if (_mp.uniformScale == true)
                {
                    if (_mp.rWithinRange == false)
                        _mp.rScale = EditorGUILayout.Slider("Random scale:", _mp.rScale, 0, 5f);
                    else
                    {
                        EditorGUILayout.Space();

                        EditorGUILayout.LabelField(toolTipUniformlyRange);
                        _mp.rUniformRange = EditorGUILayout.Vector2Field("", _mp.rUniformRange);
                    }
                }
                else
                {
                    if (_mp.rWithinRange == false)
                    {
                        EditorGUILayout.Space();

                        _mp.rScaleW = EditorGUILayout.Slider("Random width (X/Z)", _mp.rScaleW, 0, 3f);
                        _mp.rScaleH = EditorGUILayout.Slider("Random height (Y)", _mp.rScaleH, 0, 3f);
                    }
                    else
                    {
                        EditorGUILayout.Space();

                        EditorGUILayout.LabelField("Randomly scale within these ranges:");
                        EditorGUILayout.LabelField(toolTipV4);
                        _mp.rNonUniformRange = EditorGUILayout.Vector4Field("", _mp.rNonUniformRange);
                        EditorGUILayout.Space();
                    }
                }
                EditorGUILayout.Space();

                EditorGUILayout.LabelField(toolTipRot);

                // Create the slider for the percentage of random rotation around the Y axis applied to our painted meshes.
                _mp.rRot = EditorGUILayout.Slider(_mp.rRot, 0.0f, 100.0f);
                EditorGUILayout.Space();

                if (GUILayout.Button(toolTipReset, GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    _mp.ResetRandomizers();
            }

            _mp.b_OverlapFilter = EditorGUILayout.Foldout(_mp.b_OverlapFilter, new GUIContent("Overlap filter", "")); // TODO: description!!!
            if (_mp.b_OverlapFilter)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.useOverlapFilter = EditorGUILayout.Toggle(_mp.useOverlapFilter, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipOverlapFilter, GUILayout.Width(111.5f));

                    GUI.enabled = _mp.useOverlapFilter;

                    _mp.useRandomAbsMinDist = EditorGUILayout.Toggle(_mp.useRandomAbsMinDist, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(new GUIContent("Random value", "Pick a random value (within a defined range) for the minimum distance between painted meshes."), GUILayout.Width(90f));
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();


                if (!_mp.useRandomAbsMinDist)
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField(new GUIContent("Min. absolute distance [m]:", "The minimum absolute distance (in meters) between painted meshes."), GUILayout.Width(163f));
                        _mp.absoluteMinDist = Mathf.Abs(EditorGUILayout.FloatField(_mp.absoluteMinDist));
                    }
                    EditorGUILayout.EndHorizontal();
                }
                else
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField(new GUIContent("Min. absolute distance [m]:", "The minimum absolute distance (in meters) between painted meshes. A random value will be chosen within the range of [X, Y]."), GUILayout.Width(163f));
                        _mp.randomAbsMinDist = EditorGUILayout.Vector2Field(string.Empty, _mp.randomAbsMinDist);
                        _mp.randomAbsMinDist = new Vector2(Mathf.Abs(_mp.randomAbsMinDist.x), Mathf.Abs(_mp.randomAbsMinDist.y));
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.Space();

                if (GUILayout.Button(new GUIContent("Reset overlap filter settings", "Resets all overlap filter settings back to their default values."), GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    _mp.ResetOverlapFilterSettings();
            }
            GUI.enabled = _mp.isActive;

            // Foldout for the additive scale.
            _mp.b_AdditiveScale = EditorGUILayout.Foldout(_mp.b_AdditiveScale, toolTipAddScale);

            if (_mp.b_AdditiveScale)
            {
                _mp.constUniformScale = EditorGUILayout.Toggle(toolTipUniformly, _mp.constUniformScale);
                if (_mp.constUniformScale == true)
                    _mp.cScale = EditorGUILayout.FloatField("Add to scale", _mp.cScale);
                else
                {
                    _mp.cScaleXYZ = EditorGUILayout.Vector3Field("Add to scale", _mp.cScaleXYZ);
                }
                if (_mp.cScale < -0.9f) _mp.cScale = -0.9f;
                if (_mp.cScaleXYZ.x < -0.9f) _mp.cScaleXYZ.x = -0.9f;
                if (_mp.cScaleXYZ.y < -0.9f) _mp.cScaleXYZ.y = -0.9f;
                if (_mp.cScaleXYZ.z < -0.9f) _mp.cScaleXYZ.z = -0.9f;
                EditorGUILayout.Space();

                if (GUILayout.Button("Reset additive scale", GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                {
                    _mp.cScale = 0;
                    _mp.cScaleXYZ = Vector3.zero;
                }
                EditorGUILayout.Space();
            }

            _mp.b_Opt = EditorGUILayout.Foldout(_mp.b_Opt, "Optimize");
            if (_mp.b_Opt)
            {
                if (_mp.holderObj == null) OnEnable();
                MeshBrushParent mbp = _mp.holderObj.GetComponent<MeshBrushParent>(); ;

                // Create 2 buttons for quickly flagging/unflagging all painted meshes as static...
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(toolTipFlagS, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                        mbp.FlagMeshesAsStatic();
                    if (GUILayout.Button("Unflag all painted\nmeshes as static", GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                        mbp.UnflagMeshesAsStatic();
                }
                EditorGUILayout.EndHorizontal();

                // ...and 2 other buttons for combining and deleting.
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(toolTipCombine, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    {
                        if (_mp.holderObj != null)
                        {
                            _mp.holderObj.GetComponent<MeshBrushParent>().CombinePaintedMeshes(_mp.autoSelectOnCombine, _mp.holderObj.GetComponentsInChildren<MeshFilter>());
                        }
                    }

                    //...and one to delete all the meshes we painted on this GameObject so far.
                    if (GUILayout.Button(toolTipDelete, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                    {
                        ClearDeletionBuffer();
                        Undo.DestroyObjectImmediate(_mp.holderObj.gameObject);
                    }
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.Space(3f);
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.autoSelectOnCombine = EditorGUILayout.Toggle(new GUIContent("", "Automatically select the combined mesh GameObject after having pressed the combine button."), _mp.autoSelectOnCombine, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(new GUIContent("Auto-select combined mesh", "Automatically select the combined mesh GameObject after having pressed the combine button."));
                }
                EditorGUILayout.EndHorizontal();

            }
            EditorGUILayout.Space();


            // Repaint the scene view whenever the inspector's gui is changed in some way. 
            // This avoids weird disturbing snaps of the reference slope vector and the circle 
            // brush GUI handle inside the scene view when we return to it after changing some settings in the inspector.
            if (GUI.changed)
            {
                SceneView.RepaintAll();
                ClearPaintBuffer();
            }
        }
Exemplo n.º 30
0
	void EnableMenu()
	{
		UpdateGroups();
		LoadTempSlots();
		LoadToolState();
		UpdateAreActive();;
		
		brushDirection = true;
		brushMode = BrushMode.Off;

		ranEnable = true;
		
	}
Exemplo n.º 31
0
	void DisableMenu()
	{
		brushDirection = true;
		brushMode = BrushMode.Off;
		//DebugClearData();
		
		SaveTempSlots();
		SaveToolState();
	}
Exemplo n.º 32
0
	private void CaptureInput()
	{
		altDown = false;
		shiftDown = false;
		ctrlDown = false;
		xUpped = false;
		
		if(toolActive == false)
			return;
		
		Event curEvent = Event.current;
		
		
		if(curEvent.keyCode == KeyCode.X && curEvent.rawType == EventType.KeyUp)
			//if(curEvent.type == EventType.KeyUp && curEvent.keyCode == KeyCode.X)
		{
			xUpped = true;
		}
		
		if(curEvent.control)
		{
			ctrlDown = true;
			//sceneView.Focus(); // Pulls focus to the scene view, but may be responsible for bug where qb to takes over computers when ctrl is down
		}
		
		if(shiftDown == false && shiftWasDown == true) 
		{shiftWasDown = false;
			
			placementModifier = false;
			window.Repaint();
		}
		
		if(ctrlDown == false && ctrlWasDown == true)
		{ctrlWasDown = false;
			//shiftDown = false;
			//shiftWasDown = false;
			//placementModifier = false;
			
			brushMode = BrushMode.Off;
			EndStroke();
			EndPlaceStroke();
			window.Repaint();
			return;
		}
		
		else if(ctrlDown == true && ctrlWasDown == false)
		{ctrlWasDown = true;
			
			brushMode = BrushMode.On;
			window.Repaint();
		}
		
		//Toggle Brush vs Eraser
		if(xUpped)
		{
			brushDirection = !brushDirection;
			window.Repaint();
		}
		
		//Default Mode is Paint, from there we can 
		if(curEvent.alt)
		{
			//modify mode to Camera Navigation
			//if we are currently painting end stroke
			//if we are currently placing commit
			altDown = true;
		}
		
		if(curEvent.shift)
			shiftDown = true;
		
		
		if(shiftDown == true && shiftWasDown == false) //might want to force end 
		{shiftWasDown = true;
			
			//modify mode to Place
			placementModifier = true;
			window.Repaint();
		}
		
		//Default Mode is Paint, from there we can 
		if(curEvent.alt)
		{
			//modify mode to Camera Navigation
			//if we are currently painting end stroke
			//if we are currently placing commit
			altDown = true;
		}
		
		if(curEvent.shift)
			shiftDown = true;
		
		
		if(shiftDown == true && shiftWasDown == false) //might want to force end 
		{shiftWasDown = true;
			
			//modify mode to Place
			placementModifier = true;
			window.Repaint();
		}
		
		//return;
	}
Exemplo n.º 33
0
	void OnGUI()
	{	
		if(ranEnable == false)
			OnEnable();
		
		//if(builtStyles == false)
			BuildStyles();
			
			CaptureInput();
			
		drawCurTip = false;
		
		EditorGUILayout.Space();
		
	EditorGUILayout.BeginVertical(masterVerticalStyle,GUILayout.Width(280)); //Begin Master Vertical
		
		EditorGUILayout.BeginHorizontal();//Brush Toggles Section Begin
		
			Texture2D brushIndicatorTexture = null;
			
			switch(brushMode)
			{
				case BrushMode.Off:
					
					if(toolActive == true)
					{
						if(brushDirection == true)
						{
							brushIndicatorTexture = brushIcon_Inactive;
						}
						else //if(brushDirection == false)
						{
							brushIndicatorTexture = eraserIcon_Inactive;
						}
					}
					
					else
						brushIndicatorTexture = brushIcon_Locked;
				break;
				
				case BrushMode.On:
				
					if(toolActive == true)
					{
						if(placementModifier)
							brushIndicatorTexture = placementIcon_Active;
		
						else
						{
							if(brushDirection == true)
							{
								brushIndicatorTexture = brushIcon_Active;
							}
							else //if(brushDirection == false)
							{
								brushIndicatorTexture = eraserIcon_Active;
							}
						}	
					}
					
					else
						brushIndicatorTexture = brushIcon_Locked;
				break;
			}
	
			if(GUILayout.Button(brushIndicatorTexture,picLabelStyle,GUILayout.Width(32),GUILayout.Height(32)))
			{
				toolActive = !toolActive;
				brushMode = BrushMode.Off;
			}
			DoTipCheck("Brush/Eraser Indicator & master on/off switch" + System.Environment.NewLine + "Click to turn QB on/off and free shortcut keys");
			
		EditorGUI.BeginDisabledGroup(true);
			GUILayout.Label("Use Brush:" + System.Environment.NewLine + "Precise Place:" + System.Environment.NewLine + "Toggle Eraser:",tipLabelStyle,GUILayout.Width(90),GUILayout.Height(34)); DoTipCheck("Brush On/Off Indicator" + System.Environment.NewLine + "hold ctrl to paint");
			GUILayout.Label("ctrl+click/drag mouse"+ System.Environment.NewLine + "ctrl+shift+click/drag mouse" + System.Environment.NewLine + "ctrl+x" ,tipLabelStyle,GUILayout.Width(146),GUILayout.Height(32)); DoTipCheck("Brush On/Off Indicator" + System.Environment.NewLine + "hold ctrl to paint");
		EditorGUI.EndDisabledGroup();
		EditorGUILayout.EndHorizontal(); // Brush Toggles Section End

		#region Prefab Picker
		EditorGUI.BeginDisabledGroup(liveTemplate.live == false);//Overall Disable Start
		
			EditorGUILayout.BeginHorizontal(prefabPanelCrop,GUILayout.Width(280));
					
			if(liveTemplate.prefabGroup.Length == 0)
			{
				EditorGUILayout.BeginVertical(GUILayout.Height(78));
				PrefabDragBox(274, prefabAddField_Span, "Drag & Drop Prefabs Here");	DoTipCheck("Drag & Drop Prefab Here To Add");
				EditorGUILayout.EndVertical();
			}
			
			else
			{
				EditorGUILayout.BeginHorizontal();
					
					EditorGUILayout.BeginVertical();
						PrefabDragBox(30, prefabAddField_Small, ""); DoTipCheck("Drag & Drop Prefab Here To Add");
						
						if(prefabPaneOpen == false)
						{
							EditorGUI.BeginDisabledGroup(liveTemplate.prefabGroup.Length < 4);
							if(GUILayout.Button("",picButton_PrefabPaneDropdown_Closed,GUILayout.Height(16),GUILayout.Width(30)))
							{
								prefabPaneOpen = true;
								prefabFieldScrollPosition = new Vector2(0,0);
							} DoTipCheck("Expand Prefab Pane");
							EditorGUI.EndDisabledGroup();
						}

					EditorGUILayout.EndVertical();
				
				EditorGUILayout.EndHorizontal();
			
				if(prefabPaneOpen == false) // Default Scrollable View
				{
					prefabFieldScrollPosition = EditorGUILayout.BeginScrollView(prefabFieldScrollPosition,GUILayout.Height(78),GUILayout.Width(240) );//, GUILayout.Width(160));
					EditorGUILayout.BeginHorizontal();
					//Prefab Objects can be dragged or selected in this horizontal list
					for(int i = 0; i < liveTemplate.prefabGroup.Length; i++)
					{
						PrefabTile(i);
					}
					EditorGUILayout.EndHorizontal();
					EditorGUILayout.EndScrollView();
				}
				
				else // Expanded Pane View
				{
					EditorGUILayout.BeginVertical();
					EditorGUILayout.BeginHorizontal();
						for(int i = 0; i < liveTemplate.prefabGroup.Length; i++)
						{
							if(i % 3 == 0)
							{
								EditorGUILayout.EndHorizontal();
								EditorGUILayout.BeginHorizontal();
							}
							PrefabTile(i);
						}
					EditorGUILayout.EndHorizontal();
					EditorGUILayout.EndVertical();
				}

			}
			
			EditorGUILayout.EndHorizontal();
			
			if(prefabPaneOpen == true)
			{
				if(GUILayout.Button("",picButton_PrefabPaneDropdown_Open,GUILayout.Height(16),GUILayout.Width(276)))
				{
					prefabPaneOpen = false;
					prefabFieldScrollPosition = new Vector2(0,0);
				} DoTipCheck("Collapse Prefab Pane to Scrollable");
			}
		
		EditorGUILayout.Space();
		#endregion

		topScroll = EditorGUILayout.BeginScrollView(topScroll,GUILayout.Width(280));
		EditorGUILayout.BeginVertical(GUILayout.Width(260));
		
		#region	Stroke Properties
			brushSettingsFoldout = EditorGUILayout.Foldout(brushSettingsFoldout,"Brush Settings:"); DoTipCheck("Brush and Stroke settings");
		
			if(brushSettingsFoldout == true)
			{
			EditorGUI.BeginChangeCheck();
			
                EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
								
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Brush Radius",sliderLabelStyle,GUILayout.Width(100)); DoTipCheck("The Size of the brush");
						liveTemplate.brushRadius = EditorGUILayout.Slider(liveTemplate.brushRadius,liveTemplate.brushRadiusMin,liveTemplate.brushRadiusMax); DoTipCheck("The Size of the brush");
					EditorGUILayout.EndHorizontal();
			
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Min",GUILayout.Width(70)); DoTipCheck("Minimum Slider Value");
						float tryRadiusMin = EditorGUILayout.FloatField(liveTemplate.brushRadiusMin,floatFieldCompressedStyle); DoTipCheck("Minimum Slider Value");
						liveTemplate.brushRadiusMin = tryRadiusMin < liveTemplate.brushRadiusMax ? tryRadiusMin : liveTemplate.brushRadiusMax;
			
						EditorGUILayout.LabelField("Max",GUILayout.Width(70)); DoTipCheck("Maximum Slider Value");
						float tryRadiusMax = EditorGUILayout.FloatField(liveTemplate.brushRadiusMax,floatFieldCompressedStyle); DoTipCheck("Maximum Slider Value");
						liveTemplate.brushRadiusMax = tryRadiusMax > liveTemplate.brushRadiusMin ? tryRadiusMax : liveTemplate.brushRadiusMin;
					EditorGUILayout.EndHorizontal();
					/*
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Scatter Amount",GUILayout.Width(100)); DoTipCheck("How closely should scattering match brush radius");
						liveTemplate.scatterRadius = EditorGUILayout.Slider(liveTemplate.scatterRadius,0f,1f); DoTipCheck("How closely should scattering match total brush radius");
					EditorGUILayout.EndHorizontal();
					*/
				EditorGUILayout.EndVertical();

                EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
			
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Stroke Spacing",GUILayout.Width(100)); DoTipCheck("Distance between brush itterations");
						liveTemplate.brushSpacing = EditorGUILayout.Slider(liveTemplate.brushSpacing,liveTemplate.brushSpacingMin,liveTemplate.brushSpacingMax); DoTipCheck("Distance between brush itterations");
					EditorGUILayout.EndHorizontal();
			
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Min",GUILayout.Width(70)); DoTipCheck("Minimum Slider Value");
						float trySpacingMin = EditorGUILayout.FloatField(liveTemplate.brushSpacingMin,floatFieldCompressedStyle); DoTipCheck("Minimum Slider Value");
						liveTemplate.brushSpacingMin = trySpacingMin < liveTemplate.brushSpacingMax ? trySpacingMin : liveTemplate.brushSpacingMax;
			
						EditorGUILayout.LabelField("Max",GUILayout.Width(70)); DoTipCheck("Maximum Slider Value");
						float trySpacingMax = EditorGUILayout.FloatField(liveTemplate.brushSpacingMax,floatFieldCompressedStyle); DoTipCheck("Maximum Slider Value");
						liveTemplate.brushSpacingMax = trySpacingMax > liveTemplate.brushSpacingMin ? trySpacingMax : liveTemplate.brushSpacingMin;
					EditorGUILayout.EndHorizontal();
			
				EditorGUILayout.EndVertical();
			
			if(EditorGUI.EndChangeCheck())
			{
				liveTemplate.dirty = true;
			}
		
			}
		#endregion
		
		EditorGUILayout.Space();

		sortingFoldout = EditorGUILayout.Foldout(sortingFoldout,"Sorting Settings:"); DoTipCheck("Grouping and Layer settings");
		if(sortingFoldout == true)
		{
		EditorGUI.BeginChangeCheck();

		#region Layers
            EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
				//A toggle determining whether to isolate painting to specific layers
				prevPaintToLayer = liveTemplate.paintToLayer;
				liveTemplate.paintToLayer = EditorGUILayout.Toggle("Paint to Layer", liveTemplate.paintToLayer,EditorStyles.toggle); DoTipCheck("Restrict painting to specific layers?");
				
				if(prevPaintToLayer != liveTemplate.paintToLayer)
				{
					UpdateCompoundPaintToLayer();
					UpdateCompoundLayerMask();
				}
				//A dropdown where the user can check off which layers to paint to
				EditorGUI.BeginDisabledGroup(!liveTemplate.paintToLayer);
							
				EditorGUILayout.BeginHorizontal();
				
					//string layerDisplayName = "Nothing";//string.empty;
					EditorGUILayout.LabelField("Choose Layers", GUILayout.Width(146)); DoTipCheck("Choose the layers to paint onto");
					
					if(GUILayout.Button((liveTemplate.layerText).ToString(),groupMenuDropdownStyle,GUILayout.Width(102)))
					{
						RenderLayerMenu(Event.current);
					}DoTipCheck("Choose the layers to paint onto");
					
				EditorGUILayout.EndHorizontal();
				
				EditorGUI.EndDisabledGroup();
				
				prevPaintToSelection = liveTemplate.paintToSelection;
				liveTemplate.paintToSelection = EditorGUILayout.Toggle("Restrict to Selection", liveTemplate.paintToSelection); DoTipCheck("Restrinct painting to selected objects in the scene - stacks with Layer Settings");
				
				if(prevPaintToSelection != liveTemplate.paintToSelection)
					UpdateCompoundPaintToSelection();
				
			EditorGUILayout.EndVertical();
		#endregion
			
		#region Groups
            EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
						
			liveTemplate.groupObjects = EditorGUILayout.Toggle("Group Placed Objects",liveTemplate.groupObjects); DoTipCheck("Parent placed objects to an in-scene group object?");
			
			EditorGUI.BeginDisabledGroup(!liveTemplate.groupObjects);

			EditorGUILayout.BeginHorizontal();
			
				EditorGUILayout.LabelField("Choose Existing Group",GUILayout.Width(146)); DoTipCheck("Choose a group that already exists in the scene");
			
				string curGroupName = "Nothing";
				
				if(liveTemplate.groupName != string.Empty)
					curGroupName = liveTemplate.groupName;
				
				if(GUILayout.Button(curGroupName,groupMenuDropdownStyle, GUILayout.Width(102)))
				{
					RenderGroupMenu(Event.current);
				} DoTipCheck("Choose a group that already exists in the scene");
				
			EditorGUILayout.EndHorizontal();
						
		if(EditorGUI.EndChangeCheck())
		{
			liveTemplate.dirty = true;
		}
			
			EditorGUILayout.BeginHorizontal();
				newGroupName = EditorGUILayout.TextField("Name New Group",newGroupName,GUILayout.Width(210)); DoTipCheck("Enter a name for a new group you'd like to add");
				
				EditorGUI.BeginDisabledGroup(newGroupName == "");
					if(GUILayout.Button("Add",GUILayout.Width(38)))
					{
						clearSelection = true;
						
						if(GroupWithNameExists(newGroupName))
						{
							EditorUtility.DisplayDialog("Group Name Conflict","A Group named '" + newGroupName + "' already exists. Please choose a different name for your new group." ,"Ok");
							newGroupName = "";
						}
						else
						{
							qb_Group newGroup = CreateGroup(newGroupName);
							liveTemplate.groupName = newGroupName;
							liveTemplate.curGroup = newGroup;
							
							newGroupName = "";
						}
			
					} DoTipCheck("Create your newly named group in the scene");
				EditorGUI.EndDisabledGroup();
		
			EditorGUILayout.EndHorizontal();
			
			EditorGUI.EndDisabledGroup();
	
			EditorGUILayout.EndVertical();
		#endregion
		}
		
		EditorGUILayout.Space();
		
		#region Rotation
		rotationFoldout = EditorGUILayout.Foldout(rotationFoldout,"Object Rotation:"); DoTipCheck("Settings for Offsetting the rotation of placed objects");
		if(rotationFoldout == true)
		{
		EditorGUI.BeginChangeCheck();

				EditorGUILayout.BeginVertical();

                EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Align to Surface",GUILayout.Width(130)); DoTipCheck("Placed objects orient based on the surface normals of the painting surface");
						liveTemplate.alignToNormal = EditorGUILayout.Toggle(liveTemplate.alignToNormal,GUILayout.Width(14)); DoTipCheck("Placed objects orient based on the surface normals of the painting surface");
							GUILayout.Space(42);
						EditorGUI.BeginDisabledGroup(!liveTemplate.alignToNormal);
						EditorGUILayout.LabelField("Flip",GUILayout.Width(40)); DoTipCheck("Flip object's up axis along the surface");
							liveTemplate.flipNormalAlign = EditorGUILayout.Toggle(liveTemplate.flipNormalAlign,GUILayout.Width(14)); DoTipCheck("Flip object's up axis along the surface");		
						EditorGUI.EndDisabledGroup();
					EditorGUILayout.EndHorizontal();
						
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.LabelField("Align to Stroke",GUILayout.Width(130)); DoTipCheck("Placed objects face in the direction of painting");
						liveTemplate.alignToStroke = EditorGUILayout.Toggle(liveTemplate.alignToStroke,GUILayout.Width(14)); DoTipCheck("Placed objects face in the direction of painting");
							GUILayout.Space(42);
						EditorGUI.BeginDisabledGroup(!liveTemplate.alignToStroke);
							EditorGUILayout.LabelField("Flip",GUILayout.Width(40)); DoTipCheck("Flip object's forward axis along the stroke");
							liveTemplate.flipStrokeAlign = EditorGUILayout.Toggle(liveTemplate.flipStrokeAlign,GUILayout.Width(14)); DoTipCheck("Flip object's forward axis along the stroke");
						EditorGUI.EndDisabledGroup();
					EditorGUILayout.EndHorizontal();
			
					EditorGUILayout.EndVertical();
			
				EditorGUILayout.BeginHorizontal();

                EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
	
						EditorGUILayout.BeginHorizontal();
							EditorGUILayout.LabelField("Offset X",GUILayout.Width(106)); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the X axis");
								EditorGUILayout.BeginHorizontal(saveIconContainerStyle);
								if(GUILayout.Button("",picButton_ResetSlider,GUILayout.Width(16),GUILayout.Height(16)))
								{	liveTemplate.rotationRangeMin.x = 0f;
									liveTemplate.rotationRangeMax.x = 0f;
									liveTemplate.dirty = true;
									clearSelection = true;

								} DoTipCheck("Reset slider to 0");
								EditorGUILayout.EndHorizontal();
							float inputRotMinX = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMin.x, GUILayout.Width(32));
							liveTemplate.rotationRangeMin.x = inputRotMinX < liveTemplate.rotationRangeMax.x ? inputRotMinX : liveTemplate.rotationRangeMax.x; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the X axis");
								EditorGUILayout.MinMaxSlider(ref liveTemplate.rotationRangeMin.x,ref liveTemplate.rotationRangeMax.x,-180f,180); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the X axis");
								liveTemplate.rotationRangeMin.x = (float)System.Math.Round(liveTemplate.rotationRangeMin.x,0);
								liveTemplate.rotationRangeMax.x = (float)System.Math.Round(liveTemplate.rotationRangeMax.x,0);
							float inputRotMaxX = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMax.x, GUILayout.Width(32));
							liveTemplate.rotationRangeMax.x = inputRotMaxX > liveTemplate.rotationRangeMin.x ? inputRotMaxX : liveTemplate.rotationRangeMin.x; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the X axis");						
						EditorGUILayout.EndHorizontal();
						
						EditorGUILayout.BeginHorizontal();
							EditorGUILayout.LabelField("Offset Y (up)",GUILayout.Width(106)); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Y axis");
								EditorGUILayout.BeginHorizontal(saveIconContainerStyle);
								if(GUILayout.Button("",picButton_ResetSlider,GUILayout.Width(16),GUILayout.Height(16)))
								{	liveTemplate.rotationRangeMin.y = 0f;
									liveTemplate.rotationRangeMax.y = 0f;
									liveTemplate.dirty = true;
									clearSelection = true;

								} DoTipCheck("Reset slider to 0");
							EditorGUILayout.EndHorizontal();
							float inputRotMinY = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMin.y, GUILayout.Width(32));
							liveTemplate.rotationRangeMin.y = inputRotMinY < liveTemplate.rotationRangeMax.y ? inputRotMinY : liveTemplate.rotationRangeMax.y; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Y axis");		
								EditorGUILayout.MinMaxSlider(ref liveTemplate.rotationRangeMin.y,ref liveTemplate.rotationRangeMax.y,-180f,180); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Y axis");
								liveTemplate.rotationRangeMin.y = (float)System.Math.Round(liveTemplate.rotationRangeMin.y,0);
								liveTemplate.rotationRangeMax.y = (float)System.Math.Round(liveTemplate.rotationRangeMax.y,0);
							float inputRotMaxY = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMax.y, GUILayout.Width(32));
							liveTemplate.rotationRangeMax.y = inputRotMaxY > liveTemplate.rotationRangeMin.y ? inputRotMaxY : liveTemplate.rotationRangeMin.y; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Y axis");				
						EditorGUILayout.EndHorizontal();
						
						EditorGUILayout.BeginHorizontal();
							EditorGUILayout.LabelField("Offset Z",GUILayout.Width(106)); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Z axis");
								EditorGUILayout.BeginHorizontal(saveIconContainerStyle);
								if(GUILayout.Button("",picButton_ResetSlider,GUILayout.Width(16),GUILayout.Height(16)))
								{	liveTemplate.rotationRangeMin.z = 0f;
									liveTemplate.rotationRangeMax.z = 0f;
									liveTemplate.dirty = true;
									clearSelection = true;
				
								} DoTipCheck("Reset slider to 0");
								EditorGUILayout.EndHorizontal();
							float inputRotMinZ = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMin.z, GUILayout.Width(32));
							liveTemplate.rotationRangeMin.z = inputRotMinZ < liveTemplate.rotationRangeMax.z ? inputRotMinZ : liveTemplate.rotationRangeMax.z; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Z axis");					
								EditorGUILayout.MinMaxSlider(ref liveTemplate.rotationRangeMin.z,ref liveTemplate.rotationRangeMax.z,-180f,180); DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Z axis");
								liveTemplate.rotationRangeMin.z = (float)System.Math.Round(liveTemplate.rotationRangeMin.z,0);
								liveTemplate.rotationRangeMax.z = (float)System.Math.Round(liveTemplate.rotationRangeMax.z,0);
							float inputRotMaxZ = (float)EditorGUILayout.IntField((int)liveTemplate.rotationRangeMax.z, GUILayout.Width(32));
							liveTemplate.rotationRangeMax.z = inputRotMaxZ > liveTemplate.rotationRangeMin.z ? inputRotMaxZ : liveTemplate.rotationRangeMin.z; DoTipCheck("Limits (in degrees) to randomly offset object rotation around the Z axis");									

						EditorGUILayout.EndHorizontal();
			
					EditorGUILayout.EndVertical();
	
				EditorGUILayout.EndHorizontal();
				
				EditorGUILayout.EndVertical();
			
			if(EditorGUI.EndChangeCheck())
			{
				liveTemplate.dirty = true;
			}
			}
		#endregion
			
		EditorGUILayout.Space();
		
		#region Position
		positionFoldout = EditorGUILayout.Foldout(positionFoldout,"Object Position:"); DoTipCheck("Settings for Offsetting the rotation of placed objects");
		if(positionFoldout == true)
		{
		EditorGUI.BeginChangeCheck();
			
			EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));
			
				EditorGUILayout.BeginHorizontal();
					EditorGUILayout.LabelField("Offset X", GUILayout.Width(130)); DoTipCheck("Offset final placement position along local X axis");
					liveTemplate.positionOffset.x = EditorGUILayout.FloatField(liveTemplate.positionOffset.x); DoTipCheck("Offset final placement position along local X axis");
				EditorGUILayout.EndHorizontal();
				EditorGUILayout.BeginHorizontal();
					EditorGUILayout.LabelField("Offset Y (Up/Down)", GUILayout.Width(130)); DoTipCheck("Offset final placement position along local Y axis");
					liveTemplate.positionOffset.y = EditorGUILayout.FloatField(liveTemplate.positionOffset.y); DoTipCheck("Offset final placement position along local Y axis");
				EditorGUILayout.EndHorizontal();
				EditorGUILayout.BeginHorizontal();
					EditorGUILayout.LabelField("Offset Z", GUILayout.Width(130)); DoTipCheck("Offset final placement position along local Z axis");
					liveTemplate.positionOffset.z = EditorGUILayout.FloatField(liveTemplate.positionOffset.z); DoTipCheck("Offset final position placement along local Z axis");
				EditorGUILayout.EndHorizontal();
				
			EditorGUILayout.EndHorizontal();
			
		if(EditorGUI.EndChangeCheck())
		{
			liveTemplate.dirty = true;
		}
		}
		#endregion 
		
		EditorGUILayout.Space();
		
		#region Scale		
		scaleFoldout = EditorGUILayout.Foldout(scaleFoldout,"Object Scale:",EditorStyles.foldout); DoTipCheck("Settings for Offsetting the scale of placed objects");
		if(scaleFoldout == true)
		{
		EditorGUI.BeginChangeCheck();
		
			EditorGUILayout.BeginHorizontal();

				liveTemplate.scaleUniform = EditorGUILayout.Toggle(liveTemplate.scaleUniform,toggleButtonStyle,GUILayout.Width(15)); DoTipCheck("Placed models are scaled the same on all axes");
				GUILayout.Label("Uniform Scale"); DoTipCheck("Placed models are scaled the same on all axes");
			
			EditorGUILayout.EndHorizontal();
				
			EditorGUI.BeginDisabledGroup(!liveTemplate.scaleUniform);
			
				EditorGUILayout.BeginHorizontal(GUILayout.Width(260));

                EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(78));
						
						EditorGUILayout.LabelField(liveTemplate.scaleRandMinUniform.ToString("0.00") + " to " + liveTemplate.scaleRandMaxUniform.ToString("0.00"),GUILayout.Width(78)); DoTipCheck("Random Scaling Range Split Slider (Min/Max)");
						EditorGUILayout.MinMaxSlider(ref liveTemplate.scaleRandMinUniform,ref liveTemplate.scaleRandMaxUniform,liveTemplate.scaleMin,liveTemplate.scaleMax); DoTipCheck("Random Scaling Range Split Slider (Min/Max)");
						
						liveTemplate.scaleRandMinUniform = (float)System.Math. Round(liveTemplate.scaleRandMinUniform,2);
						liveTemplate.scaleRandMaxUniform = (float)System.Math.Round(liveTemplate.scaleRandMaxUniform,2);			
						liveTemplate.scaleRandMinUniform = Mathf.Clamp(liveTemplate.scaleRandMinUniform,liveTemplate.scaleMin,liveTemplate.scaleMax);
						liveTemplate.scaleRandMaxUniform = Mathf.Clamp(liveTemplate.scaleRandMaxUniform,liveTemplate.scaleMin,liveTemplate.scaleMax);
				
					if(liveTemplate.scaleUniform)
					{	
						liveTemplate.scaleRandMin = new Vector3(liveTemplate.scaleRandMinUniform,liveTemplate.scaleRandMinUniform,liveTemplate.scaleRandMinUniform);
						liveTemplate.scaleRandMax = new Vector3(liveTemplate.scaleRandMaxUniform,liveTemplate.scaleRandMaxUniform,liveTemplate.scaleRandMaxUniform);
					}
				
					EditorGUILayout.EndVertical();
			
			EditorGUI.EndDisabledGroup();

                EditorGUILayout.BeginVertical(menuBlockStyle, GUILayout.Width(170), GUILayout.MaxWidth(170));
						EditorGUILayout.BeginHorizontal();
							EditorGUILayout.LabelField("Min",GUILayout.Width(108)); DoTipCheck("Slider Minimum Value");
							liveTemplate.scaleMin = EditorGUILayout.FloatField(liveTemplate.scaleMin,floatFieldCompressedStyle); DoTipCheck("Slider Minimum Value");
						EditorGUILayout.EndHorizontal();
						EditorGUILayout.BeginHorizontal();
							EditorGUILayout.LabelField("Max",GUILayout.Width(108)); DoTipCheck("Slider Maximum Value");
							liveTemplate.scaleMax = EditorGUILayout.FloatField(liveTemplate.scaleMax,floatFieldCompressedStyle); DoTipCheck("Slider Maximum Value");
						EditorGUILayout.EndHorizontal();
		
						liveTemplate.scaleMin = (float)System.Math.Round(liveTemplate.scaleMin,2);
						liveTemplate.scaleMax = (float)System.Math.Round(liveTemplate.scaleMax,2);
					EditorGUILayout.EndVertical();
				
				EditorGUILayout.EndHorizontal();
		
	//-------------------------
				//EditorGUILayout.Space();
	//-------------------------
				
				EditorGUILayout.BeginHorizontal();

					liveTemplate.scaleUniform = !EditorGUILayout.Toggle(!liveTemplate.scaleUniform,toggleButtonStyle,GUILayout.Width(15)); DoTipCheck("Placed models are scaled separately on each axis");
					GUILayout.Label("Per Axis Scale"); DoTipCheck("Placed models are scaled separately on each axis");
				
				EditorGUILayout.EndHorizontal();
			
				EditorGUI.BeginDisabledGroup(liveTemplate.scaleUniform);
					
					EditorGUILayout.BeginHorizontal();
			
                        EditorGUILayout.BeginVertical(menuBlockStyle);
							liveTemplate.scaleRandMin.x = Mathf.Clamp(liveTemplate.scaleRandMin.x,liveTemplate.scaleMin,liveTemplate.scaleMax);
							EditorGUILayout.LabelField("X",GUILayout.Width(76));
							EditorGUILayout.LabelField(liveTemplate.scaleRandMin.x.ToString("0.00") + " to " + liveTemplate.scaleRandMax.x.ToString("0.00"),GUILayout.Width(76)); DoTipCheck("X Axis Random Scaling Range Split Slider (Min/Max)");
							EditorGUILayout.MinMaxSlider(ref liveTemplate.scaleRandMin.x,ref liveTemplate.scaleRandMax.x,liveTemplate.scaleMin,liveTemplate.scaleMax); DoTipCheck("X Axis Random Scaling Range Split Slider (Min/Max)");
							
							liveTemplate.scaleRandMin.x = (float)System.Math.Round(liveTemplate.scaleRandMin.x,2);
							liveTemplate.scaleRandMax.x = (float)System.Math.Round(liveTemplate.scaleRandMax.x,2);
							liveTemplate.scaleRandMin.x = Mathf.Clamp(liveTemplate.scaleRandMin.x,liveTemplate.scaleMin,liveTemplate.scaleMax);
							liveTemplate.scaleRandMax.x = Mathf.Clamp(liveTemplate.scaleRandMax.x,liveTemplate.scaleMin,liveTemplate.scaleMax);
						EditorGUILayout.EndVertical();

                        EditorGUILayout.BeginVertical(menuBlockStyle);
							liveTemplate.scaleRandMin.y = Mathf.Clamp(liveTemplate.scaleRandMin.y,liveTemplate.scaleMin,liveTemplate.scaleMax);
							EditorGUILayout.LabelField("Y",GUILayout.Width(76));
							EditorGUILayout.LabelField(liveTemplate.scaleRandMin.y.ToString("0.00") + " to " + liveTemplate.scaleRandMax.y.ToString("0.00"),GUILayout.Width(76)); DoTipCheck("Y Axis Random Scaling Range Split Slider (Min/Max)");
							EditorGUILayout.MinMaxSlider(ref liveTemplate.scaleRandMin.y,ref liveTemplate.scaleRandMax.y,liveTemplate.scaleMin,liveTemplate.scaleMax); DoTipCheck("Y Axis Random Scaling Range Split Slider (Min/Max)");
	
							liveTemplate.scaleRandMin.y = (float)System.Math.Round(liveTemplate.scaleRandMin.y,2);
							liveTemplate.scaleRandMax.y = (float)System.Math.Round(liveTemplate.scaleRandMax.y,2);
							liveTemplate.scaleRandMin.y = Mathf.Clamp(liveTemplate.scaleRandMin.y,liveTemplate.scaleMin,liveTemplate.scaleMax);
							liveTemplate.scaleRandMax.y = Mathf.Clamp(liveTemplate.scaleRandMax.y,liveTemplate.scaleMin,liveTemplate.scaleMax);
						EditorGUILayout.EndVertical();

                        EditorGUILayout.BeginVertical(menuBlockStyle);
							liveTemplate.scaleRandMin.z = Mathf.Clamp(liveTemplate.scaleRandMin.z,liveTemplate.scaleMin,liveTemplate.scaleMax);
							EditorGUILayout.LabelField("Z",GUILayout.Width(76));
							EditorGUILayout.LabelField(liveTemplate.scaleRandMin.z.ToString("0.00") + " to " + liveTemplate.scaleRandMax.z.ToString("0.00"),GUILayout.Width(76)); DoTipCheck("Z Axis Random Scaling Range Split Slider (Min/Max)");
							EditorGUILayout.MinMaxSlider(ref liveTemplate.scaleRandMin.z,ref liveTemplate.scaleRandMax.z,liveTemplate.scaleMin,liveTemplate.scaleMax); DoTipCheck("Z Axis Random Scaling Range Split Slider (Min/Max)");
	
							liveTemplate.scaleRandMin.z = (float)System.Math.Round(liveTemplate.scaleRandMin.z,2);
							liveTemplate.scaleRandMax.z = (float)System.Math.Round(liveTemplate.scaleRandMax.z,2);
							liveTemplate.scaleRandMin.z = Mathf.Clamp(liveTemplate.scaleRandMin.z,liveTemplate.scaleMin,liveTemplate.scaleMax);
							liveTemplate.scaleRandMax.z = Mathf.Clamp(liveTemplate.scaleRandMax.z,liveTemplate.scaleMin,liveTemplate.scaleMax);
						EditorGUILayout.EndVertical();

					EditorGUILayout.EndHorizontal();
					
				EditorGUI.EndDisabledGroup();
				
			
				EditorGUILayout.BeginVertical(menuBlockStyle);//,GUILayout.Width(78));
					
					GUILayout.Label("Scaling Style");
					
					EditorGUILayout.BeginHorizontal();
					
						liveTemplate.scaleAbsolute = EditorGUILayout.Toggle(liveTemplate.scaleAbsolute,toggleButtonStyle,GUILayout.Width(15)); DoTipCheck("Scale settings are applied directly to the transform of the prefabs being placed");
						GUILayout.Label("Absolute"); DoTipCheck("Scale settings are applied directly to the transform of the prefabs being placed");
						
						liveTemplate.scaleAbsolute = !EditorGUILayout.Toggle(!liveTemplate.scaleAbsolute,toggleButtonStyle,GUILayout.Width(15)); DoTipCheck("Scale settings are applied as a multiplier to the scale saved in the prefabs being placed as a multiplier");
						GUILayout.Label("Prefab Relative"); DoTipCheck("Scale settings are applied as a multiplier to the scale saved in the prefabs being placed");
						
					EditorGUILayout.EndHorizontal();
				EditorGUILayout.EndHorizontal();
			
			if(EditorGUI.EndChangeCheck())
			{
				liveTemplate.dirty = true;
			}
		}
		#endregion
		
		EditorGUILayout.Space();
		
		#region Eraser Options
		eraserFoldout = EditorGUILayout.Foldout(eraserFoldout,"Eraser Settings:",EditorStyles.foldout); DoTipCheck("Settings for limiting the Eraser");
		if(eraserFoldout == true)
		{
		EditorGUI.BeginChangeCheck();

			EditorGUILayout.BeginVertical(menuBlockStyle,GUILayout.Width(260));

			liveTemplate.eraseByGroup =		EditorGUILayout.Toggle("Erase by Group", liveTemplate.eraseByGroup,EditorStyles.toggle); DoTipCheck("Restrict Eraser to objects in currently selected group");
			liveTemplate.eraseBySelected =	EditorGUILayout.Toggle("Erase selected Prefab", liveTemplate.eraseBySelected,EditorStyles.toggle); DoTipCheck("Restrict Eraser to checked prefab");
			
			EditorGUILayout.EndVertical();
			
		if(EditorGUI.EndChangeCheck())
		{
			liveTemplate.dirty = true;
		}
		}
		#endregion
	
		EditorGUILayout.EndVertical(); //Overall Vertical Container End
		EditorGUILayout.EndScrollView(); // Overall Scroll View End


		EditorGUILayout.Space();
	
		#region Templates
		
		EditorGUILayout.BeginVertical(GUILayout.Width(280));
			
			EditorGUILayout.BeginHorizontal(menuBlockStyle,GUILayout.Width(276),GUILayout.Height(22));
			
				EditorGUILayout.LabelField("Name: ",GUILayout.Width(60)); DoTipCheck("Name Template");
			
				EditorGUI.BeginChangeCheck();
				GUILayout.FlexibleSpace();

				liveTemplate.brushName = EditorGUILayout.TextField(liveTemplate.brushName); DoTipCheck("Name Template");
				
				if(EditorGUI.EndChangeCheck())
				{
					liveTemplate.dirty = true;
				}
		
				EditorGUILayout.BeginHorizontal(saveIconContainerStyle);
				
					EditorGUI.BeginDisabledGroup(liveTemplate.dirty == false);
						if(GUILayout.Button("",picButton_SaveIcon,GUILayout.Width(16),GUILayout.Height(16)))
						{
						//permutation moved to TrySaveTemplate
							TrySaveTemplate(liveTemplate);
			
							clearSelection = true;
					
						} DoTipCheck("Save Template to File");
					EditorGUI.EndDisabledGroup();
				
				EditorGUILayout.EndHorizontal();
			
			EditorGUILayout.EndHorizontal();
						
		EditorGUI.EndDisabledGroup(); //Overall Disable End
	
			EditorGUILayout.BeginHorizontal(brushStripStyle,GUILayout.Width(276));
				
			int count = brushTemplates.Length;
			
			if(count != 0)
				for(int i = 0; i < count; i++)
				{
					if(i >= brushTemplates.Length)
						continue;
				
					if(brushTemplates[i] != null)
					{
						if(brushTemplates[i].live == false)
							brushTemplates[i] = null;
					}
					
					string slotNum = (i + 1).ToString("00");
					
					if(liveTemplateIndex == i)
					{
						brushSlotContainerStyle.normal.background	= templateTabBackground;
					}
					else
					{
						brushSlotContainerStyle.normal.background	= templateTabBackground_inactive;
					}
					
					EditorGUILayout.BeginVertical(brushSlotContainerStyle,GUILayout.Width(32),GUILayout.Height(48)); //Begin Tab
					
						EditorGUILayout.BeginHorizontal();	//Begin Tab Operations Duo - Load / Clear
				
								if(GUILayout.Button("",picButton_OpenFile, GUILayout.Width(16), GUILayout.Height(16)))
								{
									RenderTemplateMenu(Event.current, i);
								
								} DoTipCheck("Assign Template File to Slot" + slotNum);
								
							EditorGUI.BeginDisabledGroup(brushTemplates[i] == null);
							
								if(GUILayout.Button("", picButton_ClearSlot, GUILayout.Width(16), GUILayout.Height(16)))
								{
									TryCloseTab(i);
									
								} DoTipCheck("Clear Slot " + slotNum);
								
							EditorGUI.EndDisabledGroup();
						
						EditorGUILayout.EndHorizontal();	//End Slot Operations Duo
						
						if(i >= brushTemplates.Length)
							continue;
										
						EditorGUI.BeginDisabledGroup(brushTemplates[i] == null);// || brushTemplates[i].live == false);//!brushStateArray[i]);
							
							if(liveTemplateIndex != i)
							{
								if(GUILayout.Button(slotNum, picButton_SlotIcon_InActive, GUILayout.Width(32), GUILayout.Height(32)))
								{
									SwitchToTab(i);
								}
							}
							else
							{
								if(GUILayout.Button(slotNum, picButton_SlotIcon_Active, GUILayout.Width(32), GUILayout.Height(32)))
								{
									SwitchToTab(i);
								}
							}
							
							if(clearSelection == true)
							{
								clearSelection = false;
								EditorGUIUtility.hotControl = 0;
	  							EditorGUIUtility.keyboardControl = 0;
							}
							
						string slotName = brushTemplates[i] == null ? "Empty" : brushTemplates[i].brushName == string.Empty ? "Unnamed Template" :  brushTemplates[i].brushName ;
						DoTipCheck("Brush Slot " + slotNum + ": " + slotName);
					
					EditorGUI.EndDisabledGroup();
					
					EditorGUILayout.EndVertical();	//End Tab
					
				}
				
				count = brushTemplates.Length;
				
				//The "LOAD" faux-slot
				if(count < 6)
				{
					brushSlotContainerStyle.normal.background	= templateTabBackground_inactive;
					EditorGUILayout.BeginVertical(brushSlotContainerStyle,GUILayout.Width(32),GUILayout.Height(48)); //Begin Tab
					
						EditorGUILayout.BeginHorizontal(GUILayout.Width(32),GUILayout.Height(16));	//Begin Tab Operations Duo - FILLER in this case
							EditorGUILayout.Space();
						EditorGUILayout.EndHorizontal();
						
						EditorGUILayout.BeginHorizontal();	//Begin Slot Operations Duo

							if(GUILayout.Button("",picButton_OpenFileLarge, GUILayout.Width(32), GUILayout.Height(32)))
							{
								RenderTemplateMenu(Event.current, count);
							}
						EditorGUILayout.EndHorizontal();
					
					EditorGUILayout.EndVertical();	//End Slot
				}
				
				EditorGUILayout.EndHorizontal();
		
				//Tab Active Strip
				EditorGUILayout.BeginHorizontal(GUILayout.Height(24),GUILayout.Width(276));
					EditorGUILayout.BeginHorizontal(GUILayout.Height(24),GUILayout.Width(1));
					EditorGUILayout.Space();
					EditorGUILayout.EndHorizontal();
				
				for(int i = 0; i < count; i++)
				{
					//Template Checkboxes
					if(i == liveTemplateIndex)
					{
						picButton_TemplateActive.normal.background = templateActiveIcon_active;
						picButton_TemplateActive.hover.background = templateActiveIcon_active;
					}
					
					else
					{
						if(brushTemplates[i].active == false)
						{
							picButton_TemplateActive.normal.background = templateActiveIcon_off;
							picButton_TemplateActive.hover.background = templateActiveIcon_off;
						}
						else
						{
							picButton_TemplateActive.normal.background = templateActiveIcon_on;
							picButton_TemplateActive.hover.background = templateActiveIcon_on;
						}
					}
					
					EditorGUILayout.BeginHorizontal(slotActiveContainerStyle);//, GUILayout.Width(32), GUILayout.Height(16));
						
						if(brushTemplates[i].dirty)
						{
							window.picButton_TemplateDirty.hover.background		=	templateDirtyAsterisk;
							window.picButton_TemplateDirty.normal.background	=	templateDirtyAsterisk;
							window.picButton_TemplateDirty.active.background	=	templateDirtyAsterisk;
						}
						else
						{
							window.picButton_TemplateDirty.hover.background		=	null;
							window.picButton_TemplateDirty.normal.background	=	null;
							window.picButton_TemplateDirty.active.background	=	null;
									
						}
						
							GUILayout.Label("",picButton_TemplateDirty,GUILayout.Width(16), GUILayout.Height(16));
			
						if(GUILayout.Button("", picButton_TemplateActive, GUILayout.Width(16), GUILayout.Height(16)))
						{
							brushTemplates[i].active = !brushTemplates[i].active;
							UpdateAreActive();
							UpdateCompoundPaintToLayer();
							UpdateCompoundLayerMask();
							UpdateCompoundPaintToSelection();
							window.Repaint();
						} DoTipCheck("Toggle Template in slot '" + i + "' Active/Inactive." + " If no slot is checked, the currently selected slot is active");
						//End Template Checkboxes
						
					EditorGUILayout.EndHorizontal();
				}
				
				EditorGUILayout.Space(); //filler
				
				EditorGUILayout.EndHorizontal();
				//End Tab Active Strip
			
		EditorGUILayout.BeginVertical(GUILayout.Width(274));
			
			if(GUILayout.Button("Reset Current Template"))
			{
				RestoreTemplateDefaults();
				
			}DoTipCheck("Reset the currently selected slot to Default settings");
			
			string tipToDraw = drawCurTip ? curTip : string.Empty;
				
			EditorGUILayout.HelpBox(tipToDraw,MessageType.Info);
		
		EditorGUILayout.EndHorizontal();
		
			EditorGUILayout.EndVertical();
			
		EditorGUILayout.EndVertical();//Master Vertical End
		#endregion

		//EditorUtility.SetDirty(this);
	}
Exemplo n.º 34
0
        /// <summary>
        /// 레벨 편집기 그리기.
        /// </summary>
        private void DrawLevelEditor()
        {
            EditorGUILayout.LabelField("Level", EditorStyles.boldLabel);
            GUILayout.BeginHorizontal(GUILayout.Width(400));
            EditorGUILayout.HelpBox(
                "The layout settings of this level. (이 레벨의 레이아웃 설정)",
                MessageType.Info);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(new GUIContent("Width", "The width of this level. (이 레벨의 너비)"),
                                       GUILayout.Width(EditorGUIUtility.labelWidth));
            curLevel.width = EditorGUILayout.IntField(curLevel.width, GUILayout.Width(30));
            GUILayout.EndHorizontal();

            height = curLevel.height;

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(new GUIContent("Height", "The height of this level. (이 레벨의 높이)"),
                                       GUILayout.Width(EditorGUIUtility.labelWidth));
            curLevel.height = EditorGUILayout.IntField(curLevel.height, GUILayout.Width(30));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(new GUIContent("Brush type", "The current type of brush. (현재 브러시 유형)"),
                                       GUILayout.Width(EditorGUIUtility.labelWidth));
            curBrushType = (BrushType)EditorGUILayout.EnumPopup(curBrushType, GUILayout.Width(100));
            GUILayout.EndHorizontal();

            if (curBrushType == BrushType.block)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent("Block", "The current type of block.  (블록의 현재 유형)"),
                                           GUILayout.Width(EditorGUIUtility.labelWidth));
                curBlockType = (BlockType)EditorGUILayout.EnumPopup(curBlockType, GUILayout.Width(100));
                GUILayout.EndHorizontal();
            }
            else if (curBrushType == BrushType.blocker)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent("Blocker", "The current type of blocker.  (현재 차단기 유형)"),
                                           GUILayout.Width(EditorGUIUtility.labelWidth));
                curBlockerType =
                    (BlockerType)EditorGUILayout.EnumPopup(curBlockerType, GUILayout.Width(100));
                GUILayout.EndHorizontal();
            }
            else if (curBrushType == BrushType.booster)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent("Booster", "The current type of booster."),
                                           GUILayout.Width(EditorGUIUtility.labelWidth));
                curBoosterType =
                    (BoosterType)EditorGUILayout.EnumPopup(curBoosterType, GUILayout.Width(100));
                GUILayout.EndHorizontal();

                if (curBoosterType == BoosterType.rainbow)
                {
                    GUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField(new GUIContent("RainbowColor", "The current type of booster."),
                                               GUILayout.Width(EditorGUIUtility.labelWidth));
                    curColorType =
                        (ColorType)EditorGUILayout.EnumPopup(curColorType, GUILayout.Width(100));
                    GUILayout.EndHorizontal();
                }
            }

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(new GUIContent("Brush mode", "The current brush mode.    (현재 브러시 모드)"),
                                       GUILayout.Width(EditorGUIUtility.labelWidth));
            curBrushMode = (BrushMode)EditorGUILayout.EnumPopup(curBrushMode, GUILayout.Width(100));
            GUILayout.EndHorizontal();

            GUILayout.Space(10);

            if (width != curLevel.width || height != curLevel.height)
            {
                curLevel.blocks = new List <LevelBlock>(curLevel.width * curLevel.height);
                for (var i = 0; i < curLevel.width; i++)
                {
                    for (var j = 0; j < curLevel.height; j++)
                    {
                        curLevel.blocks.Add(new LevelBlockType()
                        {
                            type = BlockType.random
                        });
                    }
                }
            }

            //for (var i = 0; i < height; i++)
            //{
            //    GUILayout.BeginHorizontal();
            //    for (var j = 0; j < width; j++)
            //    {
            //        var tileIndex = (width * i) + j;
            //        CreateButton(tileIndex);
            //    }
            //    GUILayout.EndHorizontal();
            //}

            int gap = curLevel.width - curLevel.height;

            for (int i = curLevel.height - 1; i >= 0; --i)
            {
                GUILayout.BeginHorizontal();
                for (int j = 0; j < curLevel.width; j++)
                {
                    int tileIndex = 0;
                    if (curLevel.id <= 126)
                    {
                        tileIndex = (curLevel.width * j) + i;                     // 버그... 이전에 만든건 다틀어져서 냅둠...
                    }
                    else
                    {
                        tileIndex = ((curLevel.width - gap) * j) + i;
                    }
                    CreateButton(tileIndex);
                }
                GUILayout.EndHorizontal();
            }
        }
Exemplo n.º 35
0
        private void DrawBrush(Vector3 position, Vector3 normal, float radius, BrushMode brushMode)
        {
            // set default colors
            Color innerColor = GUIStyles.BrushNoneInnerColor;
            Color outerColor = GUIStyles.BrushNoneOuterColor;

            // set colors depending on brush mode
            switch (brushMode)
            {
            case BrushMode.None:
                innerColor = GUIStyles.BrushNoneInnerColor;
                outerColor = GUIStyles.BrushNoneOuterColor;
                break;

            case BrushMode.Add:
                innerColor = GUIStyles.BrushAddInnerColor;
                outerColor = GUIStyles.BrushAddOuterColor;
                break;

            case BrushMode.Remove:
                innerColor = GUIStyles.BrushRemoveInnerColor;
                outerColor = GUIStyles.BrushRemoveOuterColor;
                break;
            }



            // consider distribution
            switch (gizmo.brushSettings.distribution)
            {
            case BrushSettings.Distribution.Center:     // fallthrough
            case BrushSettings.Distribution.Poisson:
                // inner disc
                Handles.color = innerColor;
                Handles.DrawSolidDisc(position, normal, radius);

                // outer circle
                Handles.color = outerColor;
                Handles.DrawWireDisc(position, normal, radius);

                // center line / normal
                float   lineLength = radius * 0.5f;
                Vector3 lineStart  = position;
                Vector3 lineEnd    = position + normal * lineLength;
                Handles.DrawLine(lineStart, lineEnd);

                break;

            case BrushSettings.Distribution.FallOff:

                // use same curve for x and z
                AnimationCurve fallOffCurve = gizmo.brushSettings.fallOffCurve;
                DrawCurveBrushSamplePoints(position, normal, innerColor, outerColor, fallOffCurve, fallOffCurve);

                // alternate version: draw rings
                // DrawCurveBrushSampleRings(position, normal, radius, innerColor, outerColor);

                break;

            case BrushSettings.Distribution.FallOff2d:
                AnimationCurve fallOff2dCurveX = gizmo.brushSettings.fallOff2dCurveX;
                AnimationCurve fallOff2dCurveZ = gizmo.brushSettings.fallOff2dCurveZ;
                //DrawCurveBrushSamplePoints( position, normal, innerColor, outerColor, fallOff2dCurveX, fallOff2dCurveZ);
                DrawCurveBrushSamplePointsAsGrid(position, normal, innerColor, outerColor, fallOff2dCurveX, fallOff2dCurveZ);
                break;
            }
        }
Exemplo n.º 36
0
        // Works like OnGUI, except that it updates only the inspector view.
        public override void OnInspectorGUI()
        {
            EditorGUILayout.Space();

            // Useful textfield to name and organize your groups.
            _mp.groupName = EditorGUILayout.TextField(_mp.groupName);
            if (_mp.holderObj) _mp.holderObj.name = _mp.groupName;

            // Foldout menu for the help section, see below for further information
            help = EditorGUILayout.Foldout(help, "Help");

            // MAIN TOGGLE (this one can entirely turn the meshbrush on and off)
            EditorGUILayout.BeginHorizontal();
            {
                _mp.isActive = EditorGUILayout.Toggle(_mp.isActive, GUILayout.Width(15f));
                EditorGUILayout.LabelField("Enabled", GUILayout.Width(150f), GUILayout.ExpandWidth(false));
            }
            EditorGUILayout.EndHorizontal();

            // The help foldout menu in the inspector.
            if (help)
            {
                EditorGUILayout.HelpBox("Paint meshes onto your GameObject's surface.\n_______\n\nKeyBoard shortcuts:\n\nPaint meshes:\tpress or hold    " + _mp.paint + "\nDelete meshes:\tpress or hold    " + _mp.delete + "\nIncrease radius:\tpress or hold    " + _mp.increaseRadius + "\nDecrease radius:\tpress or hold    " + _mp.decreaseRadius + "\n_______\n\n" +
                    "Assign one or more prefab objects to the 'Set of meshes to paint' array below and press " + _mp.paint + " while hovering your mouse above your GameObject to start painting meshes. Press " + _mp.delete + " to delete painted meshes." +
                    "\n\nMake sure that the local Y-axis of each prefab mesh is the one pointing away from the surface on which you are painting (to avoid weird rotation errors).\n\n" +
                    "Check the documentation text file that comes with MeshBrush (or the YouTube tutorials) to find out more about the individual parameters (but most of them should be quite self explainatory, or supplied with a tooltip text label after hovering your mouse over them for a couple of seconds though).\n_______\n\n" +
                    "You can press 'Flag/Unflag all painted meshes as static' to mark/unmark as static all the meshes you've painted so far.\nFlagging painted meshes as static will improve performance overhead thanks to Unity's built-in static batching functionality, " +
                    "as long as the meshes obviously don't move (and as long as they share the same material).\nSo don't flag meshes as static if you have fancy looking animations on your prefab meshes (like, for instance, swaying animations for vegetation or similar properties that make the mesh move, rotate or scale in any way).\n_______\n\n" +
                    "Once you're done painting, you can also combine your meshes with the 'Combine painted meshes button'. Check out the documentation for further information.\n\n" +
                    "If you are painting grass or other kinds of small vegetation, I recommend using the '2-Sided Vegetation' shader that comes with the MeshBrush package. It's the " +
                    "built-in Unity transparent cutout diffuse shader, just without backface culling, so that you get 2-sided materials.\nYou can obviously also use your own custom shaders if you want.\n_______\n\nFeel free to add multiple MeshBrush script instances to one GameObject for multiple mesh painting sets, with defineable group names and parameters for each of them;\n" +
                    "MeshBrush will then randomly cycle through all of your MeshBrush instances and paint your meshes within the corresponding circle brush based on the corresponding parameters for that set.", MessageType.None);
            }
            EditorGUILayout.Space(); // This leaves a little space between inspector properties... It makes the custom inspector a little lighter and less painful to look at. Believe me: you're gonna need this extra-air to breathe inside the inspector!

            DrawDefaultInspector(); // We need the default inspector being displayed in order to show the array of meshes to paint in the MeshBrush's inspector.

            GUI.enabled = _mp.isActive;

            // The entire next block of code is dedicated to the inspector's GUI organization.

            EditorGUILayout.BeginHorizontal(); // Editor version of the GUILayout.BeginHorizontal().
            {
                _mp.autoStatic = EditorGUILayout.Toggle(_mp.autoStatic, GUILayout.Width(15f));
                EditorGUILayout.LabelField("Automatically flag meshes as static", GUILayout.Width(210f), GUILayout.ExpandWidth(false));
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            _mp.b_CustomKeys = EditorGUILayout.Foldout(_mp.b_CustomKeys, "Customize Keyboard Shortcuts");
            if (_mp.b_CustomKeys)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Paint");
                    _mp.paint = (KeyCode)EditorGUILayout.EnumPopup(_mp.paint);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Delete");
                    _mp.delete = (KeyCode)EditorGUILayout.EnumPopup(_mp.delete);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Increase radius");
                    _mp.increaseRadius = (KeyCode)EditorGUILayout.EnumPopup(_mp.increaseRadius);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Decrease radius");
                    _mp.decreaseRadius = (KeyCode)EditorGUILayout.EnumPopup(_mp.decreaseRadius);
                }
                EditorGUILayout.EndHorizontal();

                if (GUILayout.Button("Reset to default keys"))
                {
                    _mp.paint = KeyCode.P;
                    _mp.increaseRadius = KeyCode.O;
                    _mp.decreaseRadius = KeyCode.I;
                }
                EditorGUILayout.Space();
            } EditorGUILayout.Space();

            if (!thisCollider)
            {
                EditorGUILayout.HelpBox("This GameObject has no collider attached to it.\nMeshBrush needs a collider in order to work properly! Do you want to add a collider now?", MessageType.Error);

                if (GUILayout.Button("Yes, add a MeshCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<MeshCollider>();
                }
                if (GUILayout.Button("Yes, add a BoxCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<BoxCollider>();
                }
                if (GUILayout.Button("Yes, add a SphereCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<SphereCollider>();
                }
                if (GUILayout.Button("Yes, add a CapsuleCollider now please", GUILayout.Height(27f)))
                {
                    _mp.gameObject.AddComponent<CapsuleCollider>();
                }
                EditorGUILayout.Space();

                GUI.enabled = false;
            }

            // Avoid having unassigned keys in MeshBrush;
            // reset to the default value in case the user tries to set the button to "None"
            _mp.paint = (_mp.paint == KeyCode.None) ? KeyCode.P : _mp.paint;

            _mp.increaseRadius = (_mp.increaseRadius == KeyCode.None) ? KeyCode.O : _mp.increaseRadius;
            _mp.decreaseRadius = (_mp.decreaseRadius == KeyCode.None) ? KeyCode.I : _mp.decreaseRadius;

            // Color picker for our circle brush.
            _mp.hColor = EditorGUILayout.ColorField(toolTipColor, _mp.hColor);

            EditorGUILayout.BeginHorizontal();
            {
                // Radius value
                _mp.hRadius = EditorGUILayout.FloatField(toolTipRadius, _mp.hRadius, GUILayout.Width(175f), GUILayout.ExpandWidth(true));

                // Random mesh count toggle
                _mp.useRandomMeshCount = EditorGUILayout.Toggle(_mp.useRandomMeshCount, GUILayout.Width(15f));

                EditorGUILayout.LabelField(new GUIContent("Use random number", "Paint a random amount of meshes per stroke (within a defined range)."), GUILayout.Width(140f));
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            // Clamp the meshcount so it never goes below 1 or above 100.
            if (_mp.useRandomMeshCount)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Min. nr. of meshes:", GUILayout.Width(115f));
                        _mp.minNrOfMeshes = EditorGUILayout.IntField(Mathf.Clamp(_mp.minNrOfMeshes, 1, 100), GUILayout.Width(50f));
                        GUILayout.Space(3f);
                        EditorGUILayout.LabelField("Max. nr. of meshes:", GUILayout.Width(117f));
                        _mp.maxNrOfMeshes = EditorGUILayout.IntField(Mathf.Clamp(_mp.maxNrOfMeshes, 1, 100), GUILayout.Width(50f));
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(toolTipNR, GUILayout.Width(140f));
                    _mp.meshCount = EditorGUILayout.IntField(Mathf.Clamp(_mp.meshCount, 1, 100), GUILayout.Width(50f));
                }
                EditorGUILayout.EndHorizontal();
            }

            // Avoid negative or null radii.
            if (_mp.hRadius < 0.01f) _mp.hRadius = 0.01f;
            EditorGUILayout.Space();

            // Slider for the delay between paint strokes.
            _mp.delay = EditorGUILayout.Slider(toolTipFreq, _mp.delay, 0.05f, 1.0f);
            EditorGUILayout.Space(); EditorGUILayout.Space();

            // Slider for the offset amount.
            EditorGUILayout.LabelField(toolTipOffset);
            _mp.meshOffset = EditorGUILayout.Slider(_mp.meshOffset, -50.0f, 50.0f);

            EditorGUILayout.Space();

            // Self-explanatory.
            if (_mp.meshCount <= 1)
                GUI.enabled = false;

            // Slider for the scattering.
            EditorGUILayout.LabelField(toolTipInset);
            _mp.scattering = EditorGUILayout.Slider(_mp.scattering, 0, 100.0f);
            EditorGUILayout.Space();

            GUI.enabled = _mp.isActive;

            EditorGUILayout.BeginHorizontal();
            {
                _mp.yAxisIsTangent = EditorGUILayout.Toggle(_mp.yAxisIsTangent, GUILayout.Width(15f));
                EditorGUILayout.LabelField(toolTipTangentY, GUILayout.Width(150f));
                _mp.invertY = EditorGUILayout.Toggle(_mp.invertY, GUILayout.Width(15f));
                EditorGUILayout.LabelField(toolTipInvertY, GUILayout.Width(150f));
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            _mp.b_Slopes = EditorGUILayout.Foldout(_mp.b_Slopes, "Slopes");
            if (_mp.b_Slopes)
            {
                EditorGUILayout.LabelField(toolTipSlopeInfluence);
                _mp.slopeInfluence = EditorGUILayout.Slider(_mp.slopeInfluence, 0f, 100f); // Slider for slope influence.
                EditorGUILayout.Space();

                EditorGUILayout.BeginHorizontal();
                {
                    _mp.activeSlopeFilter = EditorGUILayout.Toggle(_mp.activeSlopeFilter, GUILayout.Width(15f));
                    EditorGUILayout.LabelField("Use slope filter");
                }
                EditorGUILayout.EndHorizontal();

                if (_mp.activeSlopeFilter == false)
                    GUI.enabled = false;

                EditorGUILayout.LabelField(toolTipSlopeFilter);
                _mp.maxSlopeFilterAngle = EditorGUILayout.Slider(_mp.maxSlopeFilterAngle, 1f, 180f);

                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.inverseSlopeFilter = EditorGUILayout.Toggle(_mp.inverseSlopeFilter, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipInvSlope, GUILayout.Width(120f));
                    _mp.manualRefVecSampling = EditorGUILayout.Toggle(_mp.manualRefVecSampling, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipManualRefVecS, GUILayout.Width(200f));
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                if (_mp.manualRefVecSampling == false)
                    GUI.enabled = false;

                EditorGUILayout.BeginHorizontal();
                {
                    _mp.showRefVecInSceneGUI = EditorGUILayout.Toggle(_mp.showRefVecInSceneGUI, GUILayout.Width(15f));
                    EditorGUILayout.LabelField("Show sampled vector", GUILayout.Width(130f));

                    if (GUILayout.Button(toolTipRefVecSample, GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                        brushMode = BrushMode.Sample;
                }
                EditorGUILayout.EndHorizontal();

                GUI.enabled = _mp.isActive;
                EditorGUILayout.Space();

                if (GUILayout.Button("Reset all slope settings", GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    _mp.ResetSlopeSettings();
            }

            _mp.b_Randomizers = EditorGUILayout.Foldout(_mp.b_Randomizers, "Randomize"); // This makes the little awesome arrow for the foldout menu in the inspector view appear...

            // ...and this below here makes it actually fold stuff in and out
            // (the menu is closed if the arrow points to the right and thus rScale is false).
            if (_mp.b_Randomizers)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.uniformScale = EditorGUILayout.Toggle("", _mp.uniformScale, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipUniformly, GUILayout.Width(100f));

                    _mp.rWithinRange = EditorGUILayout.Toggle("", _mp.rWithinRange, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(toolTipWithinRange);
                }
                EditorGUILayout.EndHorizontal();

                if (_mp.uniformScale == true)
                {
                    if (_mp.rWithinRange == false)
                        _mp.rScale = EditorGUILayout.Slider("Random scale:", _mp.rScale, 0, 5f);
                    else
                    {
                        EditorGUILayout.Space();

                        EditorGUILayout.LabelField(toolTipUniformlyRange);
                        _mp.rUniformRange = EditorGUILayout.Vector2Field("", _mp.rUniformRange);
                    }
                }
                else
                {
                    if (_mp.rWithinRange == false)
                    {
                        EditorGUILayout.Space();

                        _mp.rScaleW = EditorGUILayout.Slider("Random width (X/Z)", _mp.rScaleW, 0, 3f);
                        _mp.rScaleH = EditorGUILayout.Slider("Random height (Y)", _mp.rScaleH, 0, 3f);
                    }
                    else
                    {
                        EditorGUILayout.Space();

                        EditorGUILayout.LabelField("Randomly scale within these ranges:");
                        EditorGUILayout.LabelField(toolTipV4);
                        _mp.rNonUniformRange = EditorGUILayout.Vector4Field("", _mp.rNonUniformRange);
                        EditorGUILayout.Space();
                    }
                }
                EditorGUILayout.Space();

                EditorGUILayout.LabelField(toolTipRot);

                // Create the slider for the percentage of random rotation around the Y axis applied to our painted meshes.
                _mp.rRot = EditorGUILayout.Slider(_mp.rRot, 0.0f, 100.0f);
                EditorGUILayout.Space();

                if (GUILayout.Button(toolTipReset, GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    _mp.ResetRandomizers();
            }

            // Foldout for the additive scale.
            _mp.b_AdditiveScale = EditorGUILayout.Foldout(_mp.b_AdditiveScale, toolTipAddScale);

            if (_mp.b_AdditiveScale)
            {
                _mp.constUniformScale = EditorGUILayout.Toggle(toolTipUniformly, _mp.constUniformScale);
                if (_mp.constUniformScale == true)
                    _mp.cScale = EditorGUILayout.FloatField("Add to scale", _mp.cScale);
                else
                {
                    _mp.cScaleXYZ = EditorGUILayout.Vector3Field("Add to scale", _mp.cScaleXYZ);
                }
                if (_mp.cScale < -0.9f) _mp.cScale = -0.9f;
                if (_mp.cScaleXYZ.x < -0.9f) _mp.cScaleXYZ.x = -0.9f;
                if (_mp.cScaleXYZ.y < -0.9f) _mp.cScaleXYZ.y = -0.9f;
                if (_mp.cScaleXYZ.z < -0.9f) _mp.cScaleXYZ.z = -0.9f;
                EditorGUILayout.Space();

                if (GUILayout.Button("Reset additive scale", GUILayout.Height(27f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                {
                    _mp.cScale = 0;
                    _mp.cScaleXYZ = Vector3.zero;
                }
                EditorGUILayout.Space();
            }

            _mp.b_opt = EditorGUILayout.Foldout(_mp.b_opt, "Optimize");
            if (_mp.b_opt)
            {
                if (!_mp.holderObj) OnEnable();
                MeshBrushParent mbp = _mp.holderObj.GetComponent<MeshBrushParent>(); ;

                // Create 2 buttons for quickly flagging/unflagging all painted meshes as static...
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(toolTipFlagS, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                        mbp.FlagMeshesAsStatic();
                    if (GUILayout.Button("Unflag all painted\nmeshes as static", GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                        mbp.UnflagMeshesAsStatic();
                }
                EditorGUILayout.EndHorizontal();

                // ...and 2 other buttons for combining and deleting.
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(toolTipCombine, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)))
                    {
                        if (_mp.holderObj != null)
                        {
                            _mp.holderObj.GetComponent<MeshBrushParent>().CombinePaintedMeshes(_mp.autoSelectOnCombine);
                        }
                    }

                    //...and one to delete all the meshes we painted on this GameObject so far.
                    if (GUILayout.Button(toolTipDelete, GUILayout.Height(50f), GUILayout.Width(150f), GUILayout.ExpandWidth(true)) && mbp)
                    {
                        ClearDeletionBuffer();
                        Undo.DestroyObjectImmediate(_mp.holderObj.gameObject);
                    }
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.Space(3f);
                EditorGUILayout.BeginHorizontal();
                {
                    _mp.autoSelectOnCombine = EditorGUILayout.Toggle(new GUIContent("", "Automatically select the combined mesh GameObject after having pressed the combine button."), _mp.autoSelectOnCombine, GUILayout.Width(15f));
                    EditorGUILayout.LabelField(new GUIContent("Auto-select combined mesh", "Automatically select the combined mesh GameObject after having pressed the combine button."));
                }
                EditorGUILayout.EndHorizontal();

            }
            EditorGUILayout.Space();

            // Repaint the scene view whenever the inspector's gui is changed in some way.
            // This avoids weird disturbing snaps of the reference slope vector and the circle
            // brush GUI handle inside the scene view when we return to it after changing some settings in the inspector.
            if (GUI.changed)
            {
                SceneView.RepaintAll();
                ClearPaintBuffer();
            }
        }
Exemplo n.º 37
0
        // This one represents the vector sampling mode. This brushmode allows the user to sample a custom defined slope reference vector used by the slope filter. Check out the tutorial to find out what this does in case you're confused.
        void BrushMode_SampleReferenceVector()
        {
            if (Selection.gameObjects.Length == 1 && Selection.activeGameObject.transform == thisTransform)
            {
                scRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

                if (thisCollider.Raycast(scRay, out scHit, Mathf.Infinity))
                {
                    SceneView.RepaintAll();

                    // Draw a GUI handle arrow to represent the vector to sample.
                    Handles.ArrowCap(0, scHit.point, Quaternion.LookRotation(scHit.normal), 0.9f);

                    // Sample the reference vector for the slope filter and store it in the slopeRefVec variable.
                    if (Event.current.type == EventType.KeyDown && Event.current.keyCode == _mp.paint)
                    {
                        _mp.slopeRefVec = scHit.normal.normalized;
                        _mp.slopeRefVec_HandleLocation = scHit.point;
                        brushMode = BrushMode.MeshPaint; // Jump back to the meshpaint mode automatically.
                    }

                    // Here I give the user the chance to cancel sampling mode by pressing the escape button.
                    if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape)
                        brushMode = BrushMode.MeshPaint;
                }
            }
        }
Exemplo n.º 38
0
        public void OnSceneGUI()
        {
            bool    mousePosValid = false;
            Vector3 mousePos      = Vector3.zero;

            float radius = gizmo.brushSettings.brushSize / 2f;

            int controlId = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive);

            Ray        ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            RaycastHit hit;

            // TODO: raycast hit against layer
            //       see https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
            if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity))
            {
                mousePos      = hit.point;
                mousePosValid = true;

                ///
                /// process mouse events
                ///

                // control key pressed
                if (Event.current.control)
                {
                    // mouse wheel up/down changes the radius
                    if (Event.current.type == EventType.ScrollWheel)
                    {
                        // ctrl + shift + scroll = brush rotation
                        if (Event.current.shift)
                        {
                            int rotationStepSize = 10;
                            int rotationMin      = 0;   // TODO: find out of to get that from Range
                            int rotationMax      = 360; // TODO: find out of to get that from Range

                            // scroll up
                            if (Event.current.delta.y > 0)
                            {
                                gizmo.brushSettings.brushRotation += rotationStepSize;
                                if (gizmo.brushSettings.brushRotation > rotationMax)
                                {
                                    gizmo.brushSettings.brushRotation = rotationMin + rotationStepSize;
                                }
                                Event.current.Use();
                            }
                            // scroll down
                            else if (Event.current.delta.y < 0)
                            {
                                gizmo.brushSettings.brushRotation -= rotationStepSize;
                                if (gizmo.brushSettings.brushRotation < rotationMin)
                                {
                                    gizmo.brushSettings.brushRotation = rotationMax - rotationStepSize;
                                }
                                Event.current.Use();
                            }
                        }
                        // ctrl + scroll = brush size
                        else
                        {
                            // scroll up
                            if (Event.current.delta.y > 0)
                            {
                                gizmo.brushSettings.brushSize++;
                                Event.current.Use();
                            }
                            // scroll down
                            else if (Event.current.delta.y < 0)
                            {
                                gizmo.brushSettings.brushSize--;

                                // TODO: slider
                                if (gizmo.brushSettings.brushSize < 1)
                                {
                                    gizmo.brushSettings.brushSize = 1;
                                }

                                Event.current.Use();
                            }
                        }
                    }
                }

                BrushMode brushMode = BrushMode.None;
                if (Event.current.shift)
                {
                    brushMode = BrushMode.Add;

                    if (Event.current.control)
                    {
                        brushMode = BrushMode.Remove;
                    }
                }

                // draw brush gizmo
                DrawBrush(mousePos, hit.normal, radius, brushMode);

                // paint prefabs on mouse drag
                if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.MouseDown)
                {
                    // left button = 0; right = 1; middle = 2
                    if (Event.current.button == 0)
                    {
                        switch (brushMode)
                        {
                        case BrushMode.None:
                            break;

                        case BrushMode.Add:
                            AddPrefabs(hit);
                            break;

                        case BrushMode.Remove:
                            RemovePrefabs(hit.point);
                            break;
                        }

                        Event.current.Use();
                    }
                }
            }
            else
            {
                mousePosValid = false;
            }

            if (Event.current.type == EventType.Layout)
            {
                HandleUtility.AddDefaultControl(controlId);
            }


            // examples about how to show ui info
            // note: Handles.BeginGUI and EndGUI are important, otherwise the default gizmos aren't drawn
            Handles.BeginGUI();


            if (mousePosValid)
            {
                ShowHandleInfo(mousePos);
            }

            string[] info = new string[] { "Add prefabs: shift + drag mouse\nRemove prefabs: shift + ctrl + drag mouse\nBrush size: ctrl + mousewheel, Brush rotation: ctrl + shift + mousewheel", "Children: " + editor.getContainerChildren().Length };
            PrefabPainterEditor.ShowGuiInfo(info);

            Handles.EndGUI();
        }
Exemplo n.º 39
0
	void DisableMenu()
	{	
		brushDirection = true;
		brushMode = BrushMode.Off;
		brushSettingsFoldout = false;
		rotationFoldout = false;
		scaleFoldout = false;
		
		SaveSettings();
	}
Exemplo n.º 40
0
 internal static extern void Internal_SetMode(IntPtr obj, BrushMode value);
Exemplo n.º 41
0
	void OnDestroy()
	{
		brushMode = BrushMode.Off;
		SceneView.onSceneGUIDelegate -= onSceneGUIFunc;
//		window = null;
	}
Exemplo n.º 42
0
 /// <param name="burshMode"></param>
 public Brush BrushMode(BrushMode brushMode)
 {
     this.brushMode = brushMode;
     return this;
 }
Exemplo n.º 43
0
	static bool painting; 	//in stroke

	public void OnSceneGUI(SceneView sceneView)
	{
		/* Rules pseudo code
		//if ALT not down
		//{
			//if mouse click when shift down -		begin PlaceMode
			//if drag while PlaceMode -				scale and rotate (calculate and execute scale and rotation on stored object)
			//if mouse up while placing -			end PlaceMode (if shift is still held down it will pop back on based on the stuff above)
			//if mouse right down while placing -	remove stored object from scene
			
			//if click when shift up -				begin StrokeMode
			//if drag while StrokeMode -			Paint stuff
			//if mouse up while StokeMode -			end StrokeMode
		//}
		*/

		
		bool altDown = false;
		bool shiftDown = false;
		bool ctrlDown = false;
//		bool xDown = false;

		if(Event.current.control)
		{
			ctrlDown = true;
			sceneView.Focus();
		}
		
		if(ctrlDown == false)
		{
			brushMode = BrushMode.Off;
			EndStroke();
			EndPlaceStroke();
			return;
		}
		
		else
			brushMode = BrushMode.On;
		
	//	if(xDown)
	//		brushDirection = !brushDirection;
		
		
		RaycastHit mouseRayHit = new RaycastHit();
		mouseRayHit = DoMouseRaycast();		
		
		DrawBrushGizmo(mouseRayHit);
		HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
		
		//Default Mode is Paint, from there we can 
		if(Event.current.alt)
		{
			//modify mode to Camera Navigation
			//if we are currently painting end stroke
			//if we are currently placing commit
			altDown = true;
		}
		
		if(Event.current.shift) //might want to force end 
		{
			//modify mode to Place
			shiftDown = true;
			placementModifier = true;
		}
		
		else 
			placementModifier = false;
		
		if(GetKeyUp == KeyCode.X)
		{
			brushDirection = !brushDirection;
		}
				
		if(altDown == false)
		{
			switch(Event.current.type)
			{
				
				case EventType.mouseUp:
					if(Event.current.button == 0)
					{
						if(brushMode == BrushMode.On)
						{
							if(painting == true)
							{
								EndStroke();
							}
					
							if(placing == true)
							{
								EndPlaceStroke();
							}
						}
					}
				break;
					
				case EventType.mouseDown:
					if(Event.current.button == 0)
					{	
						if(brushMode == BrushMode.On)
						{
							if(!shiftDown) 
							{
								BeginStroke();
							
								if(paintable)
								{
									Paint(mouseRayHit);
									Event.current.Use();
								}
								Tools.current = Tool.None;
							}
							
							else //shiftDown
							{
								if(paintable)
								{
									BeginPlaceStroke();
									Event.current.Use();
								}
								Tools.current = Tool.None;
							}
						}
					}
				break;
					
				case EventType.mouseDrag:
				if(Event.current.button == 0)
				{
					if(brushMode == BrushMode.On)
					{
						if(placing == true)
						{
							//if(paintable)
							//{
								UpdatePlace(sceneView);
								Event.current.Use();
								Tools.current = Tool.None; //make sure needed?
							//}
						}
					
						else if(painting == true)
						{
							if(paintable)
							{
								Paint(mouseRayHit);
								Event.current.Use();
								Tools.current = Tool.None; //make sure needed?
							}
						}
				
					}
				}
					HandleUtility.Repaint();
				break;
				
				case EventType.mouseMove:
					HandleUtility.Repaint();
				break;

			}
		}
		
		CalculateCursor(mouseRayHit);
		
		//This repaint is important to make lines and indicators not hang around for more frames
		sceneView.Repaint();

	}