using Cinemachine; using System.Collections; using UnityEngine; /// <summary> /// Handles the movement and switching of the dolly cameras and the focused camera on the player /// </summary> public class CameraHandler : MonoBehaviour { [Header("Camera Components")] [SerializeField] float speedOfCameraMovementForDolly = 2f; // Speed of the camera movement of the dolly camera [SerializeField] float taskDelayValue = 2.5f; // Delay value for the time the player must remain still before being active when activated [SerializeField] CinemachineVirtualCamera dollyVirtualCameraRef; // Reference for the beginning Dolly Camera [SerializeField] CinemachineSmoothPath dollyForVirtualCamera; // Reference for the dolly track to get path length [SerializeField] CinemachineVirtualCamera followVirtualCamera; // Reference for the Virtual Camera that follows the player for the level CinemachineTrackedDolly dollyVirtualCamera; // Reference for the beginning Dolly Camera taken from the initial reference field bool trigger = false; // Trigger for if the camera script is necessary in the beginning Coroutine enablePlayerCoroutine; // Reference for the player coroutine GameOverlay gameOverlayRef; // Reference for the game overlay component in the current scene /// <summary> /// Getter for the Follow Camera for the Collision Handler /// </summary> /// <returns>Player Follow Camera</returns> public CinemachineVirtualCamera GetFollowCamera() { if (followVirtualCamera == null) return null; else return followVirtualCamera; } void Awake() { if (dollyVirtualCameraRef != null) { dollyVirtualCamera = dollyVirtualCameraRef.GetCinemachineComponent<CinemachineTrackedDolly>(); dollyVirtualCamera.m_PathPosition = 0f; trigger = true; } else return; } void Start() { if (trigger) GetComponent<Movement>().enabled = false; if (GameOverlay.Instance != null) gameOverlayRef = GameOverlay.Instance; } void Update() { if (!MainMenu.IsPaused) { if (trigger) { if (Input.GetKey(KeyCode.Space)) EnablePlayerStart(true); // When the player presses Space the beginning cutscene will be skipped and the // Moves the dolly camera along the path dollyVirtualCamera.m_PathPosition += (Time.deltaTime * speedOfCameraMovementForDolly); if (dollyVirtualCamera.m_PathPosition >= dollyForVirtualCamera.PathLength) EnablePlayerStart(false); // Indicator if the player has not pressed while the dolly camera has reached the end of the level showing } } } /// <summary> /// Skips the starting scene of the dolly camera moving through the level to give the player a glimpse /// </summary> /// <param name="skipTrigger">If the starting sequence should be skipped and the player can begin moving</param> void EnablePlayerStart(bool skipTrigger) => enablePlayerCoroutine ??= StartCoroutine(EnablePlayerCoroutine(skipTrigger)); /// <summary> /// Coroutine that enables and disables the necessary cameras for the player to begin playing the level while the virtual camera maintains focus on them /// </summary> /// <param name="skipTrigger">Determinant if the dolly camera should jump towards the player virtual camera that follows them</param> /// <returns></returns> IEnumerator EnablePlayerCoroutine(bool skipTrigger) { if (skipTrigger) dollyVirtualCamera.m_PathPosition = dollyForVirtualCamera.PathLength; // Switch main camera dollyVirtualCameraRef.enabled = false; followVirtualCamera.enabled = true; yield return new WaitForSeconds(taskDelayValue); // Allows player movement and starts the timer GetComponent<Movement>().enabled = true; if (gameOverlayRef != null) gameOverlayRef.StartTimer(); trigger = false; } /// <summary> /// Prevents the virtual camera from following the player further by detatching the player from the follow field /// </summary> public void DisableFollowCamera() => followVirtualCamera.Follow = null; }