public Vector3 GetPathDirection()
    {
        float   thisperc = bezier.GetPathPercentageAtPoint(this);
        float   lastperc = Mathf.Clamp01(thisperc - 0.05f);
        float   nextperc = Mathf.Clamp01(thisperc + 0.05f);
        Vector3 lastPos  = bezier.GetPathPosition(lastperc);
        Vector3 nextPos  = bezier.GetPathPosition(nextperc);

        return(nextPos - lastPos);
    }
    public void SetRotationToCurve()
    {
        float   thisperc = bezier.GetPathPercentageAtPoint(this);
        float   lastperc = Mathf.Clamp01(thisperc - 0.05f);
        float   nextperc = Mathf.Clamp01(thisperc + 0.05f);
        Vector3 lastPos  = bezier.GetPathPosition(lastperc);
        Vector3 nextPos  = bezier.GetPathPosition(nextperc);
        Vector3 dir      = nextPos - lastPos;

        transform.LookAt(transform.position + dir);
    }
Пример #3
0
    void OnDrawGizmos()
    {
        if (bezier == null)
        {
            return;
        }

        if (Application.isPlaying)
        {
            return;
        }

        if (bezier.numberOfControlPoints == 0)
        {
            return;
        }

        Vector3 debugPosition = bezier.GetPathPosition(Mathf.Clamp01(RecalculatePercentage(editorTime)));

        Gizmos.color = new Color(1.0f, 0.0f, 1.0f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.up * 0.5f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.down * 0.5f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.left * 0.5f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.right * 0.5f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.forward * 0.5f);
        Gizmos.DrawLine(debugPosition, debugPosition + Vector3.back * 0.5f);
    }
    //PRIVATE METHODS

    void UpdateAnimation()
    {
        if (animationTarget == null)
        {
            Debug.LogError("There is no aniamtion target specified in the Camera Path Bezier Animator component. Nothing to animate.\nYou can find this component in the main camera path component.");
            Stop();
            return;
        }

        if (!playing)
        {
            return;
        }

        animationTarget.position = bezier.GetPathPosition(usePercentage);
        if (isCamera)
        {
            animationTarget.GetComponent <Camera>().fov = bezier.GetPathFOV(usePercentage);
        }

        Vector3 minusPoint, plusPoint;

        switch (bezier.mode)
        {
        case CameraPathBezier.viewmodes.usercontrolled:
            animationTarget.rotation = bezier.GetPathRotation(usePercentage);
            break;

        case CameraPathBezier.viewmodes.target:

            animationTarget.LookAt(bezier.target.transform.position);
            break;

        case CameraPathBezier.viewmodes.followpath:
            if (!bezier.loop)
            {
                minusPoint = bezier.GetPathPosition(Mathf.Clamp01(usePercentage - 0.05f));
                plusPoint  = bezier.GetPathPosition(Mathf.Clamp01(usePercentage + 0.05f));
            }
            else
            {
                float minus = usePercentage - 0.05f;
                if (minus < 0)
                {
                    minus += 1;
                }
                float plus = usePercentage + 0.05f;
                if (plus > 1)
                {
                    plus += -1;
                }
                minusPoint = bezier.GetPathPosition(minus);
                plusPoint  = bezier.GetPathPosition(plus);
            }

            animationTarget.LookAt(animationTarget.position + (plusPoint - minusPoint));
            animationTarget.eulerAngles += transform.forward * -bezier.GetPathTilt(usePercentage);
            break;

        case CameraPathBezier.viewmodes.reverseFollowpath:
            if (!bezier.loop)
            {
                minusPoint = bezier.GetPathPosition(Mathf.Clamp01(usePercentage - 0.05f));
                plusPoint  = bezier.GetPathPosition(Mathf.Clamp01(usePercentage + 0.05f));
            }
            else
            {
                float minus = usePercentage - 0.05f;
                if (minus < 0)
                {
                    minus += 1;
                }
                float plus = usePercentage + 0.05f;
                if (plus > 1)
                {
                    plus += -1;
                }
                minusPoint = bezier.GetPathPosition(minus);
                plusPoint  = bezier.GetPathPosition(plus);
            }

            animationTarget.LookAt(animationTarget.position + (minusPoint - plusPoint));
            break;

        case CameraPathBezier.viewmodes.mouselook:

            animationTarget.rotation = GetMouseLook();
            break;
        }
    }
    public override void OnInspectorGUI()
    {
        Camera[] cams           = Camera.allCameras;
        bool     sceneHasCamera = cams.Length > 0;

        if (Camera.main)
        {
            sceneCamera = Camera.main;
        }
        else if (sceneHasCamera)
        {
            sceneCamera = cams[0];
        }

        if (sceneCamera != null)
        {
            if (sceneCameraSkybox == null)
            {
                sceneCameraSkybox = sceneCamera.GetComponent <Skybox>();
            }
        }

        if (pointPreviewTexture == null)
        {
            pointPreviewTexture = new RenderTexture(400, Mathf.RoundToInt(400 / aspect), 24);
        }

        if (animator.animationTarget == null)
        {
            EditorGUILayout.HelpBox("No animation target has been specified so there is nothing to animate. Select an animation target in the Camera Path Bezier Animator Component in the parent clip", MessageType.Warning);
        }
        else
        {
            if ((EditorGUIUtility.isProSkin) && bezier.numberOfCurves > 0 && pointPreviewTexture != null)
            {
                bool cameraPathPreview = EditorPrefs.GetBool("CameraPathPreview");
                GUILayout.Space(7);
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Animation Preview");
                if (cameraPathPreview)
                {
                    if (GUILayout.Button("Hide", GUILayout.Width(50)))
                    {
                        EditorPrefs.SetBool("CameraPathPreview", false);
                    }
                }
                else
                {
                    if (GUILayout.Button("Show", GUILayout.Width(50)))
                    {
                        EditorPrefs.SetBool("CameraPathPreview", true);
                    }
                }
                EditorGUILayout.Space();
                EditorGUILayout.EndHorizontal();

                if (!Application.isPlaying && cameraPathPreview)
                {
                    float usePercentage = animator.normalised? animator.RecalculatePercentage(animator.editorTime): animator.editorTime;

                    //Get animation values and apply them to the preview camera
                    previewCamPos = bezier.GetPathPosition(usePercentage);
                    previewCamRot = Quaternion.identity;
                    previewCamFOV = bezier.GetPathFOV(usePercentage);

                    //Assign rotation to preview camera
                    Vector3 plusPoint, minusPoint;
                    switch (bezier.mode)
                    {
                    case CameraPathBezier.viewmodes.usercontrolled:
                        previewCamRot = bezier.GetPathRotation(usePercentage);
                        break;

                    case CameraPathBezier.viewmodes.target:

                        if (bezier.target != null)
                        {
                            previewCamRot = Quaternion.LookRotation(bezier.target.transform.position - previewCamPos);
                        }
                        else
                        {
                            EditorGUILayout.HelpBox("No target has been specified in the bezier path", MessageType.Warning);
                            previewCamRot = Quaternion.identity;
                        }
                        break;

                    case CameraPathBezier.viewmodes.followpath:

                        minusPoint    = bezier.GetPathPosition(Mathf.Clamp01(usePercentage - 0.05f));
                        plusPoint     = bezier.GetPathPosition(Mathf.Clamp01(usePercentage + 0.05f));
                        previewCamRot = Quaternion.LookRotation(plusPoint - minusPoint);
                        break;

                    case CameraPathBezier.viewmodes.reverseFollowpath:

                        minusPoint    = bezier.GetPathPosition(Mathf.Clamp01(usePercentage - 0.05f));
                        plusPoint     = bezier.GetPathPosition(Mathf.Clamp01(usePercentage + 0.05f));
                        previewCamRot = Quaternion.LookRotation(minusPoint - plusPoint);
                        break;

                    case CameraPathBezier.viewmodes.mouselook:

                        Vector3 minusPointb = bezier.GetPathPosition(Mathf.Clamp01(usePercentage - 0.05f));
                        Vector3 plusPointb  = bezier.GetPathPosition(Mathf.Clamp01(usePercentage + 0.05f));
                        previewCamRot = Quaternion.LookRotation(plusPointb - minusPointb);
                        break;
                    }

                    //Render the camera preview
                    GameObject cam = new GameObject("Point Preview");
                    cam.transform.parent = bezier.transform;
                    cam.AddComponent <Camera>();
                    //Retreive camera settings from the main camera
                    if (sceneCamera != null)
                    {
                        cam.GetComponent <Camera>().backgroundColor = sceneCamera.backgroundColor;
                        if (sceneCameraSkybox != null)
                        {
                            cam.AddComponent <Skybox>().material = sceneCameraSkybox.material;
                        }
                        else
                        if (RenderSettings.skybox != null)
                        {
                            cam.AddComponent <Skybox>().material = RenderSettings.skybox;
                        }
                    }
                    cam.transform.position = previewCamPos;
                    cam.transform.rotation = previewCamRot;
                    cam.GetComponent <Camera>().fieldOfView   = previewCamFOV;
                    cam.GetComponent <Camera>().targetTexture = pointPreviewTexture;
                    cam.GetComponent <Camera>().Render();
                    cam.GetComponent <Camera>().targetTexture = null;
                    DestroyImmediate(cam);

                    //Display the camera preview

                    Rect previewRect = new Rect(0, 0, Screen.width, Screen.width / aspect);
                    Rect layoutRect  = EditorGUILayout.BeginVertical();
                    previewRect.x = layoutRect.x;
                    previewRect.y = layoutRect.y + 5;
                    EditorGUI.DrawPreviewTexture(previewRect, pointPreviewTexture);
                    GUILayout.Space(previewRect.height + 10);
                    pointPreviewTexture.Release();

                    EditorGUILayout.BeginHorizontal();
                    float time = EditorGUILayout.Slider(animator.editorTime * animator.pathTime, 0, animator.pathTime);
                    animator.editorTime = time / animator.pathTime;
                    EditorGUILayout.LabelField("sec", GUILayout.Width(25));
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();
                }
            }
        }

        animator.showScenePreview = EditorGUILayout.Toggle("Show Scene Preview Info", animator.showScenePreview);

        animator.playOnStart = EditorGUILayout.Toggle("Play on start", animator.playOnStart);

        EditorGUILayout.BeginHorizontal();
        animator.pathTime = EditorGUILayout.FloatField("Animation Time", animator.pathTime);
        EditorGUILayout.LabelField("sec", GUILayout.Width(25));
        EditorGUILayout.EndHorizontal();

        bool noPath = bezier.numberOfControlPoints < 2;

        EditorGUI.BeginDisabledGroup(noPath);
        EditorGUILayout.BeginHorizontal();
        float newPathSpeed = EditorGUILayout.FloatField("Animation Speed", animator.pathSpeed);

        if (!noPath)
        {
            animator.pathSpeed = newPathSpeed;
        }
        EditorGUILayout.LabelField("m/sec", GUILayout.Width(25));
        EditorGUILayout.EndHorizontal();
        EditorGUI.EndDisabledGroup();

        animator.pathTime = Mathf.Max(animator.pathTime, 0.001f);       //ensure it's a real number

        animator.animationTarget = (Transform)EditorGUILayout.ObjectField("Animate Object", animator.animationTarget, typeof(Transform), true);
        EditorGUILayout.HelpBox("This toggle can be used to specify what kind of object you are animating. If it isn't a camera, we recommend you uncheck this box", MessageType.Info);
        animator.isCamera = EditorGUILayout.Toggle("Is Camera", animator.isCamera);

        animator.mode = (CameraPathBezierAnimator.modes)EditorGUILayout.EnumPopup("Animation Mode", animator.mode);

        animator.normalised = EditorGUILayout.Toggle("Normalised Path", animator.normalised);

        EditorGUILayout.HelpBox("Set this if you want to start another camera path animation once this has completed", MessageType.Info);
        animator.nextAnimation = (CameraPathBezierAnimator)EditorGUILayout.ObjectField("Next Camera Path", animator.nextAnimation, typeof(CameraPathBezierAnimator), true);

        if (bezier.mode == CameraPathBezier.viewmodes.mouselook)
        {
            EditorGUILayout.HelpBox("Alter the mouse sensitivity here", MessageType.Info);
            animator.sensitivity = EditorGUILayout.Slider("Mouse Sensitivity", animator.sensitivity, 0.1f, 2.0f);
            EditorGUILayout.HelpBox("Restrict the vertical viewable area here.", MessageType.Info);
            EditorGUILayout.LabelField("Mouse Y Restriction");
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(((int)animator.minX).ToString(), GUILayout.Width(30));
            EditorGUILayout.MinMaxSlider(ref animator.minX, ref animator.maxX, -180, 180);
            EditorGUILayout.LabelField(((int)animator.maxX).ToString(), GUILayout.Width(30));
            EditorGUILayout.EndHorizontal();
        }

        if (GUI.changed)
        {
            bezier.RecalculateStoredValues();
            EditorUtility.SetDirty(animator);
            EditorUtility.SetDirty(bezier);
        }
    }
    public override void OnInspectorGUI()
    {
        Camera[] cams           = Camera.allCameras;
        bool     sceneHasCamera = cams.Length > 0;

        if (Camera.main)
        {
            sceneCamera = Camera.main;
        }
        else if (sceneHasCamera)
        {
            sceneCamera = cams[0];
        }

        if (sceneCamera != null)
        {
            if (sceneCameraSkybox == null)
            {
                sceneCameraSkybox = sceneCamera.GetComponent <Skybox>();
            }
        }

        if (pointPreviewTexture == null)
        {
            pointPreviewTexture = new RenderTexture(400, Mathf.RoundToInt(400 / aspect), 24);
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Name:", GUILayout.Width(50));
        bezierControlPoint.name = EditorGUILayout.TextField(bezierControlPoint.name);
        EditorGUILayout.EndHorizontal();

        if ((EditorGUIUtility.isProSkin) && bezier.numberOfCurves > 0 && pointPreviewTexture != null)
        {
            bool cameraPathPreview = EditorPrefs.GetBool("CameraPathPreview");
            GUILayout.Space(7);
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Point Preview");
            if (cameraPathPreview)
            {
                if (GUILayout.Button("Hide", GUILayout.Width(50)))
                {
                    EditorPrefs.SetBool("CameraPathPreview", false);
                }
            }
            else
            {
                if (GUILayout.Button("Show", GUILayout.Width(50)))
                {
                    EditorPrefs.SetBool("CameraPathPreview", true);
                }
            }
            EditorGUILayout.Space();
            EditorGUILayout.EndHorizontal();

            if (!Application.isPlaying && EditorPrefs.GetBool("CameraPathPreview"))
            {
                if (animator.animationTarget == null)
                {
                    EditorGUILayout.HelpBox("No animation target has been specified so there is nothing to animate. Select an animation target in the Camera Path Bezier Animator Component in the parent clip", MessageType.Warning);
                    return;
                }

                previewCamPos = bezierControlPoint.transform.position;
                previewCamRot = Quaternion.identity;
                previewCamFOV = bezierControlPoint.FOV;

                Vector3 plusPoint, minusPoint;
                float   pointPercentage = bezier.GetPathPercentageAtPoint(bezierControlPoint);
                switch (bezier.mode)
                {
                case CameraPathBezier.viewmodes.usercontrolled:
                    previewCamRot = bezierControlPoint.transform.rotation;
                    break;

                case CameraPathBezier.viewmodes.target:

                    if (bezier.target != null)
                    {
                        previewCamRot = Quaternion.LookRotation(bezier.target.transform.position - bezierControlPoint.transform.position);
                    }
                    else
                    {
                        EditorGUILayout.HelpBox("No target has been specified in the bezier path", MessageType.Warning);
                        previewCamRot = Quaternion.identity;
                    }
                    break;

                case CameraPathBezier.viewmodes.followpath:

                    minusPoint    = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage - 0.05f));
                    plusPoint     = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage + 0.05f));
                    previewCamRot = Quaternion.LookRotation(plusPoint - minusPoint);
                    break;

                case CameraPathBezier.viewmodes.reverseFollowpath:

                    minusPoint    = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage - 0.05f));
                    plusPoint     = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage + 0.05f));
                    previewCamRot = Quaternion.LookRotation(minusPoint - plusPoint);
                    break;

                case CameraPathBezier.viewmodes.mouselook:

                    Vector3 minusPointb = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage - 0.05f));
                    Vector3 plusPointb  = bezier.GetPathPosition(Mathf.Clamp01(pointPercentage + 0.05f));
                    previewCamRot = Quaternion.LookRotation(plusPointb - minusPointb);
                    break;
                }

                GameObject cam = new GameObject("Point Preview");
                cam.AddComponent <Camera>();
                if (sceneCamera != null)
                {
                    cam.GetComponent <Camera>().backgroundColor = sceneCamera.backgroundColor;
                    if (sceneCameraSkybox != null)
                    {
                        cam.AddComponent <Skybox>().material = sceneCameraSkybox.material;
                    }
                    else
                    if (RenderSettings.skybox != null)
                    {
                        cam.AddComponent <Skybox>().material = RenderSettings.skybox;
                    }
                }
                cam.transform.position                    = previewCamPos;
                cam.transform.rotation                    = previewCamRot;
                cam.GetComponent <Camera>().fov           = previewCamFOV;
                cam.GetComponent <Camera>().targetTexture = pointPreviewTexture;
                cam.GetComponent <Camera>().Render();
                cam.GetComponent <Camera>().targetTexture = null;

                DestroyImmediate(cam);

                Rect previewRect = new Rect(0, 0, Screen.width, Screen.width / aspect);
                Rect layoutRect  = EditorGUILayout.BeginVertical();
                previewRect.x = layoutRect.x;
                previewRect.y = layoutRect.y + 5;
                EditorGUI.DrawPreviewTexture(previewRect, pointPreviewTexture);
                GUILayout.Space(previewRect.height + 10);
                EditorGUILayout.EndVertical();
            }
        }

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.HelpBox("The control point modifies the curve. Resetting it will centre it and there will be no curve. Useful if you don't want there to be a curve at this point", MessageType.Info);
        if (GUILayout.Button("Reset Control Point"))
        {
            Undo.RegisterUndo(bezierControlPoint.gameObject, "Reset Control Point");
            bezierControlPoint.controlPoint = Vector3.zero;
            EditorUtility.SetDirty(bezierControlPoint);
        }
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(10);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.HelpBox("Make the rotation of the Control Point face the direction the path is going in at this point", MessageType.Info);
        if (GUILayout.Button("Face Path Direction"))
        {
            Undo.RegisterUndo(bezierControlPoint.gameObject.transform, "Set Control Point Rotation to Path Direction");
            bezierControlPoint.SetRotationToCurve();
            EditorUtility.SetDirty(bezierControlPoint);
        }
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(10);
        if (!bezierControlPoint.isLastPoint || bezier.loop)
        {
            EditorGUILayout.HelpBox("This controls the easing applied from this point to the next.", MessageType.Info);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Animation Ease");
            bezierControlPoint.ease = (CameraPathBezierControlPoint.animationEase)EditorGUILayout.EnumPopup(bezierControlPoint.ease);
            EditorGUILayout.EndHorizontal();
        }
        else
        {
            EditorGUILayout.HelpBox("The last control point does not have easing options as there is no following curve.", MessageType.Info);
        }

        bezierControlPoint.controlPoint = EditorGUILayout.Vector3Field("Control Point Location", bezierControlPoint.controlPoint);
        //
        GUILayout.Space(7);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Field of View");
        bezierControlPoint.FOV = EditorGUILayout.Slider(bezierControlPoint.FOV, 1, 180);
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(7);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Delay");
        bezierControlPoint.delayMode = (CameraPathBezierControlPoint.DELAY_MODES)EditorGUILayout.EnumPopup(bezierControlPoint.delayMode);
        EditorGUILayout.EndHorizontal();

        if (bezierControlPoint.delayMode == CameraPathBezierControlPoint.DELAY_MODES.timed)
        {
            GUILayout.Space(7);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Time of delay");
            bezierControlPoint.delayTime = EditorGUILayout.FloatField(bezierControlPoint.delayTime, GUILayout.Width(50));
            EditorGUILayout.LabelField("secs", GUILayout.Width(30));
            EditorGUILayout.EndHorizontal();
        }

        if (bezier.mode == CameraPathBezier.viewmodes.followpath || bezier.mode == CameraPathBezier.viewmodes.reverseFollowpath)
        {
            GUILayout.Space(7);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Tilt", GUILayout.Width(40));
            bezierControlPoint.tilt = EditorGUILayout.Slider(bezierControlPoint.tilt, -180, 180);
            EditorGUILayout.EndHorizontal();
        }

        if (GUI.changed)
        {
            bezier.RecalculateStoredValues();

            EditorUtility.SetDirty(bezierControlPoint);
            EditorUtility.SetDirty(bezier);
            EditorUtility.SetDirty(animator);
        }
    }