/// <summary>Add a target for the camera to follow.</summary>
        /// <param name="targetTransform">The Transform of the target</param>
        /// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
        /// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
        /// <param name="duration">The time it takes for this target to reach it's influence. Use for a more progressive transition.</param>
        /// <param name="targetOffset">A vector that offsets the target position that the camera will follow</param>
        public CameraTarget AddCameraTarget(Transform targetTransform, float targetInfluenceH = 1f, float targetInfluenceV = 1f, float duration = 0f, Vector2 targetOffset = default(Vector2))
        {
            var newCameraTarget = new CameraTarget
            {
                TargetTransform  = targetTransform,
                TargetInfluenceH = targetInfluenceH,
                TargetInfluenceV = targetInfluenceV,
                TargetOffset     = targetOffset
            };

            CameraTargets.Add(newCameraTarget);

            if (duration > 0f)
            {
                newCameraTarget.TargetInfluence = 0f;
                StartCoroutine(AdjustTargetInfluenceRoutine(newCameraTarget, targetInfluenceH, targetInfluenceV, duration));
            }

            return(newCameraTarget);
        }
        IEnumerator AdjustTargetInfluenceRoutine(CameraTarget cameraTarget, float influenceH, float influenceV, float duration, bool removeIfZeroInfluence = false)
        {
            var startInfluenceH = cameraTarget.TargetInfluenceH;
            var startInfluenceV = cameraTarget.TargetInfluenceV;

            var t = 0f;

            while (t <= 1.0f)
            {
                t += DeltaTime / duration;
                cameraTarget.TargetInfluenceH = Utils.EaseFromTo(startInfluenceH, influenceH, t, EaseType.Linear);
                cameraTarget.TargetInfluenceV = Utils.EaseFromTo(startInfluenceV, influenceV, t, EaseType.Linear);

                yield return(GetYield());
            }

            if (removeIfZeroInfluence && cameraTarget.TargetInfluenceH <= 0 && cameraTarget.TargetInfluenceV <= 0)
            {
                CameraTargets.Remove(cameraTarget);
            }
        }
Esempio n. 3
0
        IEnumerator AdjustTargetInfluenceRoutine(CameraTarget cameraTarget, float influenceH, float influenceV, float duration, bool removeIfZeroInfluence = false)
        {
            var startInfluenceH = cameraTarget.TargetInfluenceH;
            var startInfluenceV = cameraTarget.TargetInfluenceV;

            var waitForFixedUpdate = new WaitForFixedUpdate();
            var t = 0f;

            while (t <= 1.0f)
            {
                t += (UpdateType == UpdateType.LateUpdate ? Time.deltaTime : Time.fixedDeltaTime) / duration;
                cameraTarget.TargetInfluenceH = Utils.EaseFromTo(startInfluenceH, influenceH, t, EaseType.Linear);
                cameraTarget.TargetInfluenceV = Utils.EaseFromTo(startInfluenceV, influenceV, t, EaseType.Linear);

                yield return((UpdateType == UpdateType.FixedUpdate) ? waitForFixedUpdate : null);
            }

            if (removeIfZeroInfluence && cameraTarget.TargetInfluenceH <= 0 && cameraTarget.TargetInfluenceV <= 0)
            {
                CameraTargets.Remove(cameraTarget);
            }
        }
Esempio n. 4
0
        /// <summary>Add a target for the camera to follow on rails.</summary>
        /// <param name="targetTransform">The Transform of the target</param>
        /// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
        /// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
        /// <param name="targetOffset">A vector that offsets the target position that the camera will follow</param>
        public void AddRailsTarget(Transform targetTransform, float targetInfluenceH = 1f, float targetInfluenceV = 1f, Vector2 targetOffset = default(Vector2))
        {
            var newCameraTarget = new CameraTarget()
            {
                TargetTransform  = targetTransform,
                TargetInfluenceH = targetInfluenceH,
                TargetInfluenceV = targetInfluenceV,
                TargetOffset     = targetOffset
            };

            CameraTargets.Add(newCameraTarget);

            var railTransform = new GameObject(targetTransform.name + "_OnRails").transform;

            _cameraTargetsOnRails.Add(
                newCameraTarget,
                railTransform
                );

            ProCamera2D.AddCameraTarget(railTransform);

            enabled = true;
        }
