private void UpdateRotation()
        {
            if (rotationState.IsActive)
            {
                if (inputProvider.OrbitAroundTarget)
                {
                    if (!isOrbiting && Physics.Raycast(transform.position, transform.forward, out RaycastHit hit, settings.InteractionDistance, settings.InteractionMask))
                    {
                        orbitPoint = hit.point;
                        isOrbiting = true;
                    }

                    if (isOrbiting)
                    {
                        // Rotation - Rotate horizontally around the focus point
                        transform.RotateAround(orbitPoint, Vector3.up, rotationState.Value * settings.MaxRotationalSpeed * Time.deltaTime);
                    }
                    else
                    {
                        // Rotation - Rotate around the world up vector
                        transform.Rotate(Vector3.up, rotationState.Value * settings.MaxRotationalSpeed * Time.deltaTime, Space.World);
                    }
                }
                else
                {
                    // Rotation - Rotate around the world up vector
                    transform.Rotate(Vector3.up, rotationState.Value * settings.MaxRotationalSpeed * Time.deltaTime, Space.World);
                    isOrbiting = false;
                }
            }

            // Tilt - Rotate around the local right vector
            if (tiltState.IsActive)
            {
                float currentTiltAngle = CurrentTiltAngle;
                currentTiltAngle += tiltState.Value * settings.MaxRotationalSpeed * Time.deltaTime;
                if (!operatingTiltRange.InRange(currentTiltAngle))
                {
                    currentTiltAngle = operatingTiltRange.Clamp(currentTiltAngle);
                }

                CurrentTiltAngle = currentTiltAngle;
                UpdateTiltFactor();
            }

            // Dirty fix for now: keep the z-value of the local Euler angles 0 to prevent drifting.
            Vector3 localEulerAngles = transform.localEulerAngles;

            localEulerAngles.z         = 0f;
            transform.localEulerAngles = localEulerAngles;
        }
        private void UpdateMovement()
        {
            // If moving to a focus point and the animation is requested to be cancelled.
            if ((moveToPositionHandle != null) && inputProvider.CancelMoveToTarget)
            {
                StopCoroutine(moveToPositionHandle);
                moveToPositionHandle = null;
            }
            else if (inputProvider.MoveToTarget)
            {
                MoveToTarget();
            }

            Vector3 movement = Vector3.zero;

            // If the camera isn't moving towards its focus point,
            // then we apply the forward and sideways movement
            if (!IsMovingToFocusPoint)
            {
                Vector3 direction = Vector3.zero;
                if (moveForwardsState.IsActive)
                {
                    Vector3 projectedForward = Vector3.ProjectOnPlane(transform.forward, Vector3.up).normalized;

                    // If the projected forward vector is close to 0, then that means the camera is facing down,
                    // Then we use the up-vector as an indicator to go forward.
                    if (projectedForward.sqrMagnitude <= settings.Epsilon)
                    {
                        projectedForward = Vector3.ProjectOnPlane(transform.up, Vector3.up).normalized;
                    }

                    direction += projectedForward * moveForwardsState.Value;
                }

                if (moveSidewaysState.IsActive)
                {
                    Vector3 projectedRight = Vector3.ProjectOnPlane(transform.right, Vector3.up).normalized;
                    direction += projectedRight * moveSidewaysState.Value;
                }

                if (direction.sqrMagnitude > settings.Epsilon)
                {
                    movement += direction.normalized * MaxMovementSpeed * Time.deltaTime;
                }
            }

            // Vertical movement - zoom in/out
            if (moveUpwardsState.IsActive)
            {
                Vector3 direction = Vector3.up * moveUpwardsState.Value;
                if (direction.sqrMagnitude > settings.Epsilon)
                {
                    movement += direction.normalized * MaxMovementSpeed * Time.deltaTime;
                }
            }

            float distance = movement.magnitude;

            // If hardly any movement is generated, then it can stop here.
            // No need for advanced extra processing.
            if (distance < settings.Epsilon)
            {
                return;
            }

            // Restrict the height movement
            Vector3 targetPosition = transform.position + movement;

            UpdateOperatingHeightRange(targetPosition);
            targetPosition.y = operatingHeightRange.Clamp(targetPosition.y);

            characterController.Move(targetPosition - transform.position);
        }