Esempio n. 1
0
        private void DrawConfigTab()
        {
            configScrollPosition = GUILayout.BeginScrollView(configScrollPosition, GUILayout.ExpandHeight(true));
            P3dEditor.BeginLabelWidth(100);
            Settings.ColorGroup = EditorGUILayout.IntField("Color Group", Settings.ColorGroup);
            Settings.IconSize   = EditorGUILayout.IntSlider("Icon Size", Settings.IconSize, 32, 256);
            EditorGUILayout.BeginHorizontal();
            Settings.StateLimit = EditorGUILayout.IntField("State Limit", Settings.StateLimit);
            if (GUILayout.Button(new GUIContent("Apply", "Apply this undo/redo state limit to all P3dPaintableTexture components in the scene?"), EditorStyles.miniButton, GUILayout.ExpandWidth(false)) == true)
            {
                if (EditorUtility.DisplayDialog("Are you sure?", "This will apply this StateLimit to all P3dPaintableTexture components in the scene.", "OK") == true)
                {
                    ApplyStateLimit();
                }
            }
            EditorGUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            if (GUILayout.Button("Clear Settings") == true)
            {
                if (EditorUtility.DisplayDialog("Are you sure?", "This will reset all editor painting settings to default.", "OK") == true)
                {
                    ClearSettings();
                }
            }
            P3dEditor.EndLabelWidth();
            GUILayout.EndScrollView();
        }
Esempio n. 2
0
        private static float Slider(string title, float value, float min, float max)
        {
            var rect  = P3dEditor.Reserve();
            var rectA = rect; rectA.width = EditorGUIUtility.labelWidth + 50;
            var rectB = rect; rectB.xMin += EditorGUIUtility.labelWidth + 52;

            value = GUI.HorizontalSlider(rectB, value, min, max);

            return(EditorGUI.FloatField(rectA, title, value));
        }
Esempio n. 3
0
        private static float LogSlider(string title, float value, float logMin, float logMax)
        {
            var rect   = P3dEditor.Reserve();
            var rectA  = rect; rectA.width = EditorGUIUtility.labelWidth + 50;
            var rectB  = rect; rectB.xMin += EditorGUIUtility.labelWidth + 52;
            var logOld = Mathf.Log10(value);
            var logNew = GUI.HorizontalSlider(rectB, logOld, logMin, logMax);

            if (logOld != logNew)
            {
                value = Mathf.Pow(10.0f, logNew);
            }

            return(EditorGUI.FloatField(rectA, title, value));
        }
        protected virtual void OnGUI()
        {
            P3dEditor.ClearStacks();

            scrollPosition = GUILayout.BeginScrollView(scrollPosition);
            {
                EditorGUI.BeginChangeCheck();
                {
                    OnInspector();
                }
                if (EditorGUI.EndChangeCheck() == true)
                {
                    Repaint();
                }
            }
            GUILayout.EndScrollView();
        }
