Files
beyond/Assets/Scripts/Cutscene/CutSceneLerpCamera.cs
2024-11-20 15:21:28 +01:00

221 lines
7.7 KiB
C#

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<PlayableDirector>();
cutScene = GetComponent<CutScene>();
DisableAllCameras();
DisableAllAudioListeners();
}
private void DisableAllAudioListeners()
{
if (disableAllCamerasInChild)
{
Camera[] cameras = GetComponentsInChildren<Camera>(true);
for (int i = 0; i < cameras.Length; i++)
{
cameras[i].enabled = false;
}
}
}
private void DisableAllCameras()
{
if (disableAllAudioListenersInChild)
{
AudioListener[] audioListener = GetComponentsInChildren<AudioListener>(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();
}
}
}
}