public static void OnSceneGUI()
    {
        if(!_cameraPath.showGizmos)
            return;
        if(_cameraPath.transform.rotation != Quaternion.identity)
            return;

        _pointMode = _cameraPath.pointMode;

        if (SceneView.focusedWindow != null)
            SceneView.focusedWindow.wantsMouseMove = false;

        //draw small point indicators
        Handles.color = CameraPathColours.GREY;
        int numberOfCPoints = _cameraPath.fovList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.fovList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
        }
        numberOfCPoints = _cameraPath.delayList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.delayList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
        }
        numberOfCPoints = _cameraPath.orientationList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.orientationList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
        }
        numberOfCPoints = _cameraPath.speedList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.speedList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
        }
        numberOfCPoints = _cameraPath.tiltList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.tiltList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
        }

        //draw path outline
        Camera sceneCamera = Camera.current;
        int numberOfPoints = _cameraPath.numberOfPoints;
        Handles.color = _cameraPath.selectedPathColour;
        float pointPercentage = 1.0f / (numberOfPoints - 1);
        for(int i = 0; i < numberOfPoints-1; i++)
        {
            CameraPathControlPoint pointA = _cameraPath.GetPoint(i);
            CameraPathControlPoint pointB = _cameraPath.GetPoint(i+1);

            float dotPA = Vector3.Dot(sceneCamera.transform.forward, pointA.worldPosition - sceneCamera.transform.position);
            float dotPB = Vector3.Dot(sceneCamera.transform.forward, pointB.worldPosition - sceneCamera.transform.position);

            if (dotPA < 0 && dotPB < 0)//points are both behind camera - don't render
                continue;

            float pointAPercentage = pointPercentage * i;
            float pointBPercentage = pointPercentage * (i + 1);
            float arcPercentage = pointBPercentage - pointAPercentage;
            Vector3 arcCentre = (pointA.worldPosition + pointB.worldPosition) * 0.5f;
            float arcLength = _cameraPath.StoredArcLength(_cameraPath.GetCurveIndex(pointA.index));
            float arcDistance = Vector3.Distance(sceneCamera.transform.position, arcCentre);
            int arcPoints = Mathf.Max(Mathf.RoundToInt(arcLength * (40 / Mathf.Max(arcDistance,20))), 10);
            float arcTime = 1.0f / arcPoints;

            float endLoop = 1.0f - arcTime;
            Vector3 lastPoint = Vector3.zero;
            for (float p = 0; p < endLoop; p += arcTime)
            {
                float p2 = p + arcTime;
                float pathPercentageA = pointAPercentage + arcPercentage * p;
                float pathPercentageB = pointAPercentage + arcPercentage * p2;
                Vector3 lineStart = _cameraPath.GetPathPosition(pathPercentageA, true);
                Vector3 lineEnd = _cameraPath.GetPathPosition(pathPercentageB, true);

                Handles.DrawLine(lineStart, lineEnd);

                lastPoint = lineEnd;
            }
            Handles.DrawLine(lastPoint, _cameraPath.GetPathPosition(pointBPercentage, true));
        }

        switch(_pointMode)
        {
            case CameraPath.PointModes.Transform:
                SceneGUIPointBased();
                break;

            case CameraPath.PointModes.ControlPoints:
                    SceneGUIPointBased();
                break;

            case CameraPath.PointModes.Orientations:
                SceneGUIOrientationBased();
                break;

            case CameraPath.PointModes.FOV:
                SceneGUIFOVBased();
                break;

            case CameraPath.PointModes.Events:
                SceneGUIEventBased();
                break;

            case CameraPath.PointModes.Speed:
                SceneGUISpeedBased();
                break;

            case CameraPath.PointModes.Tilt:
                SceneGUITiltBased();
                break;

            case CameraPath.PointModes.Delay:
                SceneGUIDelayBased();
                break;

            case CameraPath.PointModes.Ease:
                SceneGUIEaseBased();
                break;

            case CameraPath.PointModes.AddPathPoints:
                AddPathPoints();
                break;

            case CameraPath.PointModes.RemovePathPoints:
                RemovePathPoints();
                break;

            case CameraPath.PointModes.AddOrientations:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.AddFovs:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.AddTilts:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.AddEvents:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.AddSpeeds:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.AddDelays:
                AddCPathPoints();
                break;

            case CameraPath.PointModes.RemoveOrientations:
                RemoveCPathPoints();
                break;

            case CameraPath.PointModes.RemoveTilts:
                RemoveCPathPoints();
                break;

            case CameraPath.PointModes.RemoveFovs:
                RemoveCPathPoints();
                break;

            case CameraPath.PointModes.RemoveEvents:
                RemoveCPathPoints();
                break;

            case CameraPath.PointModes.RemoveSpeeds:
                RemoveCPathPoints();
                break;

            case CameraPath.PointModes.RemoveDelays:
                RemoveCPathPoints();
                break;

        }

        
        if (Event.current.type == EventType.ValidateCommand)
        {
            switch (Event.current.commandName)
            {
                case "UndoRedoPerformed":
                    GUI.changed = true;
                    break;
            }
        }
    }
 private static void ChangePointMode(CameraPath.PointModes newPointMode)
 {
     _pointMode = newPointMode;
     EditorGUIUtility.hotControl = 0;
     EditorGUIUtility.keyboardControl = 0;
 }
    public static void OnInspectorGUI()
    {
        _pointMode = _cameraPath.pointMode;

        if(_cameraPath.transform.rotation != Quaternion.identity)
        {
            EditorGUILayout.HelpBox("Camera Path does not support rotations of the main game object.", MessageType.Error);
            if (GUILayout.Button("Reset Rotation"))
                _cameraPath.transform.rotation = Quaternion.identity;
            return;
        }

        GUILayout.BeginVertical(GUILayout.Width(400));

        if (_cameraPath.realNumberOfPoints < 2)
        {
            EditorGUILayout.HelpBox("There are no track points defined, add a path point to begin", MessageType.Warning);
            return;
        }

        EditorGUILayout.LabelField("Path Length approx. " + (_cameraPath.pathLength).ToString("F2") + " units");
        bool trackloop = EditorGUILayout.Toggle("Is Looped", _cameraPath.loop);
        _cameraPath.loop = trackloop;

        EditorGUILayout.HelpBox("Set a Camera Path to trigger once this one has complete.", MessageType.Info);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Link Camera Path", GUILayout.Width(110));
        CameraPath nextPath = (CameraPath)EditorGUILayout.ObjectField(_cameraPath.nextPath, typeof(CameraPath), true);
        if (_cameraPath.nextPath != nextPath)
            _cameraPath.nextPath = nextPath;
        EditorGUI.BeginDisabledGroup(nextPath == null);
        EditorGUILayout.LabelField("Interpolate", GUILayout.Width(70));
        bool interpolateNextPath = EditorGUILayout.Toggle(_cameraPath.interpolateNextPath, GUILayout.Width(30));
        _cameraPath.interpolateNextPath = interpolateNextPath;
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space();
        if (_animator != null && _orientationmode != _animator.orientationMode)
            SetupToolbar();
        ToolbarMenuGUI();

        switch (_pointMode)
        {
            case CameraPath.PointModes.Transform:
                ModifyPointsInspectorGUI();
                break;

            case CameraPath.PointModes.ControlPoints:
                ModifyControlPointsInspector();
                break;

            case CameraPath.PointModes.FOV:
                ModifyFOVInspector();
                break;

            case CameraPath.PointModes.Speed:
                ModifySpeedInspector();
                break;

            case CameraPath.PointModes.Orientations:
                ModifyOrientaionInspector();
                break;

            case CameraPath.PointModes.Tilt:
                ModifyTiltsInspector();
                break;

            case CameraPath.PointModes.Events:
                ModifyEventsInspector();
                break;

            case CameraPath.PointModes.Delay:
                ModifyDelayInspector();
                break;

            case CameraPath.PointModes.Ease:
                ModifyEaseInspector();
                break;

            case CameraPath.PointModes.AddPathPoints:
                ModifyPointsInspectorGUI();
                break;

            case CameraPath.PointModes.RemovePathPoints:
                ModifyPointsInspectorGUI();
                break;

            case CameraPath.PointModes.AddOrientations:
                ModifyOrientaionInspector();
                break;

            case CameraPath.PointModes.AddTilts:
                ModifyTiltsInspector();
                break;

            case CameraPath.PointModes.AddEvents:
                ModifyEventsInspector();
                break;

            case CameraPath.PointModes.AddSpeeds:
                ModifySpeedInspector();
                break;

            case CameraPath.PointModes.AddFovs:
                ModifyFOVInspector();
                break;

            case CameraPath.PointModes.AddDelays:
                ModifyDelayInspector();
                break;

            case CameraPath.PointModes.RemoveOrientations:
                ModifyOrientaionInspector();
                break;

            case CameraPath.PointModes.RemoveTilts:
                ModifyTiltsInspector();
                break;

            case CameraPath.PointModes.RemoveEvents:
                ModifyEventsInspector();
                break;

            case CameraPath.PointModes.RemoveSpeeds:
                ModifySpeedInspector();
                break;

            case CameraPath.PointModes.RemoveFovs:
                ModifyFOVInspector();
                break;

            case CameraPath.PointModes.RemoveDelays:
                ModifyDelayInspector();
                break;

            case CameraPath.PointModes.Options:
                OptionsInspectorGUI();
                break;

        }
        GUILayout.EndVertical();
    }
    public static void OnSceneGUI()
    {
        if (!_cameraPath.showGizmos)
        {
            return;
        }
        if (_cameraPath.transform.rotation != Quaternion.identity)
        {
            return;
        }

        _pointMode = _cameraPath.pointMode;

        if (SceneView.focusedWindow != null)
        {
            SceneView.focusedWindow.wantsMouseMove = false;
        }

        //draw small point indicators
        Handles.color = CameraPathColours.GREY;
        int numberOfCPoints = _cameraPath.fovList.realNumberOfPoints;

        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.fovList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
            {
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
            }
        }
        numberOfCPoints = _cameraPath.delayList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.delayList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
            {
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
            }
        }
        numberOfCPoints = _cameraPath.orientationList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.orientationList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
            {
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
            }
        }
        numberOfCPoints = _cameraPath.speedList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.speedList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
            {
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
            }
        }
        numberOfCPoints = _cameraPath.tiltList.realNumberOfPoints;
        for (int i = 0; i < numberOfCPoints; i++)
        {
            CameraPathPoint point = _cameraPath.tiltList[i];
            if (point.positionModes == CameraPathPoint.PositionModes.Free)
            {
                Handles.DotCap(0, point.worldPosition, Quaternion.identity, 0.2f);
            }
        }

        //draw path outline
        Camera sceneCamera    = Camera.current;
        int    numberOfPoints = _cameraPath.numberOfPoints;

        Handles.color = _cameraPath.selectedPathColour;
        float pointPercentage = 1.0f / (numberOfPoints - 1);

        for (int i = 0; i < numberOfPoints - 1; i++)
        {
            CameraPathControlPoint pointA = _cameraPath.GetPoint(i);
            CameraPathControlPoint pointB = _cameraPath.GetPoint(i + 1);

            float dotPA = Vector3.Dot(sceneCamera.transform.forward, pointA.worldPosition - sceneCamera.transform.position);
            float dotPB = Vector3.Dot(sceneCamera.transform.forward, pointB.worldPosition - sceneCamera.transform.position);

            if (dotPA < 0 && dotPB < 0)//points are both behind camera - don't render
            {
                continue;
            }

            float   pointAPercentage = pointPercentage * i;
            float   pointBPercentage = pointPercentage * (i + 1);
            float   arcPercentage    = pointBPercentage - pointAPercentage;
            Vector3 arcCentre        = (pointA.worldPosition + pointB.worldPosition) * 0.5f;
            float   arcLength        = _cameraPath.StoredArcLength(_cameraPath.GetCurveIndex(pointA.index));
            float   arcDistance      = Vector3.Distance(sceneCamera.transform.position, arcCentre);
            int     arcPoints        = Mathf.Max(Mathf.RoundToInt(arcLength * (40 / Mathf.Max(arcDistance, 20))), 10);
            float   arcTime          = 1.0f / arcPoints;

            float   endLoop   = 1.0f - arcTime;
            Vector3 lastPoint = Vector3.zero;
            for (float p = 0; p < endLoop; p += arcTime)
            {
                float   p2 = p + arcTime;
                float   pathPercentageA = pointAPercentage + arcPercentage * p;
                float   pathPercentageB = pointAPercentage + arcPercentage * p2;
                Vector3 lineStart       = _cameraPath.GetPathPosition(pathPercentageA, true);
                Vector3 lineEnd         = _cameraPath.GetPathPosition(pathPercentageB, true);

                Handles.DrawLine(lineStart, lineEnd);

                lastPoint = lineEnd;
            }
            Handles.DrawLine(lastPoint, _cameraPath.GetPathPosition(pointBPercentage, true));
        }

        switch (_pointMode)
        {
        case CameraPath.PointModes.Transform:
            SceneGUIPointBased();
            break;

        case CameraPath.PointModes.ControlPoints:
            SceneGUIPointBased();
            break;

        case CameraPath.PointModes.Orientations:
            SceneGUIOrientationBased();
            break;

        case CameraPath.PointModes.FOV:
            SceneGUIFOVBased();
            break;

        case CameraPath.PointModes.Events:
            SceneGUIEventBased();
            break;

        case CameraPath.PointModes.Speed:
            SceneGUISpeedBased();
            break;

        case CameraPath.PointModes.Tilt:
            SceneGUITiltBased();
            break;

        case CameraPath.PointModes.Delay:
            SceneGUIDelayBased();
            break;

        case CameraPath.PointModes.Ease:
            SceneGUIEaseBased();
            break;

        case CameraPath.PointModes.AddPathPoints:
            AddPathPoints();
            break;

        case CameraPath.PointModes.RemovePathPoints:
            RemovePathPoints();
            break;

        case CameraPath.PointModes.AddOrientations:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.AddFovs:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.AddTilts:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.AddEvents:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.AddSpeeds:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.AddDelays:
            AddCPathPoints();
            break;

        case CameraPath.PointModes.RemoveOrientations:
            RemoveCPathPoints();
            break;

        case CameraPath.PointModes.RemoveTilts:
            RemoveCPathPoints();
            break;

        case CameraPath.PointModes.RemoveFovs:
            RemoveCPathPoints();
            break;

        case CameraPath.PointModes.RemoveEvents:
            RemoveCPathPoints();
            break;

        case CameraPath.PointModes.RemoveSpeeds:
            RemoveCPathPoints();
            break;

        case CameraPath.PointModes.RemoveDelays:
            RemoveCPathPoints();
            break;
        }


        if (Event.current.type == EventType.ValidateCommand)
        {
            switch (Event.current.commandName)
            {
            case "UndoRedoPerformed":
                GUI.changed = true;
                break;
            }
        }
    }