Esempio n. 5
0
        public static void Draw(Rect position, SerializedProperty property)
        {
            var sPro      = property.FindPropertyRelative("index");
            var groupData = P3dGroupData_Editor.GetGroupData(sPro.intValue);

            P3dEditor.BeginError(groupData == null);
            if (GUI.Button(position, groupData != null ? groupData.name : "MISSING: " + sPro.intValue, EditorStyles.popup) == true)
            {
                var menu        = new GenericMenu();
                var groupDatas  = P3dGroupData_Editor.CachedInstances.OrderBy(d => d.Index);
                var editorCount = 0;

                foreach (var cachedGroupData in groupDatas)
                {
                    if (cachedGroupData != null)
                    {
                        if (cachedGroupData.Index >= 0)
                        {
                            AddMenuItem(menu, cachedGroupData, sPro, cachedGroupData.Index);
                        }
                        else
                        {
                            editorCount++;
                        }
                    }
                }

                if (editorCount > 0)
                {
                    menu.AddDisabledItem(new GUIContent(""));
                    menu.AddDisabledItem(new GUIContent("EDITOR"));
                    menu.AddDisabledItem(new GUIContent(""));

                    foreach (var cachedGroupData in groupDatas)
                    {
                        if (cachedGroupData != null && cachedGroupData.Index < 0)
                        {
                            AddMenuItem(menu, cachedGroupData, sPro, cachedGroupData.Index);
                        }
                    }
                }

                menu.DropDown(position);
            }
            P3dEditor.EndError();
        }
        private void DrawSceneFooter(P3dPaintableTexture[] paintableTextures)
        {
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            EditorGUILayout.Separator();

            EditorGUI.BeginDisabledGroup(CanLoadAll(paintableTextures) == false);
            if (GUILayout.Button("Load All", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)) == true)
            {
                if (EditorUtility.DisplayDialog("Are you sure?", "This will replace all paintable textures with their currently exported texture state.", "OK") == true)
                {
                    foreach (var paintableTexture in paintableTextures)
                    {
                        var outputTexture = paintableTexture.OutputTexture;

                        if (outputTexture != null)
                        {
                            paintableTexture.Replace(outputTexture, Color.white);

                            paintableTexture.Texture = outputTexture;
                        }
                    }
                }
            }
            EditorGUI.EndDisabledGroup();
            EditorGUI.BeginDisabledGroup(CanReExportAll(paintableTextures) == false);
            P3dEditor.BeginColor(Color.green);
            if (GUILayout.Button("Re-Export All", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)) == true)
            {
                if (EditorUtility.DisplayDialog("Are you sure?", "This will re-export all paintable textures in your scene.", "OK") == true)
                {
                    foreach (var paintableTexture in paintableTextures)
                    {
                        if (paintableTexture.OutputTexture != null)
                        {
                            System.IO.File.WriteAllBytes(AssetDatabase.GUIDToAssetPath(paintableTexture.Output), paintableTexture.GetPngData(true));
                        }
                    }

                    AssetDatabase.Refresh();
                }
            }
            P3dEditor.EndColor();
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();
        }
        private void DrawPaintableTexture(P3dPaintableTexture paintableTexture, Material material)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(paintableTexture.Slot.GetTitle(material));
            if (GUILayout.Button("Export", EditorStyles.miniButton, GUILayout.ExpandWidth(false)) == true)
            {
                var path = AssetDatabase.GUIDToAssetPath(paintableTexture.Output);
                var name = paintableTexture.name + "_" + paintableTexture.Slot.Name;
                var dir  = string.IsNullOrEmpty(path) == false?System.IO.Path.GetDirectoryName(path) : "Assets";

                if (string.IsNullOrEmpty(path) == false)
                {
                    name = System.IO.Path.GetFileNameWithoutExtension(path);
                }

                path = EditorUtility.SaveFilePanelInProject("Export Texture", name, "png", "Export Your Texture", dir);

                if (string.IsNullOrEmpty(path) == false)
                {
                    System.IO.File.WriteAllBytes(path, paintableTexture.GetPngData(true));

                    AssetDatabase.ImportAsset(path);

                    Undo.RecordObject(paintableTexture, "Output Changed");

                    paintableTexture.Output = AssetDatabase.AssetPathToGUID(path);

                    EditorUtility.SetDirty(this);
                }
            }
            EditorGUILayout.EndHorizontal();

            P3dEditor.BeginLabelWidth(100);
            EditorGUI.indentLevel++;
            EditorGUILayout.BeginHorizontal();
            var outputTexture    = paintableTexture.OutputTexture;
            var newOutputTexture = EditorGUILayout.ObjectField(outputTexture, typeof(Texture2D), false);

            EditorGUI.BeginDisabledGroup(outputTexture == null || paintableTexture.Activated == false);
            if (GUILayout.Button("Load", EditorStyles.miniButton, GUILayout.ExpandWidth(false)) == true)
            {
                if (EditorUtility.DisplayDialog("Are you sure?", "This will replace this paintable texture with the currently exported texture state.", "OK") == true)
                {
                    paintableTexture.Replace(outputTexture, Color.white);

                    paintableTexture.Texture = outputTexture;
                }
            }
            EditorGUI.EndDisabledGroup();
            EditorGUILayout.EndHorizontal();

            if (outputTexture != newOutputTexture)
            {
                Undo.RecordObject(paintableTexture, "Output Changed");

                paintableTexture.Output = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(newOutputTexture));

                EditorUtility.SetDirty(this);
            }

            if (paintableTexture.UndoRedo == P3dPaintableTexture.UndoRedoType.None)
            {
                EditorGUILayout.HelpBox("This texture has no UndoRedo set, so you cannot undo or redo.", MessageType.Warning);
            }

            if (outputTexture == null)
            {
                EditorGUILayout.HelpBox("This texture hasn't been exported yet, so you cannot Export All.", MessageType.Warning);
            }
            EditorGUI.indentLevel--;
            P3dEditor.EndLabelWidth();
        }
