Example #1
0
        /// <summary>The primary method for drawing a Rail component on the scene view</summary>
        /// <param name="rail">The rail to draw</param>
        /// <param name="handleSize">Handle size</param>
        /// <param name="snapSize">Snap Size</param>
        /// <param name="snapActive">Indicates whether positioning should snap to a grid</param>
        /// <param name="nodeRemovalActive">Indicates whether nodes are able to be removed</param>
        /// <param name="drawEditorHandles">Indicates whether interactive handles should be drawn</param>
        public static void DrawRailOnScene(Rail rail, float handleSize, Vector3 snapSize, bool snapActive = false, bool nodeRemovalActive = false, bool drawEditorHandles = false)
        {
            Handles.color = EditorPreferences.GetColor32(EditorPreferences.RailColorKey, EditorPreferences.RailColorValue);

            var nodes = rail.Nodes;

            // Editor Handles
            if (drawEditorHandles)
            {
                if (nodeRemovalActive && nodes.Count > 2)
                {
                    DrawRailNodeRemoveButtons(rail, handleSize);
                    Handles.color = EditorPreferences.GetColor32(EditorPreferences.RailColorKey, EditorPreferences.RailColorValue);
                }
                else
                {
                    DrawRailNodeInsertButtons(rail, handleSize);
                    DrawRailNodeAddButton(rail, snapActive, handleSize, snapSize.x);
                    DrawRailNodeInsertAtStartButton(rail, snapActive, handleSize, snapSize.x);
                    DrawRailNodeFreeMoveHandles(rail, handleSize, snapSize);
                }
            }


            // Node Index Labels
            Vector2 nodeIndexLabelOffset = new Vector2(-handleSize * 0.2f, handleSize * 1.2f);

            for (int j = 0; j < nodes.Count; j++)
            {
                DrawTextAtPosition(j.ToString(), nodes[j].Position + nodeIndexLabelOffset, Handles.color, false);
            }

            // Rail Name Label
            DrawTextAtPosition(rail.gameObject.name, nodes[0].Position, Handles.color, true);
        }
Example #2
0
        /// <summary>Moves the Scene View to the specified rail</summary>
        /// <param name="rail">The rail to find in Scene</param>
        private void FindInScene(Rail rail)
        {
            if (rail.Nodes.Count > 1 && SceneView.lastActiveSceneView != null)
            {
                float sceneViewHeight   = 0f;
                float sceneViewPadding  = 1.5f;
                float railDisplacementX = Mathf.Abs(rail.Nodes[0].Position.x - rail.Nodes[rail.Nodes.Count - 1].Position.x);
                float railDisplacementY = Mathf.Abs(rail.Nodes[0].Position.y - rail.Nodes[rail.Nodes.Count - 1].Position.y);
                if (railDisplacementX != 0f || railDisplacementY != 0f)
                {
                    if (railDisplacementX / SceneView.lastActiveSceneView.camera.aspect > railDisplacementY)
                    {
                        sceneViewHeight = railDisplacementX / SceneView.lastActiveSceneView.camera.aspect;
                    }
                    else
                    {
                        sceneViewHeight = railDisplacementY;
                    }

                    if (sceneViewHeight != 0)
                    {
                        SceneView.lastActiveSceneView.size = sceneViewHeight * sceneViewPadding;
                    }
                }
                SceneView.lastActiveSceneView.pivot = (rail.Nodes[0].Position + rail.Nodes[rail.Nodes.Count - 1].Position) * 0.5f;
            }
        }
Example #3
0
 /// <summary>Destroys a game object with the specified Rail component attached</summary>
 /// <param name="rail">The Rail component whose game object to destroy</param>
 private void RemoveRail(Rail rail)
 {
     if (EditorUtility.DisplayDialog("Remove Rail?", "Do you really want to remove " + rail.gameObject.name + " from the scene?", "Remove", "Cancel"))
     {
         _currentRailIndex = -1;
         GUIUtilities.RemoveChildObject(rail.gameObject);
     }
 }
Example #4
0
        /// <summary>Adds a rail node to the end of the specified rail</summary>
        /// <param name="rail">The rail to add a node to</param>
        /// <param name="nodePosition">The position of the node to add</param>
        public static void AddRailNode(Rail rail, Vector2 nodePosition)
        {
            Undo.RecordObject(rail, "Add Node");
            var node = new RailNode()
            {
                Position = nodePosition
            };

            rail.Nodes.Add(node);
        }
Example #5
0
        /// <summary>Inserts a rail node on the specified rail</summary>
        /// <param name="rail">The rail to insert a node on</param>
        /// <param name="nodeIndex">The index of the node to insert</param>
        /// <param name="nodePosition">The position of the node to insert</param>
        public static void InsertRailNode(Rail rail, int nodeIndex, Vector2 nodePosition)
        {
            Undo.RecordObject(rail, "Insert Node");
            var nodes = rail.Nodes;
            var node  = new RailNode()
            {
                Position = nodePosition
            };

            nodes.Insert(nodeIndex, node);
        }
