Пример #1
0
        //if this path is selected, display small info boxes above all waypoint positions
        //also display handles for the waypoints
        void OnSceneGUI()
        {
            //again, get waypoint array
            var waypoints = GetWaypointArray();

            //do not execute further code if we have no waypoints defined
            //(just to make sure, practically this can not occur)
            if (waypoints.Length == 0)
            {
                return;
            }
            Vector3 wpPos = Vector3.zero;
            float   size  = 1f;

            //loop through waypoint array
            for (int i = 0; i < waypoints.Length; i++)
            {
                if (!waypoints[i])
                {
                    continue;
                }
                wpPos = waypoints[i].position;
                size  = HandleUtility.GetHandleSize(wpPos) * 0.4f;

                //do not draw waypoint header if too far away
                if (size < 3f)
                {
                    //begin 2D GUI block
                    Handles.BeginGUI();
                    //translate waypoint vector3 position in world space into a position on the screen
                    var guiPoint = HandleUtility.WorldToGUIPoint(wpPos);
                    //create rectangle with that positions and do some offset
                    var rect = new Rect(guiPoint.x - 50.0f, guiPoint.y - 40, 100, 20);
                    //draw box at position with current waypoint name
                    GUI.Box(rect, waypoints[i].name);
                    Handles.EndGUI(); //end GUI block
                }

                //draw handles per waypoint, clamp size
                Handles.color = m_Color2.colorValue;
                size          = Mathf.Clamp(size, 0, 1.2f);
                Vector3 newPos = Handles.FreeMoveHandle(wpPos, Quaternion.identity,
                                                        size, Vector3.zero, Handles.SphereCap);
                Handles.RadiusHandle(Quaternion.identity, wpPos, size / 2);

                if (wpPos != newPos)
                {
                    Undo.RecordObject(waypoints[i], "Move Handles");
                    waypoints[i].position = newPos;
                }
            }

            //waypoint direction handles drawing
            if (!m_Check2.boolValue)
            {
                return;
            }
            Vector3[] pathPoints = new Vector3[waypoints.Length];
            for (int i = 0; i < pathPoints.Length; i++)
            {
                pathPoints[i] = waypoints[i].position;
            }

            //create list of path segments (list of Vector3 list)
            List <List <Vector3> > segments = new List <List <Vector3> >();
            int   curIndex = 0;
            float lerpVal  = 0f;

            //differ between linear and curved display
            switch (m_Check1.boolValue)
            {
            case true:
                //convert waypoints to curved path points
                pathPoints = WaypointManager.GetCurved(pathPoints);
                for (int i = 0; i < waypoints.Length - 1; i++)
                {
                    //loop over path points to find single segments
                    segments.Add(new List <Vector3>());
                    for (int j = curIndex; j < pathPoints.Length; j++)
                    {
                        //the segment ends here, continue with new segment
                        if (pathPoints[j] == waypoints[i + 1].position)
                        {
                            curIndex = j;
                            break;
                        }

                        //add path point to current segment
                        segments[i].Add(pathPoints[j]);
                    }
                }
                break;

            case false:
                //detail for arrows between waypoints
                int lerpMax = 16;
                //loop over waypoints to add intermediary points
                for (int i = 0; i < waypoints.Length - 1; i++)
                {
                    segments.Add(new List <Vector3>());
                    for (int j = 0; j < lerpMax; j++)
                    {
                        //linear lerp between waypoints to get additional points for drawing arrows at
                        segments[i].Add(Vector3.Lerp(pathPoints[i], pathPoints[i + 1], j / (float)lerpMax));
                    }
                }
                break;
            }

            //loop over segments
            for (int i = 0; i < segments.Count; i++)
            {
                //loop over single positions on the segment
                for (int j = 0; j < segments[i].Count; j++)
                {
                    //get current lerp value for interpolating rotation
                    //draw arrow handle on current position with interpolated rotation
                    size    = Mathf.Clamp(HandleUtility.GetHandleSize(segments[i][j]) * 0.4f, 0, 1.2f);
                    lerpVal = j / (float)segments[i].Count;
                    Handles.ArrowCap(0, segments[i][j], Quaternion.Lerp(waypoints[i].rotation, waypoints[i + 1].rotation, lerpVal) * Quaternion.Euler(0, 90, 0), size);
                }
            }
        }
