//Used to set a bezier path for the gizmo drawing void SetPathFromIndex(bool mobilePath, int currentIndex) { Vector3[] debugPath = new Vector3[curveNodeCount[currentIndex]]; if (mobilePath) { for (int i = 0; i < curveNodeCount[currentIndex]; i++) { if (debugPath.Length > i) { debugPath[i] = QCBezier.Bezier2((float)i / curveNodeCount[currentIndex], cutsceneCameraPoints[currentIndex + 1].position, cutsceneMidPoints[currentIndex + 1].position, cutsceneCameraPoints[currentIndex + 2].position); } } } else { for (int i = 0; i < curveNodeCount[currentIndex]; i++) { if (debugPath.Length > i) { debugPath[i] = QCBezier.Bezier3((float)i / curveNodeCount[currentIndex], cutsceneCameraPoints[currentIndex + 1].position, cutsceneMidPoints[currentIndex + 1].position, cutsceneCubicMidPoints[currentIndex + 1].position, cutsceneCameraPoints[currentIndex + 2].position); } } } currentDebugnodes = debugPath; }
//Moves along a bezier path over a period of time private void CurveMove() { if (currentUseLerp) //If we are lerping, we need to create the points as we go { t += deltaTimeMultiplier / currentCameraSpeed; if (mobileCurve) { mainCamT.position = QCBezier.Bezier2(t, cutsceneCameraPoints[currentEvent + 1].position, cutsceneMidPoints[currentEvent + 1].position, cutsceneCameraPoints[currentEvent + 2].position); } else { mainCamT.position = QCBezier.Bezier3(t, cutsceneCameraPoints[currentEvent + 1].position, cutsceneMidPoints[currentEvent + 1].position, cutsceneCubicMidPoints[currentEvent + 1].position, cutsceneCameraPoints[currentEvent + 2].position); } if (t >= 1) { doUpdate = false; t = 0f; } } else { if (currentNodePosition < currentNodes.Length) { mainCamT.position = Vector3.MoveTowards(mainCamT.position, currentNodes[currentNodePosition], customCurveMovementSpeed[currentEvent] * Time.deltaTime); if (mainCamT.position == currentNodes[currentNodePosition]) { currentNodePosition += 1; } } else { doUpdate = false; currentNodePosition = 0; } } }
//This coroutine handles the cutscene whilst active. It will call itself to //proceed to the next 'event' in the cutscene after the preceding event is finished IEnumerator PlayCutscene() { //Make sure currentEvent is valid, if not, output to debug and end the cutscene if (cutsceneEventKeyTime.Length < currentEvent) { Debug.LogWarning("Camera event time " + cutsceneEventKeyTime[currentEvent] + " did not have a value set."); EndCutscene(); } //Broadcast the message at the start of this event if we want to if (broadcastMessageChoice[currentEvent]) { //Debug.Log("Trying to send message"); if (broadcastMessageTarget[currentEvent] != null && broadcastMessageString[currentEvent] != "") { broadcastMessageTarget[currentEvent].BroadcastMessage(broadcastMessageString[currentEvent], SendMessageOptions.DontRequireReceiver); } else { Debug.LogWarning("No target/method name for BroadcastMessage set"); } } //Wait desired amount before moving yield return(new WaitForSeconds(cutsceneEventKeyTime[currentEvent])); //Broadcast that we have reached a transition. Because we only do this at specific intervals, it is fine to use over delegates/events. BroadcastMessage("OnCutsceneEnterTransition", currentEvent + 1, SendMessageOptions.DontRequireReceiver); //Set our current positional, rotational and speed targets, with error handling if (cutsceneCameraPoints[currentEvent + 2] != null) { currentPositionTarget = cutsceneCameraPoints[currentEvent + 2].position; currentRotationTarget = cutsceneCameraPoints[currentEvent + 2].rotation; } else //If something is wrong, end the cutscene { Debug.LogWarning("Camera point " + cutsceneCameraPoints[currentEvent + 2] + " did not have a value set."); EndCutscene(); } //Set our movement and rotational speeds currentSpeedSetting = cutsceneCameraSpeedOptions[currentEvent]; currentRotationalSpeedSetting = cutsceneCameraRotationSpeedOptions[currentEvent]; //Check if we want to follow a target during this transition if (currentRotationalSpeedSetting == CameraRotationSpeedOptions.FollowTarget) { //Set the current position we want to follow with the camera currentSmoothFollowTarget = smoothFollowTarget[currentEvent]; //Handle null references if (!currentSmoothFollowTarget) { Debug.LogWarning("No smooth follow target set for event " + (currentEvent + 1)); EndCutscene(); } } //Set the cameras movement and rotational/follow speed targets SetCameraMovement(); //Make sure we are still in the cutscene before we change the time scales if (playingCutscene) { //Set the time scale to be used for this event Time.timeScale = cutsceneEventTimescale[currentEvent]; //Sets the fixed timestep as well. 0.02 is the default physics timestep Time.fixedDeltaTime = (cutsceneEventTimescale[currentEvent] * 0.02f); } SetAudioPitch(); //Start updating in Update() doUpdate = true; //Start camera shake if we want it if (doShake[currentEvent] == true) { cameraShakeTime = initialCameraShakeTime / cameraShakeAmount[currentEvent]; StartCoroutine("CameraShake"); } //Control zooming if (cutsceneEventZoom[currentEvent] == true) { currentZoomSpeed = cutsceneEventZoomSpeed[currentEvent]; SetZoomTarget(); } //Start curved movement if we want it if (curveChoice[currentEvent] == true && currentUseLerp == false) { if (currentEvent < cutsceneCameraPoints.Length) { Vector3[] path = new Vector3[curveNodeCount[currentEvent]]; //Check what curve we want (mobile is quadratic/lower cost, other is cubic) if (mobileCurve) { for (int i = 0; i < curveNodeCount[currentEvent]; i++) { path[i] = QCBezier.Bezier2((float)i / curveNodeCount[currentEvent], cutsceneCameraPoints[currentEvent + 1].position, cutsceneMidPoints[currentEvent + 1].position, cutsceneCameraPoints[currentEvent + 2].position); } } else { for (int i = 0; i < curveNodeCount[currentEvent]; i++) { path[i] = QCBezier.Bezier3((float)i / curveNodeCount[currentEvent], cutsceneCameraPoints[currentEvent + 1].position, cutsceneMidPoints[currentEvent + 1].position, cutsceneCubicMidPoints[currentEvent + 1].position, cutsceneCameraPoints[currentEvent + 2].position); } } currentNodes = path; //currentCameraSpeed = customCurveMovementSpeed[currentEvent] / currentNodes.Length;//Set this for lerping the value } else { Debug.LogWarning("Curve point not found, you cannot start a curve at the last camera point"); } } //Don't progress further until current update has finished while (doUpdate == true) { yield return(null); } //If we have gone through all the camera points, finish the cutscene if (currentEvent == cutsceneCameraPoints.Length - 3) { currentEvent++; EndCutscene(); } else //If not, proceed to the next event { currentEvent++; StartCoroutine("PlayCutscene"); } }