Example #6
0
        /// <summary>The primary method that moves the camera. This method is called by the selected Update Method.</summary>
        private void UpdatePosition()
        {
            CheckForScreenSizeChange();

            // Check if on a rail
            _currentRail = GetCurrentRail();

            if (!_staticPosition)
            {
                // Return if no available targets
                if (Target == null && (_currentRail == null || _currentRail.Target == null))
                {
                    return;
                }

                // Get intended position without offset
                _intendedPositionWithoutOffset = GetIntendedPositionWithoutOffset();

                // Get intended position with offset
                if (OffsetX != 0f || OffsetY != 0f)
                {
                    _intendedPosition = GetIntendedPosition();
                }
                else
                {
                    _intendedPosition = _intendedPositionWithoutOffset;
                }
            }

            // Smooth
            if (!_resetSmoothing && (SmoothX > 0f || SmoothY > 0f))
            {
                _smoothedPosition = GetSmoothedPosition();
            }
            else
            {
                _smoothedPosition = _intendedPosition;
                if (_resetSmoothing)
                {
                    _resetSmoothing = false;
                }
            }

            // Correct the Smoothed Position with Bounds
            if (BoundX > 0f || BoundY > 0f)
            {
                _smoothedPosition = GetBoundPosition();
            }

            // Set camera position
            SetPosition(_smoothedPosition);
        }
Example #7
0
        /// <summary>Draws buttons used for inserting nodes on the rail</summary>
        /// <param name="rail">The rail to insert nodes on</param>
        /// <param name="handleSize">Handle size</param>
        public static void DrawRailNodeInsertButtons(Rail rail, float handleSize)
        {
            var buttonSize = 0.25f * handleSize;
            var nodes      = rail.Nodes;

            for (int i = 1; i < nodes.Count; i++)
            {
                var buttonPosition = (nodes[i].Position + nodes[i - 1].Position) * 0.5f;
                if (Handles.Button(buttonPosition, Quaternion.identity, buttonSize, buttonSize, Handles.RectangleHandleCap))
                {
                    InsertRailNode(rail, i, buttonPosition);
                }
            }
        }
Example #8
0
        /// <summary>Draws buttons that remove nodes from the specified Rail</summary>
        /// <param name="rail">The rail to draw handles for</param>
        /// <param name="handleSize">Handle size</param>
        public static void DrawRailNodeRemoveButtons(Rail rail, float handleSize)
        {
            Handles.color = Color.red;
            var buttonSize = 0.5f * handleSize;
            var nodes      = rail.Nodes;

            for (int i = 0; i < rail.Nodes.Count; i++)
            {
                if (Handles.Button(nodes[i].Position, Quaternion.identity, buttonSize, buttonSize, Handles.DotHandleCap))
                {
                    RemoveRailNode(rail, i);
                    return;
                }
            }
        }
Example #9
0
        /// <summary>Draws Free Move Handles for the specified rail</summary>
        /// <param name="rail">The rail to draw handles for</param>
        /// <param name="handleSize">Handle size</param>
        /// <param name="snapSize">Snap size</param>
        public static void DrawRailNodeFreeMoveHandles(Rail rail, float handleSize, Vector3 snapSize)
        {
            var moveHandleSize = 0.5f * handleSize;
            var nodes          = rail.Nodes;

            for (int i = 0; i < nodes.Count; i++)
            {
                Vector2 newNodePosition = Handles.FreeMoveHandle(nodes[i].Position, Quaternion.identity, moveHandleSize, snapSize, Handles.RectangleHandleCap);
                if (nodes[i].Position != newNodePosition)
                {
                    Undo.RecordObject(rail, "Move Node");
                    nodes[i].Position = newNodePosition;
                }
            }
        }
Example #10
0
        /// <summary>Sets the currently displayed rail and text in the main editor</summary>
        /// <param name="railManager">The RailManager component selected in the Inspector</param>
        private void InitializeMainEditor(RailManager railManager)
        {
            // Default values
            var  heading     = "NO RAILS FOUND";
            Rail currentRail = null;

            // If a rail is supposed to be displayed
            if (_currentRailIndex != -1 && _rails[_currentRailIndex] != null)
            {
                currentRail = _rails[_currentRailIndex];
                heading     = currentRail.gameObject.name.ToUpper();
            }

            // If no rail is displayed, but rails are available
            else if (_rails.Count > 0)
            {
                heading = "SELECT RAIL TO EDIT";
            }

            DrawMainEditor(currentRail, heading);
        }
