using Cinemachine; using System.Collections; using System.Collections.Generic; using UnityEngine; public class CMCameraRail : MonoBehaviour{ [SerializeField] CinemachineVirtualCamera dollyTrackCamera = default; CinemachineTrackedDolly cameraTrack; [Space] [SerializeField] Waypoint[] waypoints = default; int totalCount; int currentCount; bool finished; bool paused; float easedPercentBetweenWaypoints; float speed; float currentEase; float percentBetweenWaypoints; float nextPos; float lastFieldOfView; void Awake(){ totalCount = waypoints.Length - 1; if(dollyTrackCamera != null){ cameraTrack = dollyTrackCamera.GetCinemachineComponent(); } } // Update is called once per frame void Update(){ if(!finished && !paused){ Waypoint waypoint = waypoints[currentCount]; if(currentCount == 0){ speed = Time.deltaTime / waypoint.timeBetweenWaypoints * waypoint.endWaypoint; percentBetweenWaypoints += speed / waypoint.endWaypoint; percentBetweenWaypoints = Mathf.Clamp01(percentBetweenWaypoints); easedPercentBetweenWaypoints = Ease(percentBetweenWaypoints); nextPos = easedPercentBetweenWaypoints * waypoint.endWaypoint; }else{ speed = Time.deltaTime / waypoint.timeBetweenWaypoints * (waypoint.endWaypoint - waypoints[currentCount - 1].endWaypoint); percentBetweenWaypoints += speed / (waypoint.endWaypoint - waypoints[currentCount - 1].endWaypoint); percentBetweenWaypoints = Mathf.Clamp01(percentBetweenWaypoints); easedPercentBetweenWaypoints = Ease(percentBetweenWaypoints); nextPos = waypoints[currentCount - 1].endWaypoint + easedPercentBetweenWaypoints * (waypoint.endWaypoint - waypoints[currentCount - 1].endWaypoint); } dollyTrackCamera.m_Lens.FieldOfView = Mathf.Lerp(lastFieldOfView, waypoint.fieldOfView, easedPercentBetweenWaypoints); if (cameraTrack.m_PathPosition < waypoint.endWaypoint){ cameraTrack.m_PathPosition = nextPos; }else{ NextWaypoint(); } } } float Ease(float x){ if (waypoints[currentCount].ease){ float a = currentEase + 1; return Mathf.Pow(x, a) / (Mathf.Pow(x, a) + Mathf.Pow(1 - x, a)); }else{ return x; } } /// Starts playing the cutscene. public void StartRail(){ lastFieldOfView = dollyTrackCamera.m_Lens.FieldOfView; Waypoint waypoint = waypoints[currentCount]; if (waypoint.startDelay > 0){ paused = true; StartCoroutine(DelayMovement(waypoint.startDelay)); } currentEase = waypoint.ease ? waypoint.easeAmount : 1; } void NextWaypoint(){ lastFieldOfView = dollyTrackCamera.m_Lens.FieldOfView; if (currentCount >= totalCount){ Debug.Log("Finish"); finished = true; }else{ percentBetweenWaypoints = 0; currentCount++; Waypoint waypoint = waypoints[currentCount]; if(waypoint.startDelay > 0){ paused = true; StartCoroutine(DelayMovement(waypoint.startDelay)); } currentEase = waypoint.ease ? waypoint.easeAmount : 1; } } IEnumerator DelayMovement(float delay){ yield return new WaitForSeconds(delay); paused = false; } }