Пример #2
0
        //if this path is selected, display small info boxes above all waypoint positions
        //also display handles for the waypoints
        void OnSceneGUI()
        {
            //again, get waypoint array
            var waypoints = GetWaypointArray();

            //do not execute further code if we have no waypoints defined
            //(just to make sure, practically this can not occur)
            if (waypoints.Length == 0)
            {
                return;
            }
            Vector3 wpPos = Vector3.zero;
            float   size  = 1f;

            //loop through waypoint array
            for (int i = 0; i < waypoints.Length; i++)
            {
                if (!waypoints[i])
                {
                    continue;
                }
                wpPos = waypoints[i].position;

                size = HandleUtility.GetHandleSize(wpPos) * 0.4f;

                //do not draw waypoint header if too far away
                if (size < 3f)
                {
                    //begin 2D GUI block
                    Handles.BeginGUI();
                    //translate waypoint vector3 position in world space into a position on the screen
                    var guiPoint = HandleUtility.WorldToGUIPoint(wpPos);
                    //create rectangle with that positions and do some offset
                    var rect = new Rect(guiPoint.x - 50.0f, guiPoint.y - 40, 100, 20);
                    //draw box at position with current waypoint name
                    GUI.Box(rect, waypoints[i].name);
                    Handles.EndGUI(); //end GUI block
                }

                //draw handles per waypoint, clamp size
                Handles.color = m_Color2.colorValue;
                size          = Mathf.Clamp(size, 0, 1.2f);

                Handles.FreeMoveHandle(wpPos, Quaternion.identity, size, Vector3.zero, (controlID, position, rotation, hSize, eventType) =>
                {
                    Handles.SphereHandleCap(controlID, position, rotation, hSize, eventType);
                    if (controlID == GUIUtility.hotControl && GUIUtility.hotControl != 0)
                    {
                        activeNode = i;
                    }
                });
                Handles.RadiusHandle(waypoints[i].rotation, wpPos, size / 2);
            }

            if (activeNode > -1)
            {
                wpPos = waypoints[activeNode].position;
                Quaternion wpRot = waypoints[activeNode].rotation;
                switch (Tools.current)
                {
                case Tool.Move:
                    if (Tools.pivotRotation == PivotRotation.Global)
                    {
                        wpRot = Quaternion.identity;
                    }

                    Vector3 newPos = Handles.PositionHandle(wpPos, wpRot);
                    if (wpPos != newPos)
                    {
                        Undo.RecordObject(waypoints[activeNode], "Move Handle");
                        waypoints[activeNode].position = newPos;
                    }
                    break;

                case Tool.Rotate:
                    Quaternion newRot = Handles.RotationHandle(wpRot, wpPos);

                    if (wpRot != newRot)
                    {
                        Undo.RecordObject(waypoints[activeNode], "Rotate Handle");
                        waypoints[activeNode].rotation = newRot;
                    }
                    break;
                }
            }

            //waypoint direction handles drawing
            if (!m_Check2.boolValue)
            {
                return;
            }
            Vector3[] pathPoints = new Vector3[waypoints.Length];
            for (int i = 0; i < pathPoints.Length; i++)
            {
                pathPoints[i] = waypoints[i].position;
            }

            //create list of path segments (list of Vector3 list)
            List <List <Vector3> > segments = new List <List <Vector3> >();
            int   curIndex = 0;
            float lerpVal  = 0f;

            //differ between linear and curved display
            switch (m_Check1.boolValue)
            {
            case true:
                //convert waypoints to curved path points
                pathPoints = WaypointManager.GetCurved(pathPoints);
                //calculate approximate path point amount per segment
                int detail = Mathf.FloorToInt((pathPoints.Length - 1f) / (waypoints.Length - 1f));

                for (int i = 0; i < waypoints.Length - 1; i++)
                {
                    float dist = Mathf.Infinity;
                    //loop over path points to find single segments
                    segments.Add(new List <Vector3>());

                    //we are not checking for absolute path points on standard paths, because
                    //path points could also be located before or after waypoint positions.
                    //instead a minimum distance is searched which marks the nearest path point
                    for (int j = curIndex; j < pathPoints.Length; j++)
                    {
                        //add path point to current segment
                        segments[i].Add(pathPoints[j]);

                        //start looking for distance after a certain amount of path points of this segment
                        if (j >= (i + 1) * detail)
                        {
                            //calculate distance of current path point to waypoint
                            float pointDist = Vector3.Distance(waypoints[i].position, pathPoints[j]);
                            //we are getting closer to the waypoint
                            if (pointDist < dist)
                            {
                                dist = pointDist;
                            }
                            else
                            {
                                //current path point is more far away than the last one
                                //the segment ends here, continue with new segment
                                curIndex = j + 1;
                                break;
                            }
                        }
                    }
                }
                break;

            case false:
                //detail for arrows between waypoints
                int lerpMax = 16;
                //loop over waypoints to add intermediary points
                for (int i = 0; i < waypoints.Length - 1; i++)
                {
                    segments.Add(new List <Vector3>());
                    for (int j = 0; j < lerpMax; j++)
                    {
                        //linear lerp between waypoints to get additional points for drawing arrows at
                        segments[i].Add(Vector3.Lerp(pathPoints[i], pathPoints[i + 1], j / (float)lerpMax));
                    }
                }
                break;
            }

            //loop over segments
            for (int i = 0; i < segments.Count; i++)
            {
                //loop over single positions on the segment
                for (int j = 0; j < segments[i].Count; j++)
                {
                    //get current lerp value for interpolating rotation
                    //draw arrow handle on current position with interpolated rotation
                    size    = Mathf.Clamp(HandleUtility.GetHandleSize(segments[i][j]) * 0.4f, 0, 1.2f);
                    lerpVal = j / (float)segments[i].Count;
                    Handles.ArrowHandleCap(0, segments[i][j], Quaternion.Lerp(waypoints[i].rotation, waypoints[i + 1].rotation, lerpVal), size, EventType.Repaint);
                }
            }
        }