Esempio n. 5
0
        public override void OnInspectorGUI()
        {
            var proCamera2D = (ProCamera2D)target;

            serializedObject.Update();


            EditorGUILayout.Space();

            // Draw User Guide link
            if (ProCamera2DEditorResources.UserGuideIcon != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.width = ProCamera2DEditorResources.UserGuideIcon.width;
                rect.height = ProCamera2DEditorResources.UserGuideIcon.height;
                if (GUI.Button(new Rect(15, rect.y, 32, 32), new GUIContent(ProCamera2DEditorResources.UserGuideIcon, "User Guide")))
                {
                    Application.OpenURL("http://www.procamera2d.com/user-guide/");
                }
            }

            // Draw header
            if (ProCamera2DEditorResources.InspectorHeader != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.x += 37;
                rect.width = ProCamera2DEditorResources.InspectorHeader.width;
                rect.height = ProCamera2DEditorResources.InspectorHeader.height;
                GUILayout.Space(rect.height);
                GUI.DrawTexture(rect, ProCamera2DEditorResources.InspectorHeader);
            }

            EditorGUILayout.Space();


            // Review prompt
            if (_showReviewMessage)
            {
                EditorGUILayout.HelpBox("Sorry for the intrusion, but I need you for a second. Reviews on the Asset Store are very important for me to keep improving this product. Please take a minute to write a review and support ProCamera2D.", MessageType.Warning, true);
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Sure, I'll write a review!"))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                    Application.OpenURL("http://u3d.as/i7L");
                }
                if (GUILayout.Button("No, thanks."))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                }
                EditorGUILayout.EndHorizontal();
                AddSpace();
            }


            // Assign game camera
            if (proCamera2D.GameCamera == null)
                proCamera2D.GameCamera = proCamera2D.GetComponent<Camera>();


            // Targets Drop Area
            Event evt = Event.current;
            Rect drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var style = new GUIStyle("box");
            if (EditorGUIUtility.isProSkin)
                style.normal.textColor = Color.white;
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!drop_area.Contains(evt.mousePosition))
                        return;

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (evt.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        foreach (Object dragged_object in DragAndDrop.objectReferences)
                        {
                            var newCameraTarget = new CameraTarget
                            {
                                TargetTransform = ((GameObject)dragged_object).transform,
                                TargetInfluence = 1f
                            };
							
                            proCamera2D.CameraTargets.Add(newCameraTarget);
                            EditorUtility.SetDirty(proCamera2D);
                        }
                    }
                    break;
            }

            EditorGUILayout.Space();




            // Remove empty targets
            for (int i = 0; i < proCamera2D.CameraTargets.Count; i++)
            {
                if (proCamera2D.CameraTargets[i].TargetTransform == null)
                {
                    proCamera2D.CameraTargets.RemoveAt(i);
                }
            }




            // Targets List
            _targetsList.DoLayoutList();
            AddSpace();





            // Center target on start
            _tooltip = new GUIContent("Center target on start", "Should the camera move instantly to the target on game start?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CenterTargetOnStart"), _tooltip);

            AddSpace();
            




            // Axis
            _tooltip = new GUIContent("Axis", "Choose the axis in which the camera should move.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("Axis"), _tooltip);

            AddSpace();




            // UpdateType
            _tooltip = new GUIContent("Update Type", "LateUpdate: Non physics based game\nFixedUpdate: Physics based game");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UpdateType"), _tooltip);

            AddSpace();




            // Show correct axis name
            switch (proCamera2D.Axis)
            {
                case MovementAxis.XY:
                    hAxis = "X";
                    vAxis = "Y";
                    break;

                case MovementAxis.XZ:
                    hAxis = "X";
                    vAxis = "Z";
                    break;

                case MovementAxis.YZ:
                    hAxis = "Y";
                    vAxis = "Z";
                    break;
            }




            // Follow horizontal
            _tooltip = new GUIContent("Follow " + hAxis, "Should the camera move on the horizontal axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowHorizontal"), _tooltip);
            if (proCamera2D.FollowHorizontal)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target horizontal position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("HorizontalFollowSmoothness"), _tooltip);

                if (proCamera2D.HorizontalFollowSmoothness < 0f)
                    proCamera2D.HorizontalFollowSmoothness = 0f;

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitHorizontalCameraDistance"), _tooltip);

                if (proCamera2D.LimitHorizontalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxHorizontalTargetDistance < .1f)
                        proCamera2D.MaxHorizontalTargetDistance = .1f;
                    else if (proCamera2D.MaxHorizontalTargetDistance > 1f)
                        proCamera2D.MaxHorizontalTargetDistance = 1f;
                }

                EditorGUILayout.EndHorizontal();

                // Limit speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the horizontal axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxHorizontalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxHorizontalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the horizontal axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalSpeed"), _tooltip);

                    if (proCamera2D.MaxHorizontalSpeed <= 0)
                        proCamera2D.MaxHorizontalSpeed = 0.01f;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
                AddSpace();
            }




            // Follow vertical
            _tooltip = new GUIContent("Follow " + vAxis, "Should the camera move on the vertical axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowVertical"), _tooltip);

            if (proCamera2D.FollowVertical)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target vertical position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("VerticalFollowSmoothness"), _tooltip);

                if (proCamera2D.VerticalFollowSmoothness < 0f)
                    proCamera2D.VerticalFollowSmoothness = 0f;

                // Limit camera distance to target    
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitVerticalCameraDistance"), _tooltip);

                if (proCamera2D.LimitVerticalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxVerticalTargetDistance < .1f)
                        proCamera2D.MaxVerticalTargetDistance = .1f;
                    else if (proCamera2D.MaxVerticalTargetDistance > 1f)
                        proCamera2D.MaxVerticalTargetDistance = 1f;
                }

                EditorGUILayout.EndHorizontal();

                // Limit camera speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the vertical axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxVerticalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxVerticalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the vertical axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalSpeed"), _tooltip);

                    if (proCamera2D.MaxVerticalSpeed <= 0)
                        proCamera2D.MaxVerticalSpeed = 0.01f;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
            }

            if (!proCamera2D.FollowHorizontal && !proCamera2D.FollowVertical)
                EditorGUILayout.HelpBox("Camera won't move if it's not following the targets on any axis.", MessageType.Error, true);

            AddSpace();





            // Overall offset
            EditorGUILayout.LabelField("Offset");
            EditorGUI.indentLevel = 1;

            _tooltip = new GUIContent(hAxis, "Horizontal offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.x"), _tooltip);

            _tooltip = new GUIContent(vAxis, "Vertical offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.y"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();



            // Zoom with FOV
            if (!proCamera2D.GameCamera.orthographic)
            {
                GUI.enabled = !Application.isPlaying;
                _tooltip = new GUIContent("Zoom With FOV", "If enabled, when using a perspective camera, the camera will zoom by changing the FOV instead of moving the camera closer/further from the objects.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("ZoomWithFOV"), _tooltip);
                GUI.enabled = true;
                AddSpace();
            }




            // Divider
            GUILayout.Box("", new GUILayoutOption[]{ GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("EXTENSIONS", EditorStyles.boldLabel);



            // Extensions
            for (int i = 0; i < _extensions.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();

                var ext = proCamera2D.GetComponent(_extensions[i].ExtType) as BasePC2D;

                EditorGUILayout.LabelField(_extensions[i].ExtName);
                if (ext == null)
                {
                    GUI.color = Color.green;
                    if (GUILayout.Button("Enable"))
                    {
                        ext = proCamera2D.gameObject.AddComponent(_extensions[i].ExtType) as BasePC2D;
                        ext.ProCamera2D = proCamera2D;
                    }
                }
                else
                {
                    GUI.color = Color.red;
                    if (GUILayout.Button("Disable"))
                    {
                        if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                        {
                            DestroyImmediate(ext);
                            EditorGUIUtility.ExitGUI();
                        }
                    }
                }
                GUI.color = Color.white;
                EditorGUILayout.EndHorizontal();
            }



            // Divider
            EditorGUILayout.Space();
            GUI.color = Color.white;
            GUILayout.Box("", new GUILayoutOption[]{ GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("TRIGGERS", EditorStyles.boldLabel);



            // Triggers
            for (int i = 0; i < _triggers.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField(_triggers[i].TriggerName + " (" + _triggers[i].AllTriggers.Count() + ")");

                if (GUILayout.Button("Add"))
                {
                    var newGo = new GameObject(_triggers[i].TriggerType.Name);
                    newGo.transform.localScale = new Vector3(5, 5, 5);
                    var trigger = newGo.AddComponent(_triggers[i].TriggerType) as BasePC2D;
                    trigger.ProCamera2D = proCamera2D;
                    _triggers[i].AllTriggers.Add(trigger);
                }

                GUI.enabled = _triggers[i].AllTriggers.Count() > 0;

                if (GUILayout.Button(">"))
                {
                    Selection.activeGameObject = ((BasePC2D)_triggers[i].AllTriggers[_triggers[i].TriggerCurrentIndex]).gameObject;
                    SceneView.FrameLastActiveSceneView();
                    EditorGUIUtility.PingObject(((BasePC2D)_triggers[i].AllTriggers[_triggers[i].TriggerCurrentIndex]).gameObject);

                    Selection.activeGameObject = proCamera2D.gameObject;

                    _triggers[i].TriggerCurrentIndex = _triggers[i].TriggerCurrentIndex >= _triggers[i].AllTriggers.Count - 1 ? 0 : _triggers[i].TriggerCurrentIndex + 1;
                }

                GUI.enabled = true;

                EditorGUILayout.EndHorizontal();
            }

            AddSpace();


            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 6
0
        IEnumerator AdjustTargetInfluenceRoutine(CameraTarget cameraTarget, float influenceH, float influenceV, float duration, bool removeIfZeroInfluence = false)
        {
            var startInfluenceH = cameraTarget.TargetInfluenceH;
            var startInfluenceV = cameraTarget.TargetInfluenceV;

            var waitForFixedUpdate = new WaitForFixedUpdate();
            var t = 0f;
            while (t <= 1.0f)
            {
                t += (UpdateType == UpdateType.LateUpdate ? Time.deltaTime : Time.fixedDeltaTime) / duration;
                cameraTarget.TargetInfluenceH = Utils.EaseFromTo(startInfluenceH, influenceH, t, EaseType.Linear);
                cameraTarget.TargetInfluenceV = Utils.EaseFromTo(startInfluenceV, influenceV, t, EaseType.Linear);

                yield return (UpdateType == UpdateType.FixedUpdate) ? waitForFixedUpdate : null;
            }

            if (removeIfZeroInfluence && cameraTarget.TargetInfluenceH <= 0 && cameraTarget.TargetInfluenceV <= 0)
                CameraTargets.Remove(cameraTarget);
        }
Esempio n. 7
0
        /// <summary>Adjusts a target influence</summary>
        /// <param name="cameraTarget">The CameraTarget of the target</param>
        /// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
        /// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
        /// <param name="duration">The time it takes for this target to reach it's influence. Don't use a duration if calling every frame.</param>
        public Coroutine AdjustCameraTargetInfluence(CameraTarget cameraTarget, float targetInfluenceH, float targetInfluenceV, float duration = 0)
        {
            if (duration > 0)
                return StartCoroutine(AdjustTargetInfluenceRoutine(cameraTarget, targetInfluenceH, targetInfluenceV, duration));
            else
            {
                cameraTarget.TargetInfluenceH = targetInfluenceH;
                cameraTarget.TargetInfluenceV = targetInfluenceH;

                return null;
            }
        }
Esempio n. 8
0
        /// <summary>Add a target for the camera to follow.</summary>
        /// <param name="targetTransform">The Transform of the target</param>
        /// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
        /// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
        /// <param name="duration">The time it takes for this target to reach it's influence. Use for a more progressive transition.</param>
        public CameraTarget AddCameraTarget(Transform targetTransform, float targetInfluenceH = 1f, float targetInfluenceV = 1f, float duration = 0f)
        {
            var newCameraTarget = new CameraTarget
            {
                TargetTransform = targetTransform,
                TargetInfluenceH = targetInfluenceH,
                TargetInfluenceV = targetInfluenceV,
            };

            CameraTargets.Add(newCameraTarget);

            if (duration > 0f)
            {
                newCameraTarget.TargetInfluence = 0f;
                StartCoroutine(AdjustTargetInfluenceRoutine(newCameraTarget, targetInfluenceH, targetInfluenceV, duration));
            }

            return newCameraTarget;
        }
        public override void OnInspectorGUI()
        {
            if (target == null)
            {
                return;
            }

            var proCamera2DRails = (ProCamera2DRails)target;

            if (proCamera2DRails.ProCamera2D == null)
            {
                EditorGUILayout.HelpBox("ProCamera2D is not set.", MessageType.Error, true);
            }

            serializedObject.Update();

            // Show script link
            GUI.enabled = false;
            _script     = EditorGUILayout.ObjectField("Script", _script, typeof(MonoScript), false) as MonoScript;
            GUI.enabled = true;

            // ProCamera2D
            _tooltip = new GUIContent("Pro Camera 2D", "");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("_pc2D"), _tooltip);
            EditorGUILayout.Space();

            // Targets Drop Area
            Event evt       = Event.current;
            Rect  drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var   style     = new GUIStyle("box");

            if (EditorGUIUtility.isProSkin)
            {
                style.normal.textColor = Color.white;
            }
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!drop_area.Contains(evt.mousePosition))
                {
                    return;
                }

                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (evt.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences)
                    {
                        var newCameraTarget = new CameraTarget
                        {
                            TargetTransform = ((GameObject)dragged_object).transform,
                            TargetInfluence = 1f
                        };

                        proCamera2DRails.CameraTargets.Add(newCameraTarget);
                        EditorUtility.SetDirty(proCamera2DRails);
                    }
                }
                break;
            }
            EditorGUILayout.Space();

            // Targets List
            _targetsList.DoLayoutList();
            EditorGUILayout.Space();
            EditorGUILayout.Space();

            // Follow mode
            _tooltip = new GUIContent("FollowMode", "This defines which axis to use to calculate the targets position on the rails");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowMode"), _tooltip);
            EditorGUILayout.Space();

            // Apply modified properties
            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 10
0
        public override void OnInspectorGUI()
        {
            var proCamera2D = (ProCamera2D)target;

            serializedObject.Update();


            EditorGUILayout.Space();

            // Draw User Guide link
            if (ProCamera2DEditorResources.UserGuideIcon != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.width  = ProCamera2DEditorResources.UserGuideIcon.width;
                rect.height = ProCamera2DEditorResources.UserGuideIcon.height;
                if (GUI.Button(new Rect(15, rect.y, 32, 32), new GUIContent(ProCamera2DEditorResources.UserGuideIcon, "User Guide")))
                {
                    Application.OpenURL("http://www.procamera2d.com/user-guide/");
                }
            }

            // Draw header
            if (ProCamera2DEditorResources.InspectorHeader != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.x     += 37;
                rect.width  = ProCamera2DEditorResources.InspectorHeader.width;
                rect.height = ProCamera2DEditorResources.InspectorHeader.height;
                GUILayout.Space(rect.height);
                GUI.DrawTexture(rect, ProCamera2DEditorResources.InspectorHeader);
            }

            EditorGUILayout.Space();


            // Review prompt
            if (_showReviewMessage)
            {
                EditorGUILayout.HelpBox("Sorry for the intrusion, but I need you for a second. Reviews on the Asset Store are very important for me to keep improving this product. Please take a minute to write a review and support ProCamera2D.", MessageType.Warning, true);
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Sure, I'll write a review!"))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                    Application.OpenURL("http://u3d.as/i7L");
                }
                if (GUILayout.Button("No, thanks."))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                }
                EditorGUILayout.EndHorizontal();
                AddSpace();
            }


            // Assign game camera
            if (proCamera2D.GameCamera == null)
            {
                proCamera2D.GameCamera = proCamera2D.GetComponent <Camera>();
            }


            // Targets Drop Area
            Event evt       = Event.current;
            Rect  drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var   style     = new GUIStyle("box");

            if (EditorGUIUtility.isProSkin)
            {
                style.normal.textColor = Color.white;
            }
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!drop_area.Contains(evt.mousePosition))
                {
                    return;
                }

                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (evt.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (Object dragged_object in DragAndDrop.objectReferences)
                    {
                        var newCameraTarget = new CameraTarget
                        {
                            TargetTransform = ((GameObject)dragged_object).transform,
                            TargetInfluence = 1f
                        };

                        proCamera2D.CameraTargets.Add(newCameraTarget);
                        EditorUtility.SetDirty(proCamera2D);
                    }
                }
                break;
            }

            EditorGUILayout.Space();



            // Remove empty targets
            for (int i = 0; i < proCamera2D.CameraTargets.Count; i++)
            {
                if (proCamera2D.CameraTargets[i].TargetTransform == null)
                {
                    proCamera2D.CameraTargets.RemoveAt(i);
                }
            }



            // Targets List
            _targetsList.DoLayoutList();
            AddSpace();



            // Center target on start
            _tooltip = new GUIContent("Center target on start", "Should the camera move instantly to the target on game start?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CenterTargetOnStart"), _tooltip);

            AddSpace();



            // Axis
            _tooltip = new GUIContent("Axis", "Choose the axis in which the camera should move.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("Axis"), _tooltip);

            AddSpace();



            // UpdateType
            _tooltip = new GUIContent("Update Type", "LateUpdate: Non physics based game\nFixedUpdate: Physics based game");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UpdateType"), _tooltip);

            AddSpace();



            // Show correct axis name
            switch (proCamera2D.Axis)
            {
            case MovementAxis.XY:
                hAxis = "X";
                vAxis = "Y";
                break;

            case MovementAxis.XZ:
                hAxis = "X";
                vAxis = "Z";
                break;

            case MovementAxis.YZ:
                hAxis = "Y";
                vAxis = "Z";
                break;
            }



            // Follow horizontal
            _tooltip = new GUIContent("Follow " + hAxis, "Should the camera move on the horizontal axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowHorizontal"), _tooltip);
            if (proCamera2D.FollowHorizontal)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target horizontal position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("HorizontalFollowSmoothness"), _tooltip);

                if (proCamera2D.HorizontalFollowSmoothness < 0f)
                {
                    proCamera2D.HorizontalFollowSmoothness = 0f;
                }

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitHorizontalCameraDistance"), _tooltip);

                if (proCamera2D.LimitHorizontalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxHorizontalTargetDistance < .1f)
                    {
                        proCamera2D.MaxHorizontalTargetDistance = .1f;
                    }
                    else if (proCamera2D.MaxHorizontalTargetDistance > 1f)
                    {
                        proCamera2D.MaxHorizontalTargetDistance = 1f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                // Limit speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the horizontal axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxHorizontalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxHorizontalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the horizontal axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalSpeed"), _tooltip);

                    if (proCamera2D.MaxHorizontalSpeed <= 0)
                    {
                        proCamera2D.MaxHorizontalSpeed = 0.01f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
                AddSpace();
            }



            // Follow vertical
            _tooltip = new GUIContent("Follow " + vAxis, "Should the camera move on the vertical axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowVertical"), _tooltip);

            if (proCamera2D.FollowVertical)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target vertical position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("VerticalFollowSmoothness"), _tooltip);

                if (proCamera2D.VerticalFollowSmoothness < 0f)
                {
                    proCamera2D.VerticalFollowSmoothness = 0f;
                }

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitVerticalCameraDistance"), _tooltip);

                if (proCamera2D.LimitVerticalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxVerticalTargetDistance < .1f)
                    {
                        proCamera2D.MaxVerticalTargetDistance = .1f;
                    }
                    else if (proCamera2D.MaxVerticalTargetDistance > 1f)
                    {
                        proCamera2D.MaxVerticalTargetDistance = 1f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                // Limit camera speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the vertical axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxVerticalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxVerticalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the vertical axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalSpeed"), _tooltip);

                    if (proCamera2D.MaxVerticalSpeed <= 0)
                    {
                        proCamera2D.MaxVerticalSpeed = 0.01f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
            }

            if (!proCamera2D.FollowHorizontal && !proCamera2D.FollowVertical)
            {
                EditorGUILayout.HelpBox("Camera won't move if it's not following the targets on any axis.", MessageType.Error, true);
            }

            AddSpace();



            // Overall offset
            EditorGUILayout.LabelField("Offset");
            EditorGUI.indentLevel = 1;

            _tooltip = new GUIContent(hAxis, "Horizontal offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.x"), _tooltip);

            _tooltip = new GUIContent(vAxis, "Vertical offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.y"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();



            // Zoom with FOV
            if (!proCamera2D.GameCamera.orthographic)
            {
                GUI.enabled = !Application.isPlaying;
                _tooltip    = new GUIContent("Zoom With FOV", "If enabled, when using a perspective camera, the camera will zoom by changing the FOV instead of moving the camera closer/further from the objects.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("ZoomWithFOV"), _tooltip);
                GUI.enabled = true;
                AddSpace();
            }



            // Divider
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("EXTENSIONS", EditorStyles.boldLabel);



            // Camera window plugin
            EditorGUILayout.BeginHorizontal();

            var cameraWindow = proCamera2D.GetComponent <ProCamera2DCameraWindow>();

            EditorGUILayout.LabelField("Camera Window");
            if (cameraWindow == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    cameraWindow             = proCamera2D.gameObject.AddComponent <ProCamera2DCameraWindow>();
                    cameraWindow.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(cameraWindow);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Cinematics plugin
            EditorGUILayout.BeginHorizontal();

            var cinematics = proCamera2D.GetComponent <ProCamera2DCinematics>();

            EditorGUILayout.LabelField("Cinematics");
            if (cinematics == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    cinematics             = proCamera2D.gameObject.AddComponent <ProCamera2DCinematics>();
                    cinematics.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(cinematics);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Forward focus plugin
            EditorGUILayout.BeginHorizontal();

            var forwardFocus = proCamera2D.GetComponent <ProCamera2DForwardFocus>();

            EditorGUILayout.LabelField("Forward Focus");
            if (forwardFocus == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    forwardFocus             = proCamera2D.gameObject.AddComponent <ProCamera2DForwardFocus>();
                    forwardFocus.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(forwardFocus);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Geometry boundaries plugin
            EditorGUILayout.BeginHorizontal();

            var geometryBoundaries = proCamera2D.GetComponent <ProCamera2DGeometryBoundaries>();

            EditorGUILayout.LabelField("Geometry Boundaries");
            if (geometryBoundaries == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    geometryBoundaries             = proCamera2D.gameObject.AddComponent <ProCamera2DGeometryBoundaries>();
                    geometryBoundaries.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(geometryBoundaries);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Numeric boundaries plugin
            EditorGUILayout.BeginHorizontal();

            var numericBoundaries = proCamera2D.GetComponent <ProCamera2DNumericBoundaries>();

            EditorGUILayout.LabelField("Numeric Boundaries");
            if (numericBoundaries == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    numericBoundaries             = proCamera2D.gameObject.AddComponent <ProCamera2DNumericBoundaries>();
                    numericBoundaries.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(numericBoundaries);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Parallax plugin
            GUI.enabled = proCamera2D.GameCamera.orthographic;

            EditorGUILayout.BeginHorizontal();

            var parallax = proCamera2D.GetComponent <ProCamera2DParallax>();

            EditorGUILayout.LabelField("Parallax");
            if (parallax == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    parallax             = proCamera2D.gameObject.AddComponent <ProCamera2DParallax>();
                    parallax.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(parallax);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            GUI.enabled = true;



            // Pixel perfect plugin
            EditorGUILayout.BeginHorizontal();

            var pixelPerfect = proCamera2D.GetComponent <ProCamera2DPixelPerfect>();

            EditorGUILayout.LabelField("Pixel Perfect");
            if (pixelPerfect == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    pixelPerfect             = proCamera2D.gameObject.AddComponent <ProCamera2DPixelPerfect>();
                    pixelPerfect.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(pixelPerfect);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Pointer influence plugin
            EditorGUILayout.BeginHorizontal();

            var pointerInfluence = proCamera2D.GetComponent <ProCamera2DPointerInfluence>();

            EditorGUILayout.LabelField("Pointer Influence");
            if (pointerInfluence == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    pointerInfluence             = proCamera2D.gameObject.AddComponent <ProCamera2DPointerInfluence>();
                    pointerInfluence.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(pointerInfluence);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Rails
            EditorGUILayout.BeginHorizontal();

            var rails = proCamera2D.GetComponent <ProCamera2DRails>();

            EditorGUILayout.LabelField("Rails");
            if (rails == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    rails             = proCamera2D.gameObject.AddComponent <ProCamera2DRails>();
                    rails.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(rails);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Shake plugin
            EditorGUILayout.BeginHorizontal();

            var shake = proCamera2D.GetComponent <ProCamera2DShake>();

            EditorGUILayout.LabelField("Shake");
            if (shake == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    shake             = proCamera2D.gameObject.AddComponent <ProCamera2DShake>();
                    shake.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(shake);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Speed based zoom plugin
            EditorGUILayout.BeginHorizontal();

            var speedBasedZoom = proCamera2D.GetComponent <ProCamera2DSpeedBasedZoom>();

            EditorGUILayout.LabelField("Speed Based Zoom");
            if (speedBasedZoom == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    speedBasedZoom             = proCamera2D.gameObject.AddComponent <ProCamera2DSpeedBasedZoom>();
                    speedBasedZoom.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(speedBasedZoom);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Zoom to fit plugin
            EditorGUILayout.BeginHorizontal();

            var zoomToFit = proCamera2D.GetComponent <ProCamera2DZoomToFitTargets>();

            EditorGUILayout.LabelField("Zoom-To-Fit");
            if (zoomToFit == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    zoomToFit             = proCamera2D.gameObject.AddComponent <ProCamera2DZoomToFitTargets>();
                    zoomToFit.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(zoomToFit);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Divider
            EditorGUILayout.Space();
            GUI.color = Color.white;
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("TRIGGERS", EditorStyles.boldLabel);



            // Boundaries trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Boundaries Trigger (" + _triggerBoundaries.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerBoundaries");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var boundsTrigger = newGo.AddComponent <ProCamera2DTriggerBoundaries>();
                boundsTrigger.ProCamera2D = proCamera2D;
                _triggerBoundaries.Add(boundsTrigger);
            }

            GUI.enabled = _triggerBoundaries.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerBoundaries[_currentTriggerBoundaries].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerBoundaries[_currentTriggerBoundaries].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerBoundaries = _currentTriggerBoundaries >= _triggerBoundaries.Count - 1 ? 0 : _currentTriggerBoundaries + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Influence trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Influence Trigger (" + _triggerInfluence.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerInfluence");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var influenceTrigger = newGo.AddComponent <ProCamera2DTriggerInfluence>();
                influenceTrigger.ProCamera2D = proCamera2D;
                _triggerInfluence.Add(influenceTrigger);
            }

            GUI.enabled = _triggerInfluence.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerInfluence[_currentTriggerInfluence].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerInfluence[_currentTriggerInfluence].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerInfluence = _currentTriggerInfluence >= _triggerInfluence.Count - 1 ? 0 : _currentTriggerInfluence + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Rails trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Rails Trigger (" + _triggerRails.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerRails");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var railsTrigger = newGo.AddComponent <ProCamera2DTriggerRails>();
                railsTrigger.ProCamera2D = proCamera2D;
                _triggerRails.Add(railsTrigger);
            }

            GUI.enabled = _triggerRails.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerRails[_currentTriggerRails].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerRails[_currentTriggerRails].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerRails = _currentTriggerRails >= _triggerRails.Count - 1 ? 0 : _currentTriggerRails + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Zoom trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Zoom Trigger (" + _triggerZoom.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerZoom");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var zoomTrigger = newGo.AddComponent <ProCamera2DTriggerZoom>();
                zoomTrigger.ProCamera2D = proCamera2D;
                _triggerZoom.Add(zoomTrigger);
            }

            GUI.enabled = _triggerZoom.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerZoom[_currentTriggerZoom].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerZoom[_currentTriggerZoom].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerZoom = _currentTriggerZoom >= _triggerZoom.Count - 1 ? 0 : _currentTriggerZoom + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            AddSpace();


            serializedObject.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            EditorGUI.BeginChangeCheck();

            var proCamera2D = (ProCamera2D)target;

            serializedObject.Update();


            EditorGUILayout.Space();

            // Draw User Guide link
            if (ProCamera2DEditorResources.UserGuideIcon != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.width  = ProCamera2DEditorResources.UserGuideIcon.width;
                rect.height = ProCamera2DEditorResources.UserGuideIcon.height;
                if (GUI.Button(new Rect(15, rect.y, 32, 32), new GUIContent(ProCamera2DEditorResources.UserGuideIcon, "User Guide")))
                {
                    Application.OpenURL("http://www.procamera2d.com/user-guide/");
                }
            }

            // Draw header
            if (ProCamera2DEditorResources.InspectorHeader != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.x     += 37;
                rect.width  = ProCamera2DEditorResources.InspectorHeader.width;
                rect.height = ProCamera2DEditorResources.InspectorHeader.height;
                GUILayout.Space(rect.height);
                GUI.DrawTexture(rect, ProCamera2DEditorResources.InspectorHeader);
            }

            EditorGUILayout.Space();


            // Review prompt
            if (_showReviewMessage)
            {
                EditorGUILayout.HelpBox("Sorry for the intrusion, but I need you for a second. Reviews on the Asset Store are very important for me to keep improving this product. Please take a minute to write a review and support ProCamera2D.", MessageType.Warning, true);
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Sure, I'll write a review!"))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                    Application.OpenURL("http://u3d.as/i7L");
                }
                if (GUILayout.Button("No, thanks."))
                {
                    _showReviewMessage = false;
                    EditorPrefs.SetInt("ProCamera2DReview", -1);
                }
                EditorGUILayout.EndHorizontal();
                AddSpace();
            }


            // Assign game camera
            if (proCamera2D.GameCamera == null)
            {
                proCamera2D.GameCamera = proCamera2D.GetComponent <Camera>();
            }


            // Targets Drop Area
            Event evt       = Event.current;
            Rect  drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var   style     = new GUIStyle("box");

            if (EditorGUIUtility.isProSkin)
            {
                style.normal.textColor = Color.white;
            }
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            Undo.RecordObject(proCamera2D, "Added camera targets");
            switch (evt.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!drop_area.Contains(evt.mousePosition))
                {
                    return;
                }

                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (evt.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (Object dragged_object in DragAndDrop.objectReferences)
                    {
                        var newCameraTarget = new CameraTarget
                        {
                            TargetTransform = ((GameObject)dragged_object).transform,
                            TargetInfluence = 1f
                        };

                        proCamera2D.CameraTargets.Add(newCameraTarget);
                        EditorUtility.SetDirty(proCamera2D);
                    }
                }
                break;
            }

            EditorGUILayout.Space();



            // Remove empty targets
            for (int i = 0; i < proCamera2D.CameraTargets.Count; i++)
            {
                if (proCamera2D.CameraTargets[i].TargetTransform == null)
                {
                    proCamera2D.CameraTargets.RemoveAt(i);
                }
            }



            // Targets List
            _targetsList.DoLayoutList();
            AddSpace();



            // Center target on start
            _tooltip = new GUIContent("Center target on start", "Should the camera move instantly to the target on game start?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CenterTargetOnStart"), _tooltip);

            AddSpace();



            // Axis
            _tooltip = new GUIContent("Axis", "Choose the axis in which the camera should move.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("Axis"), _tooltip);

            AddSpace();



            // UpdateType
            _tooltip = new GUIContent("Update Type", "LateUpdate: Non physics based game\nFixedUpdate: Physics based game");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UpdateType"), _tooltip);

            AddSpace();



            // Show correct axis name
            switch (proCamera2D.Axis)
            {
            case MovementAxis.XY:
                hAxis = "X";
                vAxis = "Y";
                break;

            case MovementAxis.XZ:
                hAxis = "X";
                vAxis = "Z";
                break;

            case MovementAxis.YZ:
                hAxis = "Y";
                vAxis = "Z";
                break;
            }



            // Follow horizontal
            EditorGUILayout.BeginHorizontal();
            _tooltip = new GUIContent("Follow " + hAxis, "Should the camera move on the horizontal axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowHorizontal"), _tooltip);
            if (proCamera2D.FollowHorizontal)
            {
                // Follow smoothness
                _tooltip = new GUIContent("Smoothness", "How long it takes the camera to reach the target horizontal position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("HorizontalFollowSmoothness"), _tooltip);

                if (proCamera2D.HorizontalFollowSmoothness < 0f)
                {
                    proCamera2D.HorizontalFollowSmoothness = 0f;
                }
            }
            EditorGUILayout.EndHorizontal();


            // Follow vertical
            EditorGUILayout.BeginHorizontal();
            _tooltip = new GUIContent("Follow " + vAxis, "Should the camera move on the vertical axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowVertical"), _tooltip);

            if (proCamera2D.FollowVertical)
            {
                // Follow smoothness
                _tooltip = new GUIContent("Smoothness", "How long it takes the camera to reach the target vertical position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("VerticalFollowSmoothness"), _tooltip);

                if (proCamera2D.VerticalFollowSmoothness < 0f)
                {
                    proCamera2D.VerticalFollowSmoothness = 0f;
                }
            }
            EditorGUILayout.EndHorizontal();

            if (!proCamera2D.FollowHorizontal && !proCamera2D.FollowVertical)
            {
                EditorGUILayout.HelpBox("Camera won't move if it's not following the targets on any axis.", MessageType.Error, true);
            }

            AddSpace();



            // Overall offset
            EditorGUILayout.LabelField("Offset");
            EditorGUI.indentLevel = 1;

            if (proCamera2D.IsRelativeOffset)
            {
                _tooltip = new GUIContent(hAxis, "Horizontal offset");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("OffsetX"), _tooltip);

                _tooltip = new GUIContent(vAxis, "Vertical offset");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("OffsetY"), _tooltip);
            }
            else
            {
                _tooltip = new GUIContent(hAxis, "Horizontal offset");
                serializedObject.FindProperty("OffsetX").floatValue = EditorGUILayout.FloatField(hAxis, serializedObject.FindProperty("OffsetX").floatValue);

                _tooltip = new GUIContent(vAxis, "Vertical offset");
                serializedObject.FindProperty("OffsetY").floatValue = EditorGUILayout.FloatField(vAxis, serializedObject.FindProperty("OffsetY").floatValue);
            }

            _tooltip = new GUIContent("Relative Offset", "If enabled, the offset is relative to the current screen size. Otherwise it's in world units.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("IsRelativeOffset"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();



            // Zoom with FOV
            if (!proCamera2D.GameCamera.orthographic)
            {
                GUI.enabled = !Application.isPlaying;
                _tooltip    = new GUIContent("Zoom With FOV", "If enabled, when using a perspective camera, the camera will zoom by changing the FOV instead of moving the camera closer/further from the objects.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("ZoomWithFOV"), _tooltip);
                GUI.enabled = true;
                AddSpace();
            }



            // Ignore TimeScale
            _tooltip = new GUIContent("Ignore TimeScale", "If enabled, the camera will not be affected by the Time.timeScale. It will use Time.unscaledDeltaTime instead.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("IgnoreTimeScale"), _tooltip);
            AddSpace();



            // Divider
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("EXTENSIONS", EditorStyles.boldLabel);
            EditorGUILayout.Space();


            // Extensions
            GUI.color = Color.white;
            for (int i = 0; i < _extensions.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField(_extensions[i].ExtName);
                if (_extensions[i].Component == null)
                {
                    GUI.color = new Color(133f / 255f, 235f / 255f, 154f / 255f, 1f);
                    if (GUILayout.Button("Enable"))
                    {
                        _extensions[i].Component = proCamera2D.gameObject.AddComponent(_extensions[i].ExtType) as BasePC2D;
                    }
                }
                else
                {
                    GUI.color = new Color(236f / 255f, 72f / 255f, 105f / 255f, 1f);
                    if (GUILayout.Button("Disable"))
                    {
                        if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this extension?", "Yes", "No"))
                        {
                            DestroyImmediate(_extensions[i].Component);
                            EditorGUIUtility.ExitGUI();
                        }
                    }
                }
                GUI.color = Color.white;
                EditorGUILayout.EndHorizontal();
            }



            // Divider
            EditorGUILayout.Space();
            GUI.color = Color.white;
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("TRIGGERS", EditorStyles.boldLabel);
            EditorGUILayout.Space();


            // Triggers
            for (int i = 0; i < _triggers.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField(_triggers[i].TriggerName + " (" + _triggers[i].AllTriggers.Count() + ")");

                if (GUILayout.Button("Add"))
                {
                    var newGo = new GameObject(_triggers[i].TriggerType.Name);
                    newGo.transform.localScale = new Vector3(5, 5, 5);
                    var trigger = newGo.AddComponent(_triggers[i].TriggerType) as BasePC2D;
                    _triggers[i].AllTriggers.Add(trigger);
                }

                GUI.enabled = _triggers[i].AllTriggers.Count() > 0;

                if (GUILayout.Button(">"))
                {
                    Selection.activeGameObject = ((BasePC2D)_triggers[i].AllTriggers[_triggers[i].TriggerCurrentIndex]).gameObject;
                    SceneView.FrameLastActiveSceneView();
                    EditorGUIUtility.PingObject(((BasePC2D)_triggers[i].AllTriggers[_triggers[i].TriggerCurrentIndex]).gameObject);

                    Selection.activeGameObject = proCamera2D.gameObject;

                    _triggers[i].TriggerCurrentIndex = _triggers[i].TriggerCurrentIndex >= _triggers[i].AllTriggers.Count - 1 ? 0 : _triggers[i].TriggerCurrentIndex + 1;
                }

                GUI.enabled = true;

                EditorGUILayout.EndHorizontal();
            }

            AddSpace();


            serializedObject.ApplyModifiedProperties();

            if (EditorGUI.EndChangeCheck())
            {
                EditorUtility.SetDirty(proCamera2D);
            }
        }
        public override void OnInspectorGUI()
        {
            var proCamera2DRails = (ProCamera2DRails)target;
            
            if(proCamera2DRails.ProCamera2D == null)
                EditorGUILayout.HelpBox("ProCamera2D is not set.", MessageType.Error, true);
                
            serializedObject.Update();
            
            // Show script link
            _script = EditorGUILayout.ObjectField("Script", _script, typeof(MonoScript), false) as MonoScript;

            // ProCamera2D
            _tooltip = new GUIContent("Pro Camera 2D", "");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("ProCamera2D"), _tooltip);
            EditorGUILayout.Space();
            
            // Targets Drop Area
            Event evt = Event.current;
            Rect drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var style = new GUIStyle("box");
            if (EditorGUIUtility.isProSkin)
                style.normal.textColor = Color.white;
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!drop_area.Contains(evt.mousePosition))
                        return;

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (evt.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences)
                        {
                            var newCameraTarget = new CameraTarget
                            {
                                TargetTransform = ((GameObject)dragged_object).transform,
                                TargetInfluence = 1f
                            };
							
                            proCamera2DRails.CameraTargets.Add(newCameraTarget);
                            EditorUtility.SetDirty(proCamera2DRails);
                        }
                    }
                    break;
            }
            EditorGUILayout.Space();
            
            // Targets List
            _targetsList.DoLayoutList();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
            
            // Follow mode
            _tooltip = new GUIContent("FollowMode", "This defines which axis to use to calculate the targets position on the rails");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowMode"), _tooltip);
            EditorGUILayout.Space();
            
            // Apply modified properties
            serializedObject.ApplyModifiedProperties();
        }
        IEnumerator AdjustTargetInfluenceRoutine(CameraTarget cameraTarget, float influenceH, float influenceV, float duration, bool removeIfZeroInfluence = false)
        {
            var startInfluenceH = cameraTarget.TargetInfluenceH;
            var startInfluenceV = cameraTarget.TargetInfluenceV;

            var t = 0f;
            while (t <= 1.0f)
            {
                t += _deltaTime / duration;
                cameraTarget.TargetInfluenceH = Utils.EaseFromTo(startInfluenceH, influenceH, t, EaseType.Linear);
                cameraTarget.TargetInfluenceV = Utils.EaseFromTo(startInfluenceV, influenceV, t, EaseType.Linear);

                yield return GetYield();
            }

            if (removeIfZeroInfluence && cameraTarget.TargetInfluenceH <= 0 && cameraTarget.TargetInfluenceV <= 0)
                CameraTargets.Remove(cameraTarget);
        }
Esempio n. 14
0
        public override void OnInspectorGUI()
        {
            var proCamera2D = (ProCamera2D)target;

            serializedObject.Update();

            EditorGUILayout.Space();

            // Draw User Guide link
            if (ProCamera2DEditorResources.UserGuideIcon != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.width = ProCamera2DEditorResources.UserGuideIcon.width;
                rect.height = ProCamera2DEditorResources.UserGuideIcon.height;
                if (GUI.Button(new Rect(15, rect.y, 32, 32), new GUIContent(ProCamera2DEditorResources.UserGuideIcon, "User Guide")))
                {
                    Application.OpenURL("http://www.procamera2d.com/user-guide/");
                }
            }

            // Draw header
            if (ProCamera2DEditorResources.InspectorHeader != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.x += 37;
                rect.width = ProCamera2DEditorResources.InspectorHeader.width;
                rect.height = ProCamera2DEditorResources.InspectorHeader.height;
                GUILayout.Space(rect.height);
                GUI.DrawTexture(rect, ProCamera2DEditorResources.InspectorHeader);
            }

            EditorGUILayout.Space();

            // Assign game camera
            if (proCamera2D.GameCamera == null)
                proCamera2D.GameCamera = proCamera2D.GetComponent<Camera>();

            // Targets Drop Area
            Event evt = Event.current;
            Rect drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var style = new GUIStyle("box");
            if (EditorGUIUtility.isProSkin)
                style.normal.textColor = Color.white;
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (!drop_area.Contains(evt.mousePosition))
                        return;

                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                    if (evt.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        foreach (Object dragged_object in DragAndDrop.objectReferences)
                        {
                            var newCameraTarget = new CameraTarget
                            {
                                TargetTransform = ((GameObject)dragged_object).transform,
                                TargetInfluence = 1f
                            };

                            proCamera2D.CameraTargets.Add(newCameraTarget);
                            EditorUtility.SetDirty(proCamera2D);
                        }
                    }
                    break;
            }

            EditorGUILayout.Space();

            // Remove empty targets
            for (int i = 0; i < proCamera2D.CameraTargets.Count; i++)
            {
                if (proCamera2D.CameraTargets[i].TargetTransform == null)
                {
                    proCamera2D.CameraTargets.RemoveAt(i);
                }
            }

            // Targets List
            _targetsList.DoLayoutList();
            AddSpace();

            // Center target on start
            _tooltip = new GUIContent("Center target on start", "Should the camera move instantly to the target on game start?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CenterTargetOnStart"), _tooltip);

            AddSpace();

            // Axis
            _tooltip = new GUIContent("Axis", "Choose the axis in which the camera should move.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("Axis"), _tooltip);

            AddSpace();

            // UpdateType
            _tooltip = new GUIContent("Update Type", "LateUpdate: Non physics based game\nFixedUpdate: Physics based game");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UpdateType"), _tooltip);

            AddSpace();

            // Show correct axis name
            switch (proCamera2D.Axis)
            {
                case MovementAxis.XY:
                    hAxis = "X";
                    vAxis = "Y";
                    break;

                case MovementAxis.XZ:
                    hAxis = "X";
                    vAxis = "Z";
                    break;

                case MovementAxis.YZ:
                    hAxis = "Y";
                    vAxis = "Z";
                    break;
            }

            // Follow horizontal
            _tooltip = new GUIContent("Follow " + hAxis, "Should the camera move on the horizontal axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowHorizontal"), _tooltip);
            if (proCamera2D.FollowHorizontal)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target horizontal position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("HorizontalFollowSmoothness"), _tooltip);

                if (proCamera2D.HorizontalFollowSmoothness < 0f)
                    proCamera2D.HorizontalFollowSmoothness = 0f;

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitHorizontalCameraDistance"), _tooltip);

                if (proCamera2D.LimitHorizontalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxHorizontalTargetDistance < .1f)
                        proCamera2D.MaxHorizontalTargetDistance = .1f;
                    else if (proCamera2D.MaxHorizontalTargetDistance > 1f)
                        proCamera2D.MaxHorizontalTargetDistance = 1f;
                }

                EditorGUILayout.EndHorizontal();

                // Limit speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the horizontal axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxHorizontalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxHorizontalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the horizontal axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalSpeed"), _tooltip);

                    if (proCamera2D.MaxHorizontalSpeed <= 0)
                        proCamera2D.MaxHorizontalSpeed = 0.01f;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
                AddSpace();
            }

            // Follow vertical
            _tooltip = new GUIContent("Follow " + vAxis, "Should the camera move on the vertical axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowVertical"), _tooltip);

            if (proCamera2D.FollowVertical)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target vertical position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("VerticalFollowSmoothness"), _tooltip);

                if (proCamera2D.VerticalFollowSmoothness < 0f)
                    proCamera2D.VerticalFollowSmoothness = 0f;

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitVerticalCameraDistance"), _tooltip);

                if (proCamera2D.LimitVerticalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxVerticalTargetDistance < .1f)
                        proCamera2D.MaxVerticalTargetDistance = .1f;
                    else if (proCamera2D.MaxVerticalTargetDistance > 1f)
                        proCamera2D.MaxVerticalTargetDistance = 1f;
                }

                EditorGUILayout.EndHorizontal();

                // Limit camera speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the vertical axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxVerticalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxVerticalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the vertical axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalSpeed"), _tooltip);

                    if (proCamera2D.MaxVerticalSpeed <= 0)
                        proCamera2D.MaxVerticalSpeed = 0.01f;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
            }

            if (!proCamera2D.FollowHorizontal && !proCamera2D.FollowVertical)
                EditorGUILayout.HelpBox("Camera won't move if it's not following the targets on any axis.", MessageType.Error, true);

            AddSpace();

            // Overall offset
            EditorGUILayout.LabelField("Offset");
            EditorGUI.indentLevel = 1;

            _tooltip = new GUIContent(hAxis, "Horizontal offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.x"), _tooltip);

            _tooltip = new GUIContent(vAxis, "Vertical offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.y"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();

            // Divider
            GUILayout.Box("", new GUILayoutOption[]{ GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("EXTENSIONS", EditorStyles.boldLabel);

            // Camera window plugin
            EditorGUILayout.BeginHorizontal();

            var cameraWindow = proCamera2D.GetComponent<ProCamera2DCameraWindow>();

            EditorGUILayout.LabelField("Camera Window");
            if (cameraWindow == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    cameraWindow = proCamera2D.gameObject.AddComponent<ProCamera2DCameraWindow>();
                    cameraWindow.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(cameraWindow);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Cinematics plugin
            EditorGUILayout.BeginHorizontal();

            var cinematics = proCamera2D.GetComponent<ProCamera2DCinematics>();

            EditorGUILayout.LabelField("Cinematics");
            if (cinematics == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    cinematics = proCamera2D.gameObject.AddComponent<ProCamera2DCinematics>();
                    cinematics.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(cinematics);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Forward focus plugin
            EditorGUILayout.BeginHorizontal();

            var forwardFocus = proCamera2D.GetComponent<ProCamera2DForwardFocus>();

            EditorGUILayout.LabelField("Forward Focus");
            if (forwardFocus == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    forwardFocus = proCamera2D.gameObject.AddComponent<ProCamera2DForwardFocus>();
                    forwardFocus.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(forwardFocus);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Geometry boundaries plugin
            EditorGUILayout.BeginHorizontal();

            var geometryBoundaries = proCamera2D.GetComponent<ProCamera2DGeometryBoundaries>();

            EditorGUILayout.LabelField("Geometry Boundaries");
            if (geometryBoundaries == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    geometryBoundaries = proCamera2D.gameObject.AddComponent<ProCamera2DGeometryBoundaries>();
                    geometryBoundaries.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(geometryBoundaries);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Numeric boundaries plugin
            EditorGUILayout.BeginHorizontal();

            var numericBoundaries = proCamera2D.GetComponent<ProCamera2DNumericBoundaries>();

            EditorGUILayout.LabelField("Numeric Boundaries");
            if (numericBoundaries == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    numericBoundaries = proCamera2D.gameObject.AddComponent<ProCamera2DNumericBoundaries>();
                    numericBoundaries.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(numericBoundaries);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Parallax plugin
            GUI.enabled = proCamera2D.GameCamera.orthographic;

            EditorGUILayout.BeginHorizontal();

            var parallax = proCamera2D.GetComponent<ProCamera2DParallax>();

            EditorGUILayout.LabelField("Parallax");
            if (parallax == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    parallax = proCamera2D.gameObject.AddComponent<ProCamera2DParallax>();
                    parallax.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(parallax);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            GUI.enabled = true;

            // Pixel perfect plugin
            EditorGUILayout.BeginHorizontal();

            var pixelPerfect = proCamera2D.GetComponent<ProCamera2DPixelPerfect>();

            EditorGUILayout.LabelField("Pixel Perfect");
            if (pixelPerfect == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    pixelPerfect = proCamera2D.gameObject.AddComponent<ProCamera2DPixelPerfect>();
                    pixelPerfect.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(pixelPerfect);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Pointer influence plugin
            EditorGUILayout.BeginHorizontal();

            var pointerInfluence = proCamera2D.GetComponent<ProCamera2DPointerInfluence>();

            EditorGUILayout.LabelField("Pointer Influence");
            if (pointerInfluence == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    pointerInfluence = proCamera2D.gameObject.AddComponent<ProCamera2DPointerInfluence>();
                    pointerInfluence.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(pointerInfluence);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Shake plugin
            EditorGUILayout.BeginHorizontal();

            var shake = proCamera2D.GetComponent<ProCamera2DShake>();

            EditorGUILayout.LabelField("Shake");
            if (shake == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    shake = proCamera2D.gameObject.AddComponent<ProCamera2DShake>();
                    shake.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(shake);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Speed based zoom plugin
            EditorGUILayout.BeginHorizontal();

            var speedBasedZoom = proCamera2D.GetComponent<ProCamera2DSpeedBasedZoom>();

            EditorGUILayout.LabelField("Speed Based Zoom");
            if (speedBasedZoom == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    speedBasedZoom = proCamera2D.gameObject.AddComponent<ProCamera2DSpeedBasedZoom>();
                    speedBasedZoom.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(speedBasedZoom);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Zoom to fit plugin
            EditorGUILayout.BeginHorizontal();

            var zoomToFit = proCamera2D.GetComponent<ProCamera2DZoomToFitTargets>();

            EditorGUILayout.LabelField("Zoom-To-Fit");
            if (zoomToFit == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    zoomToFit = proCamera2D.gameObject.AddComponent<ProCamera2DZoomToFitTargets>();
                    zoomToFit.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(zoomToFit);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            // Divider
            EditorGUILayout.Space();
            GUI.color = Color.white;
            GUILayout.Box("", new GUILayoutOption[]{ GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("TRIGGERS", EditorStyles.boldLabel);

            // Boundaries trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Boundaries Trigger (" + _triggerBoundaries.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerBoundaries");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var boundsTrigger = newGo.AddComponent<ProCamera2DTriggerBoundaries>();
                boundsTrigger.ProCamera2D = proCamera2D;
                _triggerBoundaries.Add(boundsTrigger);
            }

            GUI.enabled = _triggerBoundaries.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerBoundaries[_currentTriggerBoundaries].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerBoundaries[_currentTriggerBoundaries].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerBoundaries = _currentTriggerBoundaries >= _triggerBoundaries.Count - 1 ? 0 : _currentTriggerBoundaries + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            // Influence trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Influence Trigger (" + _triggerInfluence.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerInfluence");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var influenceTrigger = newGo.AddComponent<ProCamera2DTriggerInfluence>();
                influenceTrigger.ProCamera2D = proCamera2D;
                _triggerInfluence.Add(influenceTrigger);
            }

            GUI.enabled = _triggerInfluence.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerInfluence[_currentTriggerInfluence].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerInfluence[_currentTriggerInfluence].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerInfluence = _currentTriggerInfluence >= _triggerInfluence.Count - 1 ? 0 : _currentTriggerInfluence + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            // Zoom trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Zoom Trigger (" + _triggerZoom.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerZoom");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var zoomTrigger = newGo.AddComponent<ProCamera2DTriggerZoom>();
                zoomTrigger.ProCamera2D = proCamera2D;
                _triggerZoom.Add(zoomTrigger);
            }

            GUI.enabled = _triggerZoom.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerZoom[_currentTriggerZoom].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerZoom[_currentTriggerZoom].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerZoom = _currentTriggerZoom >= _triggerZoom.Count - 1 ? 0 : _currentTriggerZoom + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            AddSpace();

            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 15
0
        /// <summary>Add a target for the camera to follow on rails.</summary>
        /// <param name="targetTransform">The Transform of the target</param>
        /// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
        /// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
        /// <param name="targetOffset">A vector that offsets the target position that the camera will follow</param>
        public void AddRailsTarget(Transform targetTransform, float targetInfluenceH = 1f, float targetInfluenceV = 1f, Vector2 targetOffset = default(Vector2))
        {
            var newCameraTarget = new CameraTarget()
            {
                    TargetTransform = targetTransform,
                    TargetInfluenceH = targetInfluenceH,
                    TargetInfluenceV = targetInfluenceV,
                    TargetOffset = targetOffset
            };

            CameraTargets.Add(newCameraTarget);

            var railTransform = new GameObject(targetTransform.name + "_OnRails").transform;

            _cameraTargetsOnRails.Add(
                newCameraTarget,
                railTransform
            );

            ProCamera2D.AddCameraTarget(railTransform);

            enabled = true;
        }
Esempio n. 16
0
        public override void OnInspectorGUI()
        {
            var proCamera2D = (ProCamera2D)target;

            serializedObject.Update();


            EditorGUILayout.Space();

            // Draw User Guide link
            if (ProCamera2DEditorResources.UserGuideIcon != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.width  = ProCamera2DEditorResources.UserGuideIcon.width;
                rect.height = ProCamera2DEditorResources.UserGuideIcon.height;
                if (GUI.Button(new Rect(15, rect.y, 32, 32), new GUIContent(ProCamera2DEditorResources.UserGuideIcon, "User Guide")))
                {
                    Application.OpenURL("http://www.procamera2d.com/user-guide/");
                }
            }

            // Draw header
            if (ProCamera2DEditorResources.InspectorHeader != null)
            {
                var rect = GUILayoutUtility.GetRect(0f, 0f);
                rect.x     += 37;
                rect.width  = ProCamera2DEditorResources.InspectorHeader.width;
                rect.height = ProCamera2DEditorResources.InspectorHeader.height;
                GUILayout.Space(rect.height);
                GUI.DrawTexture(rect, ProCamera2DEditorResources.InspectorHeader);
            }

            EditorGUILayout.Space();


            // Assign game camera
            if (proCamera2D.GameCamera == null)
            {
                proCamera2D.GameCamera = proCamera2D.GetComponent <Camera>();
            }


            // Targets Drop Area
            Event evt       = Event.current;
            Rect  drop_area = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
            var   style     = new GUIStyle("box");

            if (EditorGUIUtility.isProSkin)
            {
                style.normal.textColor = Color.white;
            }
            GUI.Box(drop_area, "\nDROP CAMERA TARGETS HERE", style);

            switch (evt.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!drop_area.Contains(evt.mousePosition))
                {
                    return;
                }

                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (evt.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (Object dragged_object in DragAndDrop.objectReferences)
                    {
                        var newCameraTarget = new CameraTarget
                        {
                            TargetTransform = ((GameObject)dragged_object).transform,
                            TargetInfluence = 1f
                        };

                        proCamera2D.CameraTargets.Add(newCameraTarget);
                        EditorUtility.SetDirty(proCamera2D);
                    }
                }
                break;
            }

            EditorGUILayout.Space();



            // Remove empty targets
            for (int i = 0; i < proCamera2D.CameraTargets.Count; i++)
            {
                if (proCamera2D.CameraTargets[i].TargetTransform == null)
                {
                    proCamera2D.CameraTargets.RemoveAt(i);
                }
            }



            // Targets List
            _targetsList.DoLayoutList();
            AddSpace();



            // Center target on start
            _tooltip = new GUIContent("Center target on start", "Should the camera move instantly to the target on game start?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CenterTargetOnStart"), _tooltip);

            if (proCamera2D.CenterTargetOnStart && proCamera2D.UseGeometryBoundaries)
            {
                EditorGUILayout.HelpBox("Centering on target at start while using geometry boundaries might cause the camera to get stuck.", MessageType.Warning, true);
            }

            AddSpace();



            // Axis
            _tooltip = new GUIContent("Axis", "Choose the axis in which the camera should move.");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("Axis"), _tooltip);

            AddSpace();



            // UpdateType
            _tooltip = new GUIContent("Update Type", "LateUpdate: Non physics based game\nFixedUpdate: Physics based game");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UpdateType"), _tooltip);

            AddSpace();



            // Show correct axis name
            switch (proCamera2D.Axis)
            {
            case MovementAxis.XY:
                hAxis = "X";
                vAxis = "Y";
                break;

            case MovementAxis.XZ:
                hAxis = "X";
                vAxis = "Z";
                break;

            case MovementAxis.YZ:
                hAxis = "Y";
                vAxis = "Z";
                break;
            }



            // Follow horizontal
            _tooltip = new GUIContent("Follow " + hAxis, "Should the camera move on the horizontal axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowHorizontal"), _tooltip);
            if (proCamera2D.FollowHorizontal)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target horizontal position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("HorizontalFollowSmoothness"), _tooltip);

                if (proCamera2D.HorizontalFollowSmoothness < 0f)
                {
                    proCamera2D.HorizontalFollowSmoothness = 0f;
                }

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitHorizontalCameraDistance"), _tooltip);

                if (proCamera2D.LimitHorizontalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxHorizontalTargetDistance < .1f)
                    {
                        proCamera2D.MaxHorizontalTargetDistance = .1f;
                    }
                    else if (proCamera2D.MaxHorizontalTargetDistance > 1f)
                    {
                        proCamera2D.MaxHorizontalTargetDistance = 1f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                // Limit speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the horizontal axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxHorizontalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxHorizontalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the horizontal axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxHorizontalSpeed"), _tooltip);

                    if (proCamera2D.MaxHorizontalSpeed <= 0)
                    {
                        proCamera2D.MaxHorizontalSpeed = 0.01f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
                AddSpace();
            }



            // Follow vertical
            _tooltip = new GUIContent("Follow " + vAxis, "Should the camera move on the vertical axis?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("FollowVertical"), _tooltip);

            if (proCamera2D.FollowVertical)
            {
                EditorGUI.indentLevel = 1;

                // Follow smoothness
                _tooltip = new GUIContent("Follow Smoothness", "How long it takes the camera to reach the target vertical position.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("VerticalFollowSmoothness"), _tooltip);

                if (proCamera2D.VerticalFollowSmoothness < 0f)
                {
                    proCamera2D.VerticalFollowSmoothness = 0f;
                }

                // Limit camera distance to target
                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Limit Cam Distance", "Prevent the camera target from getting too far. Use this if you have a high follow smoothness and your targets are getting out of the screen.");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitVerticalCameraDistance"), _tooltip);

                if (proCamera2D.LimitVerticalCameraDistance)
                {
                    _tooltip = new GUIContent(" ", "The percentage of the screen at which the camera will be forced to move");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalTargetDistance"), _tooltip);

                    if (proCamera2D.MaxVerticalTargetDistance < .1f)
                    {
                        proCamera2D.MaxVerticalTargetDistance = .1f;
                    }
                    else if (proCamera2D.MaxVerticalTargetDistance > 1f)
                    {
                        proCamera2D.MaxVerticalTargetDistance = 1f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                // Limit camera speed
                EditorGUILayout.BeginHorizontal();

                _tooltip = new GUIContent("Limit Speed", "Limit how fast the camera moves per second on the vertical axis");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("LimitMaxVerticalSpeed"), _tooltip);

                if (proCamera2D.LimitMaxVerticalSpeed)
                {
                    _tooltip = new GUIContent(" ", "Limit how fast the camera moves per second on the vertical axis");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxVerticalSpeed"), _tooltip);

                    if (proCamera2D.MaxVerticalSpeed <= 0)
                    {
                        proCamera2D.MaxVerticalSpeed = 0.01f;
                    }
                }

                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel = 0;
            }

            if (!proCamera2D.FollowHorizontal && !proCamera2D.FollowVertical)
            {
                EditorGUILayout.HelpBox("Camera won't move if it's not following the targets on any axis.", MessageType.Error, true);
            }

            AddSpace();



            // Overall offset
            EditorGUILayout.LabelField("Offset");
            EditorGUI.indentLevel = 1;

            _tooltip = new GUIContent(hAxis, "Horizontal offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.x"), _tooltip);

            _tooltip = new GUIContent(vAxis, "Vertical offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("OverallOffset.y"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();



            // Camera window rect
            _tooltip = new GUIContent("Camera Window", "Inside this Rect the camera won't move. Use to avoid constant camera move with slight changes.");
            EditorGUILayout.LabelField(_tooltip);

            EditorGUI.indentLevel = 1;

            _tooltip = new GUIContent("Width", "Window width");
            EditorGUILayout.Slider(serializedObject.FindProperty("CameraWindowRect.width"), 0f, 1f, _tooltip);

            _tooltip = new GUIContent("Height", "Window height");
            EditorGUILayout.Slider(serializedObject.FindProperty("CameraWindowRect.height"), 0f, 1f, _tooltip);

            _tooltip = new GUIContent(hAxis, "Window horizontal offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CameraWindowRect.x"), _tooltip);

            _tooltip = new GUIContent(vAxis, "Window vertical offset");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("CameraWindowRect.y"), _tooltip);

            EditorGUI.indentLevel = 0;

            AddSpace();



            // Geometry boundaries
            _tooltip = new GUIContent("Use Geometry Boundaries", "Should the camera position be constrained by geometry?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UseGeometryBoundaries"), _tooltip);

            if (proCamera2D.UseGeometryBoundaries)
            {
                EditorGUI.indentLevel = 1;

                _tooltip = new GUIContent("Layer", "Choose which layer contains the (3d) colliders that define the boundaries for the camera");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("BoundariesLayerMask"), _tooltip);

                EditorGUI.indentLevel = 0;
            }



            // Numeric boundaries
            _tooltip = new GUIContent("Use Numeric Boundaries", "Should the camera position be constrained by position?");
            EditorGUILayout.PropertyField(serializedObject.FindProperty("UseNumericBoundaries"), _tooltip);

            if (proCamera2D.UseNumericBoundaries)
            {
                EditorGUI.indentLevel = 1;

                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Use Top", "Prevent camera movement beyond this point");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("UseTopBoundary"), _tooltip);

                if (proCamera2D.UseTopBoundary)
                {
                    _tooltip = new GUIContent(" ", "Prevent camera movement beyond this point");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("TopBoundary"), _tooltip);
                }

                if (proCamera2D.UseBottomBoundary && proCamera2D.TopBoundary < proCamera2D.BottomBoundary)
                {
                    proCamera2D.TopBoundary = proCamera2D.BottomBoundary;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Use Bottom", "Prevent camera movement beyond this point");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("UseBottomBoundary"), _tooltip);

                if (proCamera2D.UseBottomBoundary)
                {
                    _tooltip = new GUIContent(" ", "Prevent camera movement beyond this point");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("BottomBoundary"), _tooltip);
                }

                if (proCamera2D.UseTopBoundary && proCamera2D.BottomBoundary > proCamera2D.TopBoundary)
                {
                    proCamera2D.BottomBoundary = proCamera2D.TopBoundary;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Use Left", "Prevent camera movement beyond this point");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("UseLeftBoundary"), _tooltip);

                if (proCamera2D.UseLeftBoundary)
                {
                    _tooltip = new GUIContent(" ", "Prevent camera movement beyond this point");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("LeftBoundary"), _tooltip);
                }

                if (proCamera2D.UseRightBoundary && proCamera2D.LeftBoundary > proCamera2D.RightBoundary)
                {
                    proCamera2D.LeftBoundary = proCamera2D.RightBoundary;
                }

                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                _tooltip = new GUIContent("Use Right", "Prevent camera movement beyond this point");
                EditorGUILayout.PropertyField(serializedObject.FindProperty("UseRightBoundary"), _tooltip);

                if (proCamera2D.UseRightBoundary)
                {
                    _tooltip = new GUIContent(" ", "Prevent camera movement beyond this point");
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("RightBoundary"), _tooltip);
                }

                if (proCamera2D.UseLeftBoundary && proCamera2D.RightBoundary < proCamera2D.LeftBoundary)
                {
                    proCamera2D.RightBoundary = proCamera2D.LeftBoundary;
                }

                EditorGUILayout.EndHorizontal();

                if ((proCamera2D.UseTopBoundary && proCamera2D.UseBottomBoundary && proCamera2D.BottomBoundary == proCamera2D.TopBoundary) ||
                    (proCamera2D.UseLeftBoundary && proCamera2D.UseRightBoundary && proCamera2D.LeftBoundary == proCamera2D.RightBoundary))
                {
                    EditorGUILayout.HelpBox("Same axis boundaries can't have the same value!", MessageType.Error, true);
                }

                EditorGUI.indentLevel = 0;
            }

            AddSpace();



            // Divider
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("PLUGINS", EditorStyles.boldLabel);



            // Pixel perfect plugin
            EditorGUILayout.BeginHorizontal();

            var pixelPerfect = proCamera2D.GetComponent <ProCamera2DPixelPerfect>();

            EditorGUILayout.LabelField("Pixel Perfect");
            if (pixelPerfect == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    pixelPerfect             = proCamera2D.gameObject.AddComponent <ProCamera2DPixelPerfect>();
                    pixelPerfect.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(pixelPerfect);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Forward focus plugin
            EditorGUILayout.BeginHorizontal();

            var forwardFocus = proCamera2D.GetComponent <ProCamera2DForwardFocus>();

            EditorGUILayout.LabelField("Forward Focus");
            if (forwardFocus == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    forwardFocus             = proCamera2D.gameObject.AddComponent <ProCamera2DForwardFocus>();
                    forwardFocus.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(forwardFocus);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Zoom to fit plugin
            EditorGUILayout.BeginHorizontal();

            var zoomToFit = proCamera2D.GetComponent <ProCamera2DZoomToFitTargets>();

            EditorGUILayout.LabelField("Zoom-To-Fit");
            if (zoomToFit == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    zoomToFit             = proCamera2D.gameObject.AddComponent <ProCamera2DZoomToFitTargets>();
                    zoomToFit.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(zoomToFit);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Speed based zoom plugin
            EditorGUILayout.BeginHorizontal();

            var speedBasedZoom = proCamera2D.GetComponent <ProCamera2DSpeedBasedZoom>();

            EditorGUILayout.LabelField("Speed Based Zoom");
            if (speedBasedZoom == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    speedBasedZoom             = proCamera2D.gameObject.AddComponent <ProCamera2DSpeedBasedZoom>();
                    speedBasedZoom.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(speedBasedZoom);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Parallax plugin
            GUI.enabled = proCamera2D.GameCamera.orthographic;

            EditorGUILayout.BeginHorizontal();

            var parallax = proCamera2D.GetComponent <ProCamera2DParallax>();

            EditorGUILayout.LabelField("Parallax");
            if (parallax == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    parallax             = proCamera2D.gameObject.AddComponent <ProCamera2DParallax>();
                    parallax.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(parallax);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();

            GUI.enabled = true;



            // Shake plugin
            EditorGUILayout.BeginHorizontal();

            var shake = proCamera2D.GetComponent <ProCamera2DShake>();

            EditorGUILayout.LabelField("Shake");
            if (shake == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    shake             = proCamera2D.gameObject.AddComponent <ProCamera2DShake>();
                    shake.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(shake);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Mouse influence plugin
            EditorGUILayout.BeginHorizontal();

            var mouseInfluence = proCamera2D.GetComponent <ProCamera2DPointerInfluence>();

            EditorGUILayout.LabelField("Pointer Influence");
            if (mouseInfluence == null)
            {
                GUI.color = Color.green;
                if (GUILayout.Button("Enable"))
                {
                    mouseInfluence             = proCamera2D.gameObject.AddComponent <ProCamera2DPointerInfluence>();
                    mouseInfluence.ProCamera2D = proCamera2D;
                }
            }
            else
            {
                GUI.color = Color.red;
                if (GUILayout.Button("Disable"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to remove this plugin?", "Yes", "No"))
                    {
                        DestroyImmediate(mouseInfluence);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.color = Color.white;
            EditorGUILayout.EndHorizontal();



            // Divider
            EditorGUILayout.Space();
            GUI.color = Color.white;
            GUILayout.Box("", new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
            GUILayout.Label("HELPERS", EditorStyles.boldLabel);



            // Boundaries trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Boundaries Trigger (" + _triggerBoundaries.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerBoundaries");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var boundsTrigger = newGo.AddComponent <ProCamera2DTriggerBoundaries>();
                boundsTrigger.ProCamera2D = proCamera2D;
                _triggerBoundaries.Add(boundsTrigger);
            }

            GUI.enabled = _triggerBoundaries.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerBoundaries[_currentTriggerBoundaries].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerBoundaries[_currentTriggerBoundaries].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerBoundaries = _currentTriggerBoundaries >= _triggerBoundaries.Count - 1 ? 0 : _currentTriggerBoundaries + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Influence trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Influence Trigger (" + _triggerInfluence.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerInfluence");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var influenceTrigger = newGo.AddComponent <ProCamera2DTriggerInfluence>();
                influenceTrigger.ProCamera2D = proCamera2D;
                _triggerInfluence.Add(influenceTrigger);
            }

            GUI.enabled = _triggerInfluence.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerInfluence[_currentTriggerInfluence].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerInfluence[_currentTriggerInfluence].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerInfluence = _currentTriggerInfluence >= _triggerInfluence.Count - 1 ? 0 : _currentTriggerInfluence + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Zoom trigger
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Zoom Trigger (" + _triggerZoom.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DTriggerZoom");
                newGo.transform.localScale = new Vector3(5, 5, 5);
                var zoomTrigger = newGo.AddComponent <ProCamera2DTriggerZoom>();
                zoomTrigger.ProCamera2D = proCamera2D;
                _triggerZoom.Add(zoomTrigger);
            }

            GUI.enabled = _triggerZoom.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _triggerZoom[_currentTriggerZoom].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_triggerZoom[_currentTriggerZoom].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentTriggerZoom = _currentTriggerZoom >= _triggerZoom.Count - 1 ? 0 : _currentTriggerZoom + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            // Cinematic Focus Target
            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("Cinematic Focus Target (" + _cinematicFocusTargets.Count + ")");

            if (GUILayout.Button("Add"))
            {
                var newGo = new GameObject("ProCamera2DCinematicFocusTarget");
                var cinematicFocusTarget = newGo.AddComponent <ProCamera2DCinematicFocusTarget>();
                cinematicFocusTarget.ProCamera2D = proCamera2D;
                _cinematicFocusTargets.Add(cinematicFocusTarget);
            }

            GUI.enabled = _cinematicFocusTargets.Count > 0;

            if (GUILayout.Button(">"))
            {
                Selection.activeGameObject = _cinematicFocusTargets[_currentCinematicFocusTarget].gameObject;
                SceneView.FrameLastActiveSceneView();
                EditorGUIUtility.PingObject(_cinematicFocusTargets[_currentCinematicFocusTarget].gameObject);

                Selection.activeGameObject = proCamera2D.gameObject;

                _currentCinematicFocusTarget = _currentCinematicFocusTarget >= _cinematicFocusTargets.Count - 1 ? 0 : _currentCinematicFocusTarget + 1;
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();



            serializedObject.ApplyModifiedProperties();
        }