Example #11
0
        /// <summary>Draws a button used for inserting a node at the start of the rail</summary>
        /// <param name="rail">The rail to insert a node at the start of</param>
        /// <param name="snapActive">Indicates whether positioning should snap to a grid</param>
        /// <param name="handleSize">Handle size</param>
        public static void DrawRailNodeInsertAtStartButton(Rail rail, bool snapActive, float handleSize, float snapSize)
        {
            var buttonSize = 0.25f * handleSize;

            var buttonOffsetVector = handleSize * 1.5f;

            if (snapActive)
            {
                buttonOffsetVector = Mathf.Round(buttonOffsetVector / snapSize) * snapSize;
                if (buttonOffsetVector < snapSize)
                {
                    buttonOffsetVector = snapSize;
                }
            }

            var buttonPosition = rail.Nodes[0].Position - new Vector2(buttonOffsetVector, buttonOffsetVector);

            if (Handles.Button(buttonPosition, Quaternion.identity, buttonSize, buttonSize, Handles.RectangleHandleCap))
            {
                InsertRailNode(rail, 0, buttonPosition);
            }
        }
Example #12
0
        /// <summary>Creates Buttons for organising a rail's nodes</summary>
        /// <param name="rail">The rail whose nodes are being edited</param>
        /// <param name="i">Index of the node to be edited</param>
        private void NodeEditorButtons(Rail rail, int i)
        {
            var nodes = rail.Nodes;

            // Shift Up
            _content = new GUIContent("\u25b2", "Shift up");
            if (GUILayout.Button(_content, EditorStyles.miniButtonLeft, GUILayout.Width(20f)))
            {
                if (i > 0)
                {
                    Undo.RecordObject(rail, "Shift Node Up");
                    var node = nodes[i];
                    nodes.RemoveAt(i);
                    nodes.Insert(i - 1, node);
                    _repaintScene = true;
                }
            }

            // Shift Down
            _content = new GUIContent("\u25bc", "Shift down");
            if (GUILayout.Button(_content, EditorStyles.miniButtonMid, GUILayout.Width(20f)))
            {
                if (i < nodes.Count - 1)
                {
                    Undo.RecordObject(rail, "Shift Node Down");
                    var node = nodes[i];
                    nodes.RemoveAt(i);
                    nodes.Insert(i + 1, node);
                    _repaintScene = true;
                }
            }

            // Insert
            _content = new GUIContent("\u002b", "Insert");
            if (GUILayout.Button(_content, EditorStyles.miniButtonMid, GUILayout.Width(20f)))
            {
                Vector2 newNodePos;
                if (i == 0)
                {
                    newNodePos = nodes[i].Position - new Vector2(2f, 2f);
                }
                else
                {
                    newNodePos = (nodes[i].Position + nodes[i - 1].Position) * 0.5f;
                }

                GUIUtilities.InsertRailNode(rail, i, newNodePos);
                _repaintScene = true;
            }

            // Remove
            _content = new GUIContent("\u2212", "Remove");
            if (GUILayout.Button(_content, EditorStyles.miniButtonRight, GUILayout.Width(20f)))
            {
                if (nodes.Count > 2)
                {
                    GUIUtilities.RemoveRailNode(rail, i);
                    _repaintScene = true;
                }
            }
        }
Example #13
0
        /// <summary>Displays a list of nodes for the current rail</summary>
        /// <param name="rail">The Rail component whose nodes to display</param>
        private void ListRailNodes(Rail rail)
        {
            List <RailNode> nodes = rail.Nodes;

            // Column Labels
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Node #", GUILayout.Width(60f));
            EditorGUILayout.LabelField("Position", GUILayout.MinWidth(105f));
            _content = new GUIContent("FX: Threshold", "Increased velocity transition effect\n\u2611 to invert");
            EditorGUILayout.LabelField(_content, GUILayout.MinWidth(156f), GUILayout.MaxWidth(156f));
            EditorGUILayout.EndHorizontal();

            for (int i = 0; i < nodes.Count; i++)
            {
                var node = nodes[i];
                EditorGUILayout.BeginHorizontal();

                // Row Label
                EditorGUILayout.LabelField("Node " + i.ToString(), GUILayout.Width(60f));

                // Position
                var newPosition = EditorGUILayout.Vector2Field(GUIContent.none, node.Position, GUILayout.MinWidth(105f));
                if (node.Position != newPosition)
                {
                    Undo.RecordObject(rail, "Move Node");
                    node.Position = newPosition;
                }

                // Disables editing of the final node's Threshold FX as the value produces no effect
                if (i == nodes.Count - 1)
                {
                    GUI.enabled = false;
                }

                var newInvertThreshold = EditorGUILayout.Toggle(GUIContent.none, node.InvertThreshold, GUILayout.Width(12f));
                if (node.InvertThreshold != newInvertThreshold)
                {
                    Undo.RecordObject(rail, "Invert Node Threshold");
                    node.InvertThreshold = newInvertThreshold;
                }

                var newThreshold = EditorGUILayout.Slider(GUIContent.none, node.Threshold, 0f, 1f, GUILayout.Width(50f));
                if (node.Threshold != newThreshold)
                {
                    Undo.RecordObject(rail, "Change Node Threshold");
                    node.Threshold = newThreshold;
                }

                if (i == nodes.Count - 1)
                {
                    GUI.enabled = true;
                }

                // Buttons for shifting, inserting, and removing nodes
                NodeEditorButtons(rail, i);
                EditorGUILayout.EndHorizontal();
            }

            // Button to add node
            _content = new GUIContent("\u002b", "Add node");
            if (GUILayout.Button(_content))
            {
                Vector2 newNodePos;
                if (nodes.Count > 0)
                {
                    newNodePos = nodes[nodes.Count - 1].Position + new Vector2(2f, 2f);
                }
                else
                {
                    newNodePos = GUIUtilities.GetRoundedScenePivot();
                }

                GUIUtilities.AddRailNode(rail, newNodePos);
                _repaintScene = true;
            }
        }
