Ejemplo n.º 1
0
        /// <summary>
        /// Called every frame to perform processing. We only use
        /// this function if it's not called by another component.
        /// </summary>
        protected void Update()
        {
            if (mAnimator == null)
            {
                return;
            }
            if (mCameraRig == null)
            {
                return;
            }
            if (Time.deltaTime == 0f)
            {
                return;
            }

            // Store the state we're in
            mStateInfo      = mAnimator.GetCurrentAnimatorStateInfo(0);
            mTransitionInfo = mAnimator.GetAnimatorTransitionInfo(0);

            if (mCameraRig.Mode == 2)
            {
                if (mStance != 2)
                {
                    mPrevStance = mStance;
                    mStance     = 2;
                }
            }
            else
            {
                if (mStance == 2)
                {
                    mStance = mPrevStance;
                }
            }

            // Determine the stance we're in
            if (mInputSource != null && mInputSource.IsPressed(KeyCode.LeftControl))
            {
                //if (mStance != 2)
                //{
                //    mPrevStance = mStance;
                //    mStance = 2;

                //    mPrevRigMode = CameraRigMode;

                //    // Start the transition process
                //    //_CameraRig.TransitionToMode(EnumCameraMode.FIRST_PERSON);
                //    CameraRigMode = EnumCameraMode.FIRST_PERSON;
                //}
            }
            else if (mStance == 2)
            {
                //mStance = mPrevStance;

                ////_CameraRig.TransitionToMode(mPrevRigMode);
                //CameraRigMode = mPrevRigMode;
            }
            else if (mInputSource != null && mInputSource.IsJustPressed(KeyCode.T))
            {
                mPrevStance = mStance;
                if (mStance == 0)
                {
                    mStance = 1;
                    ((AdventureRig)mCameraRig).AnchorOrbitsCamera = false;
                }
                else if (mStance == 1)
                {
                    mStance = 0;
                    ((AdventureRig)mCameraRig).AnchorOrbitsCamera = true;
                }

                mCameraRig.Mode = 0;
            }

            // Grab the direction and speed of the input relative to our current heading
            StickToWorldspace(this.transform, _CameraRig.transform, ref mTempState);

            // Ensure some of the other values are set correctly
            mTempState.Acceleration   = mState.Acceleration;
            mTempState.InitialHeading = mState.InitialHeading;

            // Ranged movement allows for slow forward, backwards, and strafing
            if (mStance == 2)
            {
                //CameraRigMode = EnumCameraMode.FIRST_PERSON;

                mTempState.Speed *= _TargetingStanceMovementSpeedMultiplier;

                // Change our heading if needed
                if (mTempState.Speed == 0)
                {
                    if (IsInBackwardsState)
                    {
                        mTempState.InitialHeading = 2;
                    }
                    else
                    {
                        mTempState.InitialHeading = 0;
                    }
                }
                else if (mTempState.Speed != 0 && mState.Speed == 0)
                {
                    float lInitialAngle = Mathf.Abs(mTempState.FromCameraAngle);
                    if (lInitialAngle < mForwardHeadingLimit)
                    {
                        mTempState.InitialHeading = 0;
                    }
                    else if (lInitialAngle > 180f - mBackwardsHeadingLimit)
                    {
                        mTempState.InitialHeading = 2;
                    }
                    else
                    {
                        mTempState.InitialHeading = 1;
                    }
                }

                // Ensure we're always facing forward
                //mYAxisRotationAngle = NumberHelper.GetHorizontalAngle(transform.forward, _CameraRig.transform.forward);
                //mTempState.FromAvatarAngle = 0f;
            }
            // Combat movement allows for forward, backwards, strafing, and pivoting
            else if (mStance == 1)
            {
                // Determine our initial heading
                if (mTempState.Speed == 0)
                {
                    if (IsInBackwardsState)
                    {
                        mTempState.InitialHeading = 2;
                    }
                    else
                    {
                        mTempState.InitialHeading = 0;
                    }
                }
                else if (mTempState.Speed != 0 && mState.Speed == 0)
                {
                    float lInitialAngle = Mathf.Abs(mTempState.FromCameraAngle);
                    if (lInitialAngle < mForwardHeadingLimit)
                    {
                        mTempState.InitialHeading = 0;
                    }
                    else if (lInitialAngle > 180f - mBackwardsHeadingLimit)
                    {
                        mTempState.InitialHeading = 2;
                    }
                    else
                    {
                        mTempState.InitialHeading = 1;
                    }
                }

                // Ensure if we've been heading forward that we don't allow the
                // avatar to rotate back facing the player
                if (mTempState.InitialHeading == 0)
                {
                    //CameraRigMode = EnumCameraMode.THIRD_PERSON_FOLLOW;

                    // Force the input to make us go forwards
                    if (mTempState.Speed > 0.1f && (mTempState.FromCameraAngle < -90 || mTempState.FromCameraAngle > 90))
                    {
                        mTempState.InputY = 1;
                    }

                    // If no forward rotation is allowed, this is easy
                    if (mForwardHeadingLimit == 0f)
                    {
                        mTempState.FromAvatarAngle = 0f;
                    }
                    // Respect the foward rotation limits
                    else
                    {
                        // Test if our rotation reaches the max from the camera. We use the camera since
                        // the avatar itself rotates and this limit is relative.
                        if (mTempState.FromCameraAngle < -mForwardHeadingLimit)
                        {
                            mTempState.FromCameraAngle = -mForwardHeadingLimit;
                        }
                        else if (mTempState.FromCameraAngle > mForwardHeadingLimit)
                        {
                            mTempState.FromCameraAngle = mForwardHeadingLimit;
                        }

                        // If we have reached a limit, we need to adjust the avatar angle
                        if (Mathf.Abs(mTempState.FromCameraAngle) == mForwardHeadingLimit)
                        {
                            // Flip the angle if we're crossing over the axis
                            if (Mathf.Sign(mTempState.FromCameraAngle) != Mathf.Sign(mState.FromCameraAngle))
                            {
                                mTempState.FromCameraAngle = -mTempState.FromCameraAngle;
                            }

                            // Only allow the avatar to rotate the heading limit, taking into account the angular
                            // difference between the camera and the avatar
                            mTempState.FromAvatarAngle = mTempState.FromCameraAngle + NumberHelper.GetHorizontalAngle(transform.forward, _CameraRig.transform.forward);
                        }
                    }
                }
                else if (mTempState.InitialHeading == 2)
                {
                    //CameraRigMode = EnumCameraMode.THIRD_PERSON_FIXED;

                    // Force the input to make us go backwards
                    if (mTempState.Speed > 0.1f && (mTempState.FromCameraAngle > -90 && mTempState.FromCameraAngle < 90))
                    {
                        mTempState.InputY = -1;
                    }

                    // Ensure we don't go beyond our boundry
                    if (mBackwardsHeadingLimit != 0f)
                    {
                        float lBackwardsHeadingLimit = 180f - mBackwardsHeadingLimit;

                        // Test if our rotation reaches the max from the camera. We use the camera since
                        // the avatar itself rotates and this limit is relative.
                        if (mTempState.FromCameraAngle <= 0 && mTempState.FromCameraAngle > -lBackwardsHeadingLimit)
                        {
                            mTempState.FromCameraAngle = -lBackwardsHeadingLimit;
                        }
                        else if (mTempState.FromCameraAngle >= 0 && mTempState.FromCameraAngle < lBackwardsHeadingLimit)
                        {
                            mTempState.FromCameraAngle = lBackwardsHeadingLimit;
                        }

                        // If we have reached a limit, we need to adjust the avatar angle
                        if (Mathf.Abs(mTempState.FromCameraAngle) == lBackwardsHeadingLimit)
                        {
                            // Only allow the avatar to rotate the heading limit, taking into account the angular
                            // difference between the camera and the avatar
                            mTempState.FromAvatarAngle = mTempState.FromCameraAngle + NumberHelper.GetHorizontalAngle(transform.forward, _CameraRig.transform.forward);
                        }

                        // Since we're moving backwards, we need to flip the movement angle.
                        // If we're not moving and simply finishing an animation, we don't
                        // want to rotate at all.
                        if (mTempState.Speed == 0)
                        {
                            mTempState.FromAvatarAngle = 0f;
                        }
                        else if (mTempState.FromAvatarAngle <= 0)
                        {
                            mTempState.FromAvatarAngle += 180f;
                        }
                        else if (mTempState.FromAvatarAngle > 0)
                        {
                            mTempState.FromAvatarAngle -= 180f;
                        }
                    }
                }
                else if (mTempState.InitialHeading == 1)
                {
                    //CameraRigMode = EnumCameraMode.THIRD_PERSON_FIXED;

                    // Move out of the sidestep if needed
                    if (mTempState.InputY > 0.1)
                    {
                        mTempState.InitialHeading = 0;
                    }
                    else if (mTempState.InputY < -0.1)
                    {
                        mTempState.InitialHeading = 2;
                    }

                    // We need to be able to rotate our avatar so it's facing
                    // in the direction of the camera
                    if (mTempState.InitialHeading == 1)
                    {
                        mTempState.FromCameraAngle = 0f;
                        mTempState.FromAvatarAngle = mTempState.FromCameraAngle + NumberHelper.GetHorizontalAngle(transform.forward, _CameraRig.transform.forward);
                    }
                }
            }

            // Determine the acceleration. We test this agains the 'last-last' speed so
            // that we are averaging out one frame.
            //mLastAcceleration = mAcceleration;
            mPrevState.Acceleration = mState.Acceleration;

            // Determine the trend so we can figure out acceleration
            if (mTempState.Speed == mState.Speed)
            {
                if (mSpeedTrendDirection != 0)
                {
                    mSpeedTrendDirection = 0;
                }
            }
            else if (mTempState.Speed < mState.Speed)
            {
                if (mSpeedTrendDirection != 1)
                {
                    mSpeedTrendDirection = 1;
                    if (mMecanimUpdateDelay <= 0f)
                    {
                        mMecanimUpdateDelay = 0.2f;
                    }
                }

                // Acceleration needs to stay consistant for mecanim
                mTempState.Acceleration = mTempState.Speed - mSpeedTrendStart;
            }
            else if (mTempState.Speed > mState.Speed)
            {
                if (mSpeedTrendDirection != 2)
                {
                    mSpeedTrendDirection = 2;
                    if (mMecanimUpdateDelay <= 0f)
                    {
                        mMecanimUpdateDelay = 0.2f;
                    }
                }

                // Acceleration needs to stay consistant for mecanim
                mTempState.Acceleration = mTempState.Speed - mSpeedTrendStart;
            }

            // Shuffle the states to keep us from having to reallocated
            AdventureControllerState lTempState = mPrevState;

            mPrevState = mState;
            mState     = mTempState;
            mTempState = lTempState;

            // Apply the movement and rotation
            ApplyMovement();
            ApplyRotation();

            // Delay a bit before we update the speed if we're accelerating
            // or decelerating.
            mMecanimUpdateDelay -= Time.deltaTime;
            if (mMecanimUpdateDelay <= 0f)
            {
                mAnimator.SetFloat("Speed", mState.Speed); //, 0.05f, Time.deltaTime);

                mSpeedTrendStart = mState.Speed;
            }

            // Update the direction relative to the avatar
            mAnimator.SetFloat("Avatar Direction", mState.FromAvatarAngle);

            // At this point, we never use angular speed. Rotation is done
            // in the ApplyRotation() function. Angular speed currently only effects
            // locomotion.
            mAnimator.SetFloat("Angular Speed", 0f);

            // The stance determins if we're in exploration or combat mode.
            mAnimator.SetInteger("Stance", mStance);

            // The direction from the camera
            mAnimator.SetFloat("Camera Direction", mState.FromCameraAngle); //, 0.05f, Time.deltaTime);

            // The raw input from the UI
            mAnimator.SetFloat("Input X", mState.InputX); //, 0.25f, Time.deltaTime);
            mAnimator.SetFloat("Input Y", mState.InputY); //, 0.25f, Time.deltaTime);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This function is used to convert the game control stick value to
        /// speed and direction values for the player.
        /// </summary>
        protected void StickToWorldspace(Transform rController, Transform rCamera, ref AdventureControllerState rState)
        {
            if (mInputSource == null)
            {
                return;
            }

            // Grab the movement, but create a bit of a dead zone
            float lHInput = mInputSource.MovementX;
            float lVInput = mInputSource.MovementY;

            // Get out early if we can simply this
            if (lVInput == 0f && lHInput == 0f)
            {
                rState.Speed           = 0f;
                rState.FromAvatarAngle = 0f;
                rState.InputX          = 0f;
                rState.InputY          = 0f;

                return;
            }

            // Determine the relative speed
            rState.Speed = Mathf.Sqrt((lHInput * lHInput) + (lVInput * lVInput));

            // Create a simple vector off of our stick input and get the speed
            sVector3A.x = lHInput;
            sVector3A.y = 0f;
            sVector3A.z = lVInput;

            // Direction of the avatar
            Vector3 lControllerForward = rController.forward;

            lControllerForward.y = 0f;
            lControllerForward.Normalize();

            // Direction of the camera
            Vector3 lCameraForward = rCamera.forward;

            lCameraForward.y = 0f;
            lCameraForward.Normalize();

            // Create a quaternion that gets us from our world-forward to our camera direction.
            // FromToRotation creates a quaternion using the shortest method which can sometimes
            // flip the angle. LookRotation will attempt to keep the "up" direction "up".
            //Quaternion rToCamera = Quaternion.FromToRotation(Vector3.forward, Vector3.Normalize(lCameraForward));
            Quaternion rToCamera = Quaternion.LookRotation(lCameraForward);

            // Transform joystick from world space to camera space. Now the input is relative
            // to how the camera is facing.
            Vector3 lMoveDirection = rToCamera * sVector3A;

            rState.FromCameraAngle = NumberHelper.GetHorizontalAngle(lCameraForward, lMoveDirection);
            rState.FromAvatarAngle = NumberHelper.GetHorizontalAngle(lControllerForward, lMoveDirection);

            // Set the direction of the movement in ranges of -1 to 1
            rState.InputX = lHInput;
            rState.InputY = lVInput;

            //Debug.DrawRay(new Vector3(rController.position.x, rController.position.y + 2f, rController.position.z), lControllerForward, Color.gray);
            //Debug.DrawRay(new Vector3(rController.position.x, rController.position.y + 2f, rController.position.z), lMoveDirection, Color.green);
        }