public void Update() { if (!gameActive) { return; } // at the start of the game move within the camera view so the player knows that they are being chased. Move to this same spot // if the player has hit too many obstacles. Also, don't move within the camera view if the player is on a sloped platform // since the chase object can obstruct the camera view if (!playerController.AbovePlatform(false) && ((Time.time < approachTime + visibleDuration) || (Time.time < startTime + previewDuration) || (playerController.maxCollisions != 0 && approachTime > 0) || attackParticles.isPlaying)) { Vector3 relativePosition = playerTransform.TransformPoint(visibleDistance); if (thisTransform.position != relativePosition) { // use smooth damping if the chase object is close to the target position if (Vector3.SqrMagnitude(thisTransform.position - relativePosition) < 2) { Vector3 currentVelocity = Vector3.zero; thisTransform.position = Vector3.SmoothDamp(thisTransform.position, relativePosition, ref currentVelocity, smoothMoveTime); } else { thisTransform.position = Vector3.MoveTowards(thisTransform.position, relativePosition, moveSpeed); } } else if (!gameManager.IsGameActive()) { gameActive = false; } // keep the chase character on the ground if the player is in the air if (playerController.InAir()) { // adjust the vertical position for any height changes RaycastHit hit; if (Physics.Raycast(thisTransform.position + Vector3.up, -thisTransform.up, out hit, Mathf.Infinity, platformLayer)) { Vector3 targetPosition = thisTransform.position; targetPosition.y = hit.point.y + visibleDistance.y; thisTransform.position = targetPosition; } } } else { // stay hidden for now if (thisTransform.position != playerTransform.TransformPoint(hiddenDistance)) { thisTransform.position = Vector3.MoveTowards(thisTransform.position, playerTransform.TransformPoint(hiddenDistance), moveSpeed); } } Vector3 rotation = Vector3.zero; rotation.y = playerTransform.eulerAngles.y; Quaternion targetRotation = Quaternion.identity; targetRotation.eulerAngles = rotation; if (thisTransform.rotation != targetRotation) { thisTransform.rotation = Quaternion.RotateTowards(thisTransform.rotation, targetRotation, rotateSpeed); } }
public void LateUpdate() { if (!gameActive && !isShaking) { return; } // Get the target position of the camera relative to the back of the player. This will also automatically reposition the camera so it is always behind the player's // back when turning Vector3 relativeTargetPosition = playerTransform.TransformPoint(targetPosition); // If enabled, keep the camera at the same y offset so it doesn't move vertically if the player jumps if (steadyHeight && verticalOffset > 0) { // set the vertical offset to 0 if the player isn't in the air anymore. This can happen if the player lands on an upward slope if (!playerController.InAir()) { verticalOffset = 0; } relativeTargetPosition.y -= verticalOffset; } // Face the same direction as the player on the y axis. Vector3 relativeTargetRotationVec = targetRotation.eulerAngles; relativeTargetRotationVec.y += playerTransform.eulerAngles.y; Quaternion relativeTargetRotation = thisTransform.rotation; relativeTargetRotation.eulerAngles = relativeTargetRotationVec; // if the camera is transitioning from one position to another then use the regular move towards / rotate towards. The camera transitions when moving between // menus. if (transitioning) { bool transitioned = true; if ((thisTransform.position - relativeTargetPosition).sqrMagnitude > 0.01f) { transitioned = false; thisTransform.position = Vector3.MoveTowards(thisTransform.position, relativeTargetPosition, moveSpeed); } if (Quaternion.Angle(thisTransform.rotation, relativeTargetRotation) > 0.01f) { transitioned = false; thisTransform.rotation = Quaternion.RotateTowards(thisTransform.rotation, relativeTargetRotation, rotationSpeed); } transitioning = !transitioned; } else { // The camera is not transition during normal play mode Vector3 currentVelocity = Vector3.zero; // Smoothly move between the current position and the target position thisTransform.position = Vector3.SmoothDamp(thisTransform.position, relativeTargetPosition, ref currentVelocity, smoothMoveTime); // if the camera should have a steady height and the player is in the air then keep the y position steady regardless of the smooth move time. if (steadyHeight && playerController.InAir()) { Vector3 position = thisTransform.position; position.y = relativeTargetPosition.y; thisTransform.position = position; } // Smoothly rotate between the current rotation and the target rotation thisTransform.rotation = Quaternion.RotateTowards(thisTransform.rotation, relativeTargetRotation, rotationSpeed); } // Apply a random rotation if shaking if (isShaking) { Vector3 rotation = relativeTargetRotation.eulerAngles; rotation.Set(rotation.x + Random.Range(-currentShakeIntensity, currentShakeIntensity), rotation.y + Random.Range(-currentShakeIntensity, currentShakeIntensity), rotation.z + Random.Range(-currentShakeIntensity, currentShakeIntensity)); currentShakeIntensity -= shakeDelta * Time.deltaTime; // slowly wind down thisTransform.eulerAngles = rotation; if (Time.time - shakeStartTime > shakeDuration) { isShaking = false; // will end on the next update loop } } }
public void LateUpdate() { if (!gameActive && !isShaking) { return; } Vector3 relativeTargetPosition = playerTransform.TransformPoint(targetPosition); if (steadyHeight && verticalOffset > 0) { // set the vertical offset to 0 if the player isn't in the air anymore. This can happen if the player lands on an upward slope if (!playerController.InAir()) { verticalOffset = 0; } relativeTargetPosition.y -= verticalOffset; } Vector3 relativeTargetRotationVec = targetRotation.eulerAngles; relativeTargetRotationVec.y += playerTransform.eulerAngles.y; Quaternion relativeTargetRotation = thisTransform.rotation; relativeTargetRotation.eulerAngles = relativeTargetRotationVec; // if the camera is transitioning from one position to another then use the regular move towards / rotate towards. if (transitioning) { bool transitioned = true; if ((thisTransform.position - relativeTargetPosition).sqrMagnitude > 0.01f) { transitioned = false; thisTransform.position = Vector3.MoveTowards(thisTransform.position, relativeTargetPosition, moveSpeed); } if (Quaternion.Angle(thisTransform.rotation, relativeTargetRotation) > 0.01f) { transitioned = false; thisTransform.rotation = Quaternion.RotateTowards(thisTransform.rotation, relativeTargetRotation, rotationSpeed); } transitioning = !transitioned; } else { Vector3 currentVelocity = Vector3.zero; thisTransform.position = Vector3.SmoothDamp(thisTransform.position, relativeTargetPosition, ref currentVelocity, smoothMoveTime); // if the camera should have a steady height and the player is in the air then keep the y position steady regardless of the smooth move time. if (steadyHeight && playerController.InAir()) { Vector3 position = thisTransform.position; position.y = relativeTargetPosition.y; thisTransform.position = position; } thisTransform.rotation = Quaternion.RotateTowards(thisTransform.rotation, relativeTargetRotation, rotationSpeed); } if (isShaking) { Vector3 rotation = relativeTargetRotation.eulerAngles; rotation.Set(rotation.x + Random.Range(-currentShakeIntensity, currentShakeIntensity), rotation.y + Random.Range(-currentShakeIntensity, currentShakeIntensity), rotation.z + Random.Range(-currentShakeIntensity, currentShakeIntensity)); currentShakeIntensity -= shakeDelta * Time.deltaTime; // slowly wind down thisTransform.eulerAngles = rotation; if (Time.time - shakeStartTime > shakeDuration) { isShaking = false; // will end on the next update loop } } }