示例#1
0
        /// <summary>
        /// Rotates the camera according to the horizontal and vertical movement values.
        /// </summary>
        /// <param name="horizontalMovement">-1 to 1 value specifying the amount of horizontal movement.</param>
        /// <param name="verticalMovement">-1 to 1 value specifying the amount of vertical movement.</param>
        /// <param name="immediateUpdate">Should the camera be updated immediately?</param>
        /// <returns>The updated rotation.</returns>
        public override Quaternion Rotate(float horizontalMovement, float verticalMovement, bool immediateUpdate)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_VR
            if (m_VREnabled && immediateUpdate)
            {
                m_CharacterRotation = m_CharacterTransform.rotation;
                EventHandler.ExecuteEvent("OnTryRecenterTracking");
            }
#endif

            if (m_UpdateCharacterRotation)
            {
                // Rotate with the moving platform.
                if (m_CharacterLocomotion.Platform != null)
                {
                    m_PlatformRotation = MathUtility.InverseTransformQuaternion(m_CharacterLocomotion.Platform.rotation, m_CharacterPlatformRotationOffset) *
                                         Quaternion.Inverse(MathUtility.InverseTransformQuaternion(m_CharacterLocomotion.Platform.rotation, m_CharacterRotation *
                                                                                                   Quaternion.Inverse(m_CharacterLocomotion.Platform.rotation)));
                    if (!m_CharacterLocomotion.AlignToGravity)
                    {
                        // Only the local y rotation should affect the character's rotation.
                        var localPlatformTorque = MathUtility.InverseTransformQuaternion(m_CharacterTransform.rotation, m_PlatformRotation).eulerAngles;
                        localPlatformTorque.x = localPlatformTorque.z = 0;
                        m_PlatformRotation    = MathUtility.TransformQuaternion(m_CharacterTransform.rotation, Quaternion.Euler(localPlatformTorque));
                    }
                    m_CharacterRotation *= m_PlatformRotation;
                }

                // Keep the same relative rotation with the character if the character changes their up direction.
                if (m_CharacterLocomotion.AlignToGravity && m_AlignToGravityRotationSpeed > 0)
                {
                    var localRotation = MathUtility.InverseTransformQuaternion(m_CharacterTransform.rotation, m_CharacterRotation).eulerAngles;
                    localRotation.x     = localRotation.z = 0;
                    m_CharacterRotation = Quaternion.Slerp(m_CharacterRotation, MathUtility.TransformQuaternion(m_CharacterTransform.rotation, Quaternion.Euler(localRotation)), m_AlignToGravityRotationSpeed);
                }
            }

            // Remember the offset so the delta can be compared the next update.
            if (m_CharacterLocomotion.Platform != null)
            {
                UpdatePlatformRotationOffset(m_CharacterLocomotion.Platform);
            }

            // Update the rotation. The pitch may have a limit.
            if (Mathf.Abs(m_MinPitchLimit - m_MaxPitchLimit) < 180)
            {
                m_Pitch = MathUtility.ClampAngle(m_Pitch, -verticalMovement, m_MinPitchLimit, m_MaxPitchLimit);
            }
            else
            {
                m_Pitch -= verticalMovement;
            }

            // Prevent the values from getting too large.
            m_Pitch = MathUtility.ClampInnerAngle(m_Pitch);
            m_Yaw   = MathUtility.ClampInnerAngle(m_Yaw);

            // If aim assist has a target then the camera should look in the specified direction.
            if (m_AimAssist != null)
            {
                m_AimAssist.UpdateBreakForce(Mathf.Abs(horizontalMovement) + Mathf.Abs(verticalMovement));
                if (m_AimAssist.HasTarget())
                {
                    var rotation       = MathUtility.TransformQuaternion(m_CharacterRotation, Quaternion.Euler(m_Pitch, m_Yaw, 0));
                    var assistRotation = rotation * MathUtility.InverseTransformQuaternion(rotation, m_AimAssist.TargetRotation(rotation));
                    // Set the pitch and yaw so when the target is lost the view type won't snap back to the previous rotation value.
                    var localAssistRotation = MathUtility.InverseTransformQuaternion(m_CharacterRotation, assistRotation).eulerAngles;
                    m_Pitch = MathUtility.ClampInnerAngle(localAssistRotation.x);
                    m_Yaw   = MathUtility.ClampInnerAngle(localAssistRotation.y);
                }
            }

            // Return the rotation.
            return(MathUtility.TransformQuaternion(m_CharacterRotation, Quaternion.Euler(m_Pitch, m_Yaw, 0)) * Quaternion.LookRotation(m_ForwardAxis) * Quaternion.Euler(m_RotationSpring.Value) * Quaternion.Euler(m_SecondaryRotationSpring.Value));
        }