using Invector.vCamera; using System.Collections; using UnityEngine; using UnityEngine.Playables; namespace Beyond { [RequireComponent(typeof(PlayableDirector))] public class CutSceneLerpCamera : MonoBehaviour { [Header("Lerp")] public bool disableAllCamerasInChild = true; public bool disableAllAudioListenersInChild = true; public Transform lerpTarget; [HideInInspector] public bool useDefaultCameraRotation; [Min(0.01f), Tooltip("How long is lerpIn in seconds")] public float lerpInDuration = 1f; [Min(0f), Tooltip("Time after which the timeline will run. ")] public float startTimeline = 1f; [Min(0.01f), Tooltip("How long is lerpOut in seconds")] public float lerpOutDuration = 1f; [Tooltip("The time lerpOut started relative to the end of the timeline. If the value is negative, the lerpOut starts before the end of the timeline.")] public float exitTimeline = 0f; public AnimationCurve lerpCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); private PlayableDirector playableDirector; private Quaternion cameraRotationStart; private Quaternion cameraRotationEnd; private Vector3 cameraPositionStart; private Vector3 cameraPositionEnd; private bool stopped; private bool isRunning; private float lerpInTime; private float lerpOutTime; private Transform cameraPlayerTransform; private CutScene cutScene; private bool followTarget; private void Awake() { playableDirector = GetComponent(); cutScene = GetComponent(); DisableAllCameras(); DisableAllAudioListeners(); } private void DisableAllAudioListeners() { if (disableAllCamerasInChild) { Camera[] cameras = GetComponentsInChildren(true); for (int i = 0; i < cameras.Length; i++) { cameras[i].enabled = false; } } } private void DisableAllCameras() { if (disableAllAudioListenersInChild) { AudioListener[] audioListener = GetComponentsInChildren(true); for (int i = 0; i < audioListener.Length; i++) { audioListener[i].enabled = false; } } } private void Start() { cameraPlayerTransform = vThirdPersonCamera.instance.transform; } private void OnEnable() { playableDirector.played += OnPlayed; } private void OnDisable() { playableDirector.played -= OnPlayed; } private void OnPlayed(PlayableDirector playableDirector) { if (cutScene && !cutScene.TimelineStarted) { return;//when timeline is played from playabledirector. } if (isRunning) { return; } lerpInTime = 0f; lerpOutTime = 0f; StartCoroutine(StartTimeLineDelay(startTimeline)); StartCoroutine(LerpCamera()); } private void OnStopped(PlayableDirector playableDirector) { cameraPositionEnd = lerpTarget.transform.position; cameraRotationEnd = lerpTarget.transform.rotation; if (cutScene) { cutScene.teleport.Teleport(lerpTarget); } stopped = true; } private IEnumerator StartTimeLineDelay(float delay) { yield return new WaitForSeconds(delay); playableDirector.Play(); StartCoroutine(ExitTimeline()); } private IEnumerator ExitTimeline() { var waitTime = playableDirector.duration + exitTimeline; yield return new WaitUntil(() => playableDirector.time != 0); if (exitTimeline > 0) { while (playableDirector.time < playableDirector.duration && playableDirector.time != 0) { yield return null; } yield return new WaitForSeconds(exitTimeline); } else { while (playableDirector.time < waitTime && playableDirector.time != 0) { yield return null; } } OnStopped(playableDirector); } private void LateUpdate() { if (lerpTarget != null && followTarget) { cameraPlayerTransform.transform.position = lerpTarget.transform.position; cameraPlayerTransform.transform.rotation = lerpTarget.transform.rotation; } } private IEnumerator LerpCamera() { isRunning = true; stopped = false; yield return null; // wait one frame for timeline camera position update playableDirector.Pause(); var orgiginalPos = cameraPlayerTransform.position; var orgiginalRot = cameraPlayerTransform.rotation; cameraPositionStart = cameraPlayerTransform.position; cameraRotationStart = cameraPlayerTransform.rotation; cameraPositionEnd = lerpTarget.transform.position; cameraRotationEnd = lerpTarget.transform.rotation; vThirdPersonCamera.instance.enabled = false; //var parent = cameraPlayerTransform.transform.parent; while (lerpInTime <= lerpInDuration) { lerpInTime += Time.deltaTime; var lerpProgressIn = Mathf.Clamp(lerpInTime / lerpInDuration, 0f, 1f); if (lerpTarget != null && cameraPlayerTransform != null) { cameraPlayerTransform.position = Vector3.Lerp(cameraPositionStart, lerpTarget.transform.position, lerpCurve.Evaluate(lerpProgressIn)); cameraPlayerTransform.rotation = Quaternion.Slerp(cameraRotationStart, lerpTarget.transform.rotation, lerpCurve.Evaluate(lerpProgressIn)); } yield return null; } followTarget = true; yield return new WaitUntil(() => stopped); followTarget = false; //cameraPositionEnd = bThirdPersonCamera.instance.GetCameraTargetPosition(useDefaultCameraRotation); //cameraRotationEnd = cameraRotationStart; cameraPositionEnd = orgiginalPos; cameraRotationEnd = orgiginalRot; cameraPositionStart = cameraPlayerTransform.transform.position; cameraRotationStart = cameraPlayerTransform.transform.rotation; while (lerpOutTime <= lerpOutDuration) { lerpOutTime += Time.deltaTime; var lerpProgressOut = Mathf.Clamp(lerpOutTime / lerpOutDuration, 0f, 1f); if (lerpTarget != null && cameraPlayerTransform != null) { cameraPlayerTransform.transform.position = Vector3.Lerp(cameraPositionStart, cameraPositionEnd, lerpCurve.Evaluate(lerpProgressOut)); cameraPlayerTransform.transform.rotation = Quaternion.Slerp(cameraRotationStart, cameraRotationEnd, lerpCurve.Evaluate(lerpProgressOut)); } yield return null; } isRunning = false; vThirdPersonCamera.instance.enabled = true; if (cutScene) { cutScene.EnableInputAndUI(); } } } }