Example #14
0
        /// <summary>Draws the main editor used for editing rail values</summary>
        /// <param name="rail">The Rail component whose values to display</param>
        /// <param name="heading">The string to display in the EditorHeader</param>
        private void DrawMainEditor(Rail rail, string heading)
        {
            // Default values used when rail == null.
            Color           currentColor       = Color.grey;
            Transform       currentTarget      = null;
            RailOrientation currentOrientation = RailOrientation.Horizontal;
            float           currentLeadIn      = 0f;
            float           currentTrailOut    = 0f;

            if (rail != null)
            {
                currentTarget      = rail.Target;
                currentOrientation = rail.Orientation;
                currentLeadIn      = rail.LeadIn;
                currentTrailOut    = rail.TrailOut;
            }
            else
            {
                GUI.enabled = false;
            }

            // Header - displays name of rail being edited
            GUIUtilities.EditorHeader(heading);

            EditorGUILayout.Space();

            // Target
            _content = new GUIContent("Target", "The target the camera follows while on the rail. If null, the Railcam 2D target is used by default");
            var newTarget = EditorGUILayout.ObjectField(_content, currentTarget, typeof(Transform), true);

            if (rail != null)
            {
                if (rail.Target != (Transform)newTarget)
                {
                    Undo.RecordObject(rail, "Change Rail Target");
                    rail.Target = (Transform)newTarget;
                }
            }

            EditorGUILayout.Space();

            // Orientation
            _content = new GUIContent("Orientation", "The axis used to calculate camera position while on the rail");
            var newOrientation = EditorGUILayout.EnumPopup(_content, currentOrientation);

            if (rail != null)
            {
                if (rail.Orientation != (RailOrientation)newOrientation)
                {
                    Undo.RecordObject(rail, "Change Rail Orientation");
                    rail.Orientation = (RailOrientation)newOrientation;
                }
            }

            EditorGUILayout.Space();

            // Lead-In
            _content = new GUIContent("FX: Lead-In", "The camera leads with reduced velocity between the first two nodes");
            var newLeadIn = EditorGUILayout.Slider(_content, currentLeadIn, 0f, 1f);

            if (rail != null)
            {
                if (rail.LeadIn != newLeadIn)
                {
                    Undo.RecordObject(rail, "Change Rail Lead-In");
                    rail.LeadIn   = newLeadIn;
                    _repaintScene = true;
                }
            }

            // Trail-Out
            _content = new GUIContent("FX: Trail-Out", "The camera trails with reduced velocity between the final two nodes");
            var newTrailOut = EditorGUILayout.Slider(_content, currentTrailOut, 0f, 1f);

            if (rail != null)
            {
                if (rail.TrailOut != newTrailOut)
                {
                    Undo.RecordObject(rail, "Change Rail Trail-Out");
                    rail.TrailOut = newTrailOut;
                    _repaintScene = true;
                }
            }

            EditorGUILayout.Space();

            // Rail Nodes
            if (rail != null)
            {
                ListRailNodes(rail);
            }
        }
Example #15
0
 /// <summary>Removes a rail node from the specified rail</summary>
 /// <param name="rail">The rail to remove the node from</param>
 /// <param name="nodeIndex">The index of the node to remove</param>
 public static void RemoveRailNode(Rail rail, int nodeIndex)
 {
     Undo.RecordObject(rail, "Remove Node");
     rail.Nodes.RemoveAt(nodeIndex);
 }