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);
            }
        }
Beispiel #2
0
        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
                }
            }
        }
Beispiel #3
0
        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
                }
            }
        }