Esempio n. 8
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var sObj      = property.serializedObject;
            var sIdx      = property.FindPropertyRelative("Index");
            var sNam      = property.FindPropertyRelative("Name");
            var rectA     = position; rectA.width = EditorGUIUtility.labelWidth;
            var rectB     = position; rectB.xMin += EditorGUIUtility.labelWidth; rectB.width = 20;
            var rectC     = position; rectC.xMin += EditorGUIUtility.labelWidth; rectC.xMin += 22; rectC.width -= 20;
            var rectD     = position; rectD.xMin = rectD.xMax - 18;
            var component = property.serializedObject.targetObject as Component;
            var paintable = component != null?component.GetComponentInParent <P3dPaintable>() : null;

            var missing = true;

            // Valid slot?
            if (paintable != null)
            {
                var material = P3dHelper.GetMaterial(paintable.CachedRenderer, sIdx.intValue);

                if (material != null && P3dHelper.TexEnvNameExists(material.shader, sNam.stringValue) == true)
                {
                    missing = false;
                }
            }

            P3dEditor.BeginError(missing);
            {
                EditorGUI.LabelField(rectA, label);

                sObj.Update();

                sIdx.intValue    = Mathf.Clamp(EditorGUI.IntField(rectB, sIdx.intValue), 0, 99);
                sNam.stringValue = EditorGUI.TextField(rectC, sNam.stringValue);

                sObj.ApplyModifiedProperties();

                // Draw menu
                if (GUI.Button(rectD, "", EditorStyles.popup) == true)
                {
                    var menu = new GenericMenu();

                    if (paintable != null)
                    {
                        var materials = paintable.CachedRenderer.sharedMaterials;

                        if (materials.Length > 0)
                        {
                            for (var i = 0; i < materials.Length; i++)
                            {
                                var material     = materials[i];
                                var materialName = i.ToString();
                                var matIndex     = i;

                                if (material != null)
                                {
                                    materialName += " (" + material.name + ")";

                                    var texEnvs = P3dHelper.GetTexEnvs(material.shader);

                                    if (texEnvs != null && texEnvs.Count > 0)
                                    {
                                        foreach (var texEnv in texEnvs)
                                        {
                                            var texName  = texEnv.Name;
                                            var texTitle = texEnv.Title;
                                            var tex      = material.GetTexture(texName);

                                            if (tex != null)
                                            {
                                                texTitle += " (" + tex.name + ")";
                                            }
                                            else
                                            {
                                                texTitle += " (empty)";
                                            }

                                            menu.AddItem(new GUIContent(materialName + "/" + texTitle), sIdx.intValue == matIndex && sNam.stringValue == texName, () => { sObj.Update(); sIdx.intValue = matIndex; sNam.stringValue = texName; sObj.ApplyModifiedProperties(); });
                                        }
                                    }
                                    else
                                    {
                                        menu.AddDisabledItem(new GUIContent(materialName + "/This Material's shader has no textures!"));
                                    }
                                }
                                else
                                {
                                    menu.AddDisabledItem(new GUIContent(materialName + "/This Material is null!"));
                                }
                            }
                        }
                        else
                        {
                            menu.AddDisabledItem(new GUIContent("This GameObject has no materials!"));
                        }
                    }

                    menu.DropDown(rectD);
                }
            }
            P3dEditor.EndError();
        }
 public static void Draw()
 {
     P3dEditor.Draw("connector.hitSpacing", "The world space distance between each paint point.\n\n0 = No spacing.");
     P3dEditor.Draw("connector.hitLimit", "When using HitSpacing, this prevents scenarios where something goes wrong and you attempt to paint too many times per frame.");
     P3dEditor.Draw("connector.connectHits", "If you enable this then the hit points generated by this component will be connected into lines, allowing you to paint continuously.");
 }
Esempio n. 10
0
 public override void DrawEditorLayout()
 {
     texture     = (Texture)UnityEditor.EditorGUI.ObjectField(P3dEditor.Reserve(), new GUIContent("Texture", "The painting texture will be changed to this."), texture, typeof(Texture), true);
     pressureMin = UnityEditor.EditorGUILayout.FloatField(new GUIContent("Pressure Min", "The paint pressure must be at least this value."), pressureMin);
     pressureMax = UnityEditor.EditorGUILayout.FloatField(new GUIContent("Pressure Max", "The paint pressure must be at most this value."), pressureMax);
 }
        protected override void OnInspector()
        {
            EditorGUILayout.BeginHorizontal();
            var newMesh = (Mesh)EditorGUILayout.ObjectField("Mesh", mesh, typeof(Mesh), false);

            if (GUILayout.Button("Refresh", EditorStyles.miniButton, GUILayout.Width(50)) == true)
            {
                ready = false;
            }
            EditorGUILayout.EndHorizontal();

            if (newMesh != mesh)
            {
                ready = false;
                mesh  = newMesh;
            }

            if (mesh != null)
            {
                if (mesh.subMeshCount != submeshNames.Length)
                {
                    var submeshNamesList = new List <string>();

                    for (var i = 0; i < mesh.subMeshCount; i++)
                    {
                        submeshNamesList.Add(i.ToString());
                    }

                    submeshNames = submeshNamesList.ToArray();
                }

                EditorGUILayout.Separator();

                var newSubmesh = EditorGUILayout.Popup("Submesh", submesh, submeshNames);
                var newCoord   = EditorGUILayout.Popup("Coord", coord, new string[] { "UV0", "UV1", "UV2", "UV3" });
                var newMode    = EditorGUILayout.Popup("Mode", mode, new string[] { "Texcoord", "Triangles" });

                if (mode == 1)                 // Triangles
                {
                    EditorGUILayout.BeginHorizontal();
                    var newPitch = EditorGUILayout.FloatField("Pitch", pitch);
                    var newYaw   = EditorGUILayout.FloatField("Yaw", yaw);
                    EditorGUILayout.EndHorizontal();

                    if (newPitch != pitch || newYaw != yaw)
                    {
                        ready = false;
                        pitch = newPitch;
                        yaw   = newYaw;
                    }
                }

                EditorGUILayout.Separator();

                EditorGUILayout.LabelField("Triangles", EditorStyles.boldLabel);
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.IntField("Total", triangleCount);
                P3dEditor.BeginError(invalidCount > 0);
                EditorGUILayout.IntField("With No UV", invalidCount);
                P3dEditor.EndError();
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                P3dEditor.BeginError(outsideCount > 0);
                EditorGUILayout.IntField("Out Of Bounds", outsideCount);
                P3dEditor.EndError();
                P3dEditor.BeginError(partiallyCount > 0);
                EditorGUILayout.IntField("Partially Out Of Bounds", partiallyCount);
                P3dEditor.EndError();
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                P3dEditor.BeginError(utilizationPercent < 40.0f);
                EditorGUILayout.FloatField("Utilization %", utilizationPercent);
                P3dEditor.EndError();
                P3dEditor.BeginError(overlapPercent > 0);
                EditorGUILayout.FloatField("Overlap %", overlapPercent);
                P3dEditor.EndError();
                EditorGUILayout.EndHorizontal();
                EditorGUI.EndDisabledGroup();

                if (coord != newCoord || newSubmesh != submesh || newMode != mode || ready == false)
                {
                    ready   = true;
                    coord   = newCoord;
                    submesh = newSubmesh;
                    mode    = newMode;

                    listA.Clear();
                    listB.Clear();
                    ratioList.Clear();
                    mesh.GetTriangles(indices, submesh);
                    mesh.GetVertices(positions);
                    mesh.GetUVs(coord, coords);

                    triangleCount      = indices.Count / 3;
                    invalidCount       = 0;
                    outsideCount       = 0;
                    partiallyCount     = 0;
                    overlapTex         = P3dHelper.Destroy(overlapTex);
                    utilizationPercent = 0.0f;
                    overlapPercent     = 0.0f;

                    if (coords.Count > 0)
                    {
                        if (mode == 0)                         // Texcoord
                        {
                            BakeOverlap();
                        }

                        var rot  = Quaternion.Euler(pitch, yaw, 0.0f);
                        var off  = -mesh.bounds.center;
                        var mul  = P3dHelper.Reciprocal(mesh.bounds.size.magnitude);
                        var half = Vector3.one * 0.5f;

                        for (var i = 0; i < indices.Count; i += 3)
                        {
                            var positionA = positions[indices[i + 0]];
                            var positionB = positions[indices[i + 1]];
                            var positionC = positions[indices[i + 2]];
                            var coordA    = coords[indices[i + 0]];
                            var coordB    = coords[indices[i + 1]];
                            var coordC    = coords[indices[i + 2]];
                            var outside   = 0; outside += IsOutside(coordA) ? 1 : 0; outside += IsOutside(coordB) ? 1 : 0; outside += IsOutside(coordC) ? 1 : 0;
                            var area      = Vector3.Cross(coordA - coordB, coordA - coordC).sqrMagnitude;
                            var invalid   = area <= float.Epsilon;

                            if (invalid == true)
                            {
                                invalidCount++;
                            }

                            if (outside == 3)
                            {
                                outsideCount++;
                            }

                            if (outside == 1 || outside == 2)
                            {
                                partiallyCount++;
                            }

                            if (mode == 0)                             // Texcoord
                            {
                                listA.Add(coordA); listA.Add(coordB);
                                listA.Add(coordB); listA.Add(coordC);
                                listA.Add(coordC); listA.Add(coordA);
                            }

                            if (mode == 1)                             // Triangles
                            {
                                positionA = half + rot * (off + positionA) * mul;
                                positionB = half + rot * (off + positionB) * mul;
                                positionC = half + rot * (off + positionC) * mul;

                                positionA.z = positionB.z = positionC.z = 0.0f;

                                listA.Add(positionA); listA.Add(positionB);
                                listA.Add(positionB); listA.Add(positionC);
                                listA.Add(positionC); listA.Add(positionA);

                                if (invalid == true)
                                {
                                    listB.Add(positionA); listB.Add(positionB);
                                    listB.Add(positionB); listB.Add(positionC);
                                    listB.Add(positionC); listB.Add(positionA);
                                }
                            }
                        }
                    }
                    else
                    {
                        invalidCount = triangleCount;
                    }

                    arrayA = listA.ToArray();
                    arrayB = listB.ToArray();
                }

                var rect = EditorGUILayout.BeginVertical(); GUILayout.FlexibleSpace(); EditorGUILayout.EndVertical();
                var pos  = rect.min;
                var siz  = rect.size;

                GUI.Box(rect, "");

                if (mode == 0 && overlapTex != null)                 // Texcoord
                {
                    GUI.DrawTexture(rect, overlapTex);
                }

                Handles.BeginGUI();
                if (listA.Count > 0)
                {
                    for (var i = listA.Count - 1; i >= 0; i--)
                    {
                        var coord = listA[i];

                        coord.x = pos.x + siz.x * coord.x;
                        coord.y = pos.y + siz.y * (1.0f - coord.y);

                        arrayA[i] = coord;
                    }

                    Handles.DrawLines(arrayA);

                    for (var i = listB.Count - 1; i >= 0; i--)
                    {
                        var coord = listB[i];

                        coord.x = pos.x + siz.x * coord.x;
                        coord.y = pos.y + siz.y * (1.0f - coord.y);

                        arrayB[i] = coord;
                    }

                    Handles.color = Color.red;
                    Handles.DrawLines(arrayB);
                }
                Handles.EndGUI();
            }
            else
            {
                EditorGUILayout.HelpBox("No Mesh Selected.\nTo select a mesh, click Analyze Mesh from the P3dPaintable component, or from the Mesh inspector context menu (gear icon at top right).", MessageType.Info);
            }
        }
        private void DrawPaintTab()
        {
            visitedPaintTab = true;

            if (selectingTool == true)
            {
                DrawTool(); return;
            }

            if (selectingMaterial == true)
            {
                DrawMaterial(); return;
            }

            if (selectingShape == true)
            {
                DrawShape(); return;
            }

            paintScrollPosition = GUILayout.BeginScrollView(paintScrollPosition, GUILayout.ExpandHeight(true));
            DrawTop();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawRadius();
            P3dEditor.EndLabelWidth();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawColor();
            P3dEditor.EndLabelWidth();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawAngle();
            P3dEditor.EndLabelWidth();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawTiling();
            P3dEditor.EndLabelWidth();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawNormal();
            P3dEditor.EndLabelWidth();

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            DrawModifiers();
            P3dEditor.EndLabelWidth();
            GUILayout.EndScrollView();

            GUILayout.FlexibleSpace();

            if (Application.isPlaying == false)
            {
                EditorGUILayout.HelpBox("You must enter play mode to begin painting.", MessageType.Warning);
            }
            else
            {
                if (SceneView.sceneViews.Contains(mouseOverWindow) == true)
                {
                    EditorGUILayout.HelpBox("You can only paint in the Game view.", MessageType.Warning);
                }

                if (toolInstance != null)
                {
                    if (GUILayout.Button(new GUIContent("Unload Paint Brush", "If you want to keep this window open but don't want to perform in-editor painting any more, then you can click this.")) == true)
                    {
                        ClearTool();

                        visitedPaintTab = false;
                        currentPage     = PageType.Scene;
                    }
                }
            }

            UpdatePaint();
        }
Esempio n. 13
0
        private void DrawCameraTab()
        {
            cameraScrollPosition = GUILayout.BeginScrollView(cameraScrollPosition, GUILayout.ExpandHeight(true));
            EditorGUILayout.HelpBox("This allows you to control the Game view camera. Keep in mind this will not work if your camera already has controls from another source.", MessageType.Info);

            EditorGUILayout.Separator();

            P3dEditor.BeginLabelWidth(100);
            EditorGUILayout.LabelField("Controls", EditorStyles.boldLabel);
            Settings.MoveSpeed    = EditorGUILayout.FloatField("Speed", Settings.MoveSpeed);
            Settings.MoveForward  = (KeyCode)EditorGUILayout.EnumPopup("Forward", Settings.MoveForward);
            Settings.MoveBackward = (KeyCode)EditorGUILayout.EnumPopup("Backward", Settings.MoveBackward);
            Settings.MoveLeft     = (KeyCode)EditorGUILayout.EnumPopup("Left", Settings.MoveLeft);
            Settings.MoveRight    = (KeyCode)EditorGUILayout.EnumPopup("Right", Settings.MoveRight);
            Settings.Rotate       = (KeyCode)EditorGUILayout.EnumPopup("Rotate", Settings.Rotate);
            Settings.Pan          = (KeyCode)EditorGUILayout.EnumPopup("Pan", Settings.Pan);
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.TextField("Paint", "Mouse 0", EditorStyles.popup);
            EditorGUILayout.TextField("Zoom", "Mouse Wheel", EditorStyles.popup);
            EditorGUILayout.TextField("Move Pivot", "Double Click (Right / Middle)", EditorStyles.popup);
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.Separator();

            Settings.OverrideCamera = EditorGUILayout.Toggle("Override Camera", Settings.OverrideCamera);

            if (Settings.OverrideCamera == true)
            {
                EditorGUI.indentLevel++;
                Settings.Distance  = LogSlider("Distance", Settings.Distance, -4, 4);
                Settings.Observer  = (Transform)EditorGUILayout.ObjectField("Root", Settings.Observer, typeof(Transform), true);
                Settings.ShowPivot = EditorGUILayout.Toggle("Show Pivot", Settings.ShowPivot);

                if (GUI.Button(EditorGUI.IndentedRect(P3dEditor.Reserve()), "Snap To Scene View", EditorStyles.miniButton) == true)
                {
                    var camA = Camera.main;

                    if (camA != null && SceneView.lastActiveSceneView != null && SceneView.lastActiveSceneView.camera != null)
                    {
                        var camB = SceneView.lastActiveSceneView.camera;

                        camA.transform.position = camB.transform.position;
                        camA.transform.rotation = camB.transform.rotation;
                    }
                }
                EditorGUI.indentLevel--;

                if (toolInstance != null && toolInstance.CameraMovedUnexpectedly == true)
                {
                    EditorGUILayout.HelpBox("The camera moved unexpectedly. Mabe your scene already has camera controls?", MessageType.Warning);
                }
            }
            P3dEditor.EndLabelWidth();
            GUILayout.EndScrollView();

            GUILayout.FlexibleSpace();

            if (Application.isPlaying == false)
            {
                EditorGUILayout.HelpBox("You must enter play mode to move the Game camera.", MessageType.Warning);
            }
        }