Exemple #1
0
        /// <summary>
        /// Updates the motion over time. This is called by the controller
        /// every update cycle so animations and stages can be updated.
        /// </summary>
        /// <param name="rDeltaTime">Time since the last frame (or fixed update call)</param>
        /// <param name="rUpdateIndex">Index of the update to help manage dynamic/fixed updates. [0: Invalid update, >=1: Valid update]</param>
        public override void Update(float rDeltaTime, int rUpdateIndex)
        {
            mMovement = Vector3.zero;
            mRotation = Quaternion.identity;

            // Test if we stop sneak due to a change in stance. We do this here to transition
            if (mMotionController.State.AnimatorStates[mMotionLayer._AnimatorLayerIndex].MotionPhase == 0 && mMotionController._InputSource != null && mMotionController._InputSource.IsEnabled)
            {
                //if (mMotionController._InputSource.IsJustPressed(_ActionAlias))
                if (mMotionController._InputSource.IsReleased(_ActionAlias))
                {
                    // We have to use the forced value our we'll change the current blend value as we transition
                    mMotionController.ForcedInput.x = mInputX.Average;
                    mMotionController.ForcedInput.y = mInputY.Average;
                    mMotionController.SetAnimatorMotionPhase(mMotionLayer._AnimatorLayerIndex, PHASE_END, 0, true);
                }
            }

            // Grab the state info
            MotionState lState = mMotionController.State;

            // Convert the input to radial so we deal with keyboard and gamepad input the same.
            float lInputX         = lState.InputX;
            float lInputY         = lState.InputY;
            float lInputMagnitude = lState.InputMagnitudeTrend.Value;

            InputManagerHelper.ConvertToRadialInput(ref lInputX, ref lInputY, ref lInputMagnitude, 0.5f);

            // Smooth the input
            mInputX.Add(lInputX);
            mInputY.Add(lInputY);
            mInputMagnitude.Add(lInputMagnitude);

            // Use the smoothed values for input
            mMotionController.State.InputX = mInputX.Average;
            mMotionController.State.InputY = mInputY.Average;
            mMotionController.State.InputMagnitudeTrend.Replace(mInputMagnitude.Average);

            // If we're not dealing with an ootii camera rig, we need to rotate to the camera here
            if (_RotateWithCamera && !(mMotionController.CameraRig is BaseCameraRig))
            {
                OnCameraUpdated(rDeltaTime, rUpdateIndex, null);
            }

            // Rotate as needed
            if (!_RotateWithCamera && _RotateWithInput)
            {
                RotateUsingInput(rDeltaTime, ref mRotation);
            }
        }
Exemple #2
0
        /// <summary>
        /// Sets the value of this state with values from another
        ///
        /// Note: When the shift occurs, all intrinsict types (float, string, etc)
        /// have thier values copied over. Any reference types (arrays, objects) have
        /// thier references assigned. This includes 'child' properties.
        ///
        /// For the reference values... if we want them shared between the prev and current
        /// instances, we don't need to do anything.
        ///
        /// However, if we want reference values to be independant between the prev and current
        /// we need to grab the prev's reference, hold it, and then reset it.
        /// </summary>
        /// <param name="rSource">MotionState that has the data to copy</param>
        public static void Shift(ref MotionState rCurrent, ref MotionState rPrev)
        {
            // Reference objects need to be held onto otherwise our 'prev'
            // container will actually hold the reference in the 'current' container
            AnimatorLayerState[] lAnimatorStates = rPrev.AnimatorStates;

            // Move the current contents into the previous bucket
            rPrev = rCurrent;

            // Update the members of the states array. We have to do this
            // so 'prev' doesn't accidentally hold a reference sot the array in 'current'
            rPrev.AnimatorStates = lAnimatorStates;
            if (rPrev.AnimatorStates != null)
            {
                int lCount = lAnimatorStates.Length;
                for (int i = 0; i < lCount; i++)
                {
                    //rPrev.AnimatorStates[i] = rCurrent.AnimatorStates[i];

                    //TT
                    rPrev.AnimatorStates[i].SetTime                     = rCurrent.AnimatorStates[i].SetTime;
                    rPrev.AnimatorStates[i].MotionPhase                 = rCurrent.AnimatorStates[i].MotionPhase;
                    rPrev.AnimatorStates[i].MotionForm                  = rCurrent.AnimatorStates[i].MotionForm;
                    rPrev.AnimatorStates[i].MotionParameter             = rCurrent.AnimatorStates[i].MotionParameter;
                    rPrev.AnimatorStates[i].AutoClearMotionPhase        = rCurrent.AnimatorStates[i].AutoClearMotionPhase;
                    rPrev.AnimatorStates[i].AutoClearMotionPhaseReady   = rCurrent.AnimatorStates[i].AutoClearMotionPhaseReady;
                    rPrev.AnimatorStates[i].AutoClearActiveTransitionID = rCurrent.AnimatorStates[i].AutoClearActiveTransitionID;
                    rPrev.AnimatorStates[i].StateInfo                   = rCurrent.AnimatorStates[i].StateInfo;
                    rPrev.AnimatorStates[i].TransitionInfo              = rCurrent.AnimatorStates[i].TransitionInfo;
                }
            }

            // Initialize the object we're attached to. Don't clear
            // the contact position as we'll store it for future use
            //rCurrent.Support = null;
            //rCurrent.SupportPosition = Vector3.zero;
            //rCurrent.SupportRotation = Quaternion.identity;

            // Initialize the ground information
            //rCurrent.IsGrounded = false;
            //rCurrent.GroundAngle = 0f;
            //rCurrent.GroundNormal = Vector3.up;
            //rCurrent.GroundDistance = float.MaxValue;
        }
Exemple #3
0
        /// <summary>
        /// We smooth the input so that we don't start and stop immediately in the blend tree. That can create pops.
        /// </summary>
        protected void SmoothInput()
        {
            MotionState lState = mMotionController.State;

            // Convert the input to radial so we deal with keyboard and gamepad input the same.
            float lInputMax = (IsRunActive ? 1f : 0.5f);

            float lInputX = Mathf.Clamp(lState.InputX, -lInputMax, lInputMax);
            float lInputY = Mathf.Clamp(lState.InputY, -lInputMax, lInputMax);
            float lInputMagnitude = Mathf.Clamp(lState.InputMagnitudeTrend.Value, 0f, lInputMax);
            InputManagerHelper.ConvertToRadialInput(ref lInputX, ref lInputY, ref lInputMagnitude);

            // Smooth the input
            mInputX.Add(lInputX);
            mInputY.Add(lInputY);
            mInputMagnitude.Add(lInputMagnitude);

            // Modify the input values to add some lag
            mMotionController.State.InputX = mInputX.Average;
            mMotionController.State.InputY = mInputY.Average;
            mMotionController.State.InputMagnitudeTrend.Replace(mInputMagnitude.Average);
        }
Exemple #4
0
        /// <summary>
        /// Updates the motion over time. This is called by the controller
        /// every update cycle so animations and stages can be updated.
        /// </summary>
        /// <param name="rDeltaTime">Time since the last frame (or fixed update call)</param>
        /// <param name="rUpdateIndex">Index of the update to help manage dynamic/fixed updates. [0: Invalid update, >=1: Valid update]</param>
        public override void Update(float rDeltaTime, int rUpdateIndex)
        {
            mMovement = Vector3.zero;
            mRotation = Quaternion.identity;

            // Grab the state info
            MotionState lState = mMotionController.State;

            // Convert the input to radial so we deal with keyboard and gamepad input the same.
            float lInputMax = (IsRunActive ? 1f : 0.5f);

            float lInputX         = Mathf.Clamp(lState.InputX, -lInputMax, lInputMax);
            float lInputY         = Mathf.Clamp(lState.InputY, -lInputMax, lInputMax);
            float lInputMagnitude = Mathf.Clamp(lState.InputMagnitudeTrend.Value, 0f, lInputMax);

            InputManagerHelper.ConvertToRadialInput(ref lInputX, ref lInputY, ref lInputMagnitude);

            // Smooth the input
            mInputX.Add(lInputX);
            mInputY.Add(lInputY);
            mInputMagnitude.Add(lInputMagnitude);

            // Modify the input values to add some lag
            mMotionController.State.InputX = mInputX.Average;
            mMotionController.State.InputY = mInputY.Average;
            mMotionController.State.InputMagnitudeTrend.Replace(mInputMagnitude.Average);

            // If we're not dealing with an ootii camera rig, we need to rotate to the camera here
            if (_RotateWithCamera && !(mMotionController.CameraRig is BaseCameraRig))
            {
                OnCameraUpdated(rDeltaTime, rUpdateIndex, null);
            }

            if (!_RotateWithCamera && _RotateWithInput)
            {
                RotateUsingInput(rDeltaTime, ref mRotation);
            }
        }
        /// <summary>
        /// Updates the motion over time. This is called by the controller
        /// every update cycle so animations and stages can be updated.
        /// </summary>
        /// <param name="rDeltaTime">Time since the last frame (or fixed update call)</param>
        /// <param name="rUpdateIndex">Index of the update to help manage dynamic/fixed updates. [0: Invalid update, >=1: Valid update]</param>
        public override void Update(float rDeltaTime, int rUpdateIndex)
        {
            mVelocity = Vector3.zero;
            mMovement = Vector3.zero;
            float lHipDistanceDelta = 0f;

            // Since we're not doing any lerping or physics based stuff here,
            // we'll only process once per cyle even if we're running slow.
            if (rUpdateIndex != 1)
            {
                return;
            }

            // If we have a hip bone, we'll adjust the jump based on the distance
            // that changes between the foot and the hips. This way, the jump is
            // "hip based" and not "foot based".
            if (_ConvertToHipBase && mHipBone != null)
            {
                float lHipDistance = mHipBone.position.y - mMotionController._Transform.position.y;

                // As the distance gets smaller, we increase the shift
                lHipDistanceDelta = -(lHipDistance - mLastHipDistance);
                mLastHipDistance  = lHipDistance;
            }

            // Determine how gravity is being applied
            //Vector3 lWorldGravity = (mActorController._Gravity.sqrMagnitude == 0f ? UnityEngine.Physics.gravity : mActorController._Gravity);
            //if (mActorController._IsGravityRelative) { lWorldGravity = mActorController._Transform.rotation * lWorldGravity; }

            //Vector3 lGravityNormal = lWorldGravity.normalized;

            // Determine our velocities
            //mVelocity = mLaunchVelocity;

            //Vector3 lVelocity = mActorController.State.MovementForceAdjust / rDeltaTime;
            //Vector3 lVerticalVelocity = Vector3.Project(lVelocity, mActorController._Transform.up);

            // Grab the state info
            MotionState lState = mMotionController.State;
            //int lStateMotionPhase = lState.AnimatorStates[mMotionLayer._AnimatorLayerIndex].MotionPhase;
            //int lStateMotionParameter = lState.AnimatorStates[mMotionLayer._AnimatorLayerIndex].MotionParameter;

            //AnimatorStateInfo lStateInfo = lState.AnimatorStates[mMotionLayer._AnimatorLayerIndex].StateInfo;
            int   lStateID   = mMotionLayer._AnimatorStateID;
            float lStateTime = mMotionLayer._AnimatorStateNormalizedTime;

            //AnimatorTransitionInfo lTransitionInfo = lState.AnimatorStates[mMotionLayer._AnimatorLayerIndex].TransitionInfo;
            //int lTransitionID = lTransitionInfo.fullPathHash;

            // On launch, add the impulse
            if (lStateID == STATE_RunningJump)
            {
                // If we haven't applied the impulse, do it now.
                if (!mIsImpulseApplied)
                {
                    mIsImpulseApplied = true;
                    mActorController.AddImpulse(mActorController._Transform.up * _Impulse);
                }

                // As we come to the end, we have a couple of options
                if (!mIsExitTriggered && lStateTime > 0.80f)
                {
                    // If we're a long way from the ground, transition to a fall
                    if (mFall != null && mFall.IsEnabled && mActorController.State.GroundSurfaceDistance > _MinFallHeight)
                    {
                        mIsExitTriggered = true;
                        mMotionController.ActivateMotion(mFall);
                    }
                    // If we're still getting input, keep running
                    else if (lState.InputMagnitudeTrend.Value >= 0.1f) // && Mathf.Abs(lState.InputFromAvatarAngle) < 10f)
                    {
                        mIsExitTriggered = true;
                        mMotionController.SetAnimatorMotionPhase(mMotionLayer.AnimatorLayerIndex, PHASE_LAND_RUN, true);
                    }
                    // Come to a quick stop
                    else
                    {
                        mIsExitTriggered = true;
                        mMotionController.SetAnimatorMotionPhase(mMotionLayer.AnimatorLayerIndex, PHASE_LAND_IDLE, true);
                    }
                }
                // While in the jump, adjust the displacement
                else
                {
                    mMovement = mActorController._Transform.up * lHipDistanceDelta;
                }
            }
            // Once we get into the run forward, we can transition to the true run
            else if (lStateID == STATE_RunJump_RunForward)
            {
                if (lStateTime > 1f)
                {
                    // It may be time to move into the walk/run
                    if (mWalkRunMotion != null && mWalkRunMotion.IsEnabled)
                    {
                        mWalkRunMotion.StartInRun  = mWalkRunMotion.IsRunActive;
                        mWalkRunMotion.StartInWalk = !mWalkRunMotion.StartInRun;
                        mMotionController.ActivateMotion(mWalkRunMotion as MotionControllerMotion);
                    }
                    //if (mWalkRunPivot != null && mWalkRunPivot.IsEnabled)
                    //{
                    //    mWalkRunPivot.StartInRun = mWalkRunPivot.IsRunActive;
                    //    mWalkRunPivot.StartInWalk = !mWalkRunPivot.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunPivot);
                    //}
                    //else if (mWalkRunPivot_v2 != null && mWalkRunPivot_v2.IsEnabled)
                    //{
                    //    mWalkRunPivot_v2.StartInRun = mWalkRunPivot_v2.IsRunActive;
                    //    mWalkRunPivot_v2.StartInWalk = !mWalkRunPivot_v2.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunPivot_v2);
                    //}
                    //else if (mWalkRunStrafe != null && mWalkRunStrafe.IsEnabled)
                    //{
                    //    mWalkRunStrafe.StartInRun = mWalkRunStrafe.IsRunActive;
                    //    mWalkRunStrafe.StartInWalk = !mWalkRunStrafe.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunStrafe);
                    //}
                    //else if (mWalkRunStrafe_v2 != null && mWalkRunStrafe_v2.IsEnabled)
                    //{
                    //    mWalkRunStrafe_v2.StartInRun = mWalkRunStrafe_v2.IsRunActive;
                    //    mWalkRunStrafe_v2.StartInWalk = !mWalkRunStrafe_v2.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunStrafe_v2);
                    //}
                    //else if (mWalkRunRotate != null && mWalkRunRotate.IsEnabled)
                    //{
                    //    mWalkRunRotate.StartInRun = mWalkRunRotate.IsRunActive;
                    //    mWalkRunRotate.StartInWalk = !mWalkRunRotate.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunRotate);
                    //}
                    //else if (mWalkRunRotate_v2 != null && mWalkRunRotate_v2.IsEnabled)
                    //{
                    //    mWalkRunRotate_v2.StartInRun = mWalkRunRotate_v2.IsRunActive;
                    //    mWalkRunRotate_v2.StartInWalk = !mWalkRunRotate_v2.StartInRun;
                    //    mMotionController.ActivateMotion(mWalkRunRotate_v2);
                    //}
                    else
                    {
                        Deactivate();
                    }
                }
            }
            // Once we get to the idle pose, we can deactivate
            else if (lStateID == STATE_IdlePose)
            {
                Deactivate();
            }

            //Log.FileWrite("Adv_J.Update(" + rDeltaTime.ToString("f4") + ", " + rUpdateIndex + ") isAct:" + mIsActive + " " + mMotionController.AnimatorStateNames[lStateID] + " %:" + lStateInfo.normalizedTime.ToString("0.000") + " mm:" + mMovement.y.ToString("f4") + " mv:" + mVelocity.y.ToString("f4") + " pv:" + lProjectedVelocity.y.ToString("f4"));
        }
Exemple #6
0
        /// <summary>
        /// Returns the current velocity of the motion
        /// </summary>
        protected Vector3 DetermineVelocity(bool rAllowSlide)
        {
            Vector3 lVelocity = Vector3.zero;

            //int lStateID = mMotionLayer._AnimatorStateID;

            // TRT 11/20/15: If we're colliding with an object, we won't allow
            // any velocity. This helps prevent sliding while jumping
            // against an object.
            if (mActorController.State.IsColliding)
            {
                return(lVelocity);
            }

            // Determines if we allow sliding or not
            if (!rAllowSlide && mActorController.State.IsGrounded)
            {
                return(lVelocity);
            }

            // If were in the midst of jumping, we want to add velocity based on
            // the magnitude of the controller.
            //if ((lStateID != STATE_JumpRecoverIdle || rAllowSlide) &&
            //    (lStateID != STATE_JumpRecoverRun || rAllowSlide) &&
            //    IsInMotionState)
            {
                MotionState lState = mMotionController.State;

                // Speed that comes from momenum
                Vector3 lMomentum      = mLaunchVelocity;
                float   lMomentumSpeed = (_IsMomentumEnabled ? lMomentum.magnitude : 0f);

                // Speed that comes from the user
                float lControlSpeed = (_IsControlEnabled ? _ControlSpeed * lState.InputMagnitudeTrend.Value : 0f);

                // Speed we'll use as the character is jumping
                float lAirSpeed = Mathf.Max(lMomentumSpeed, lControlSpeed);

                // If we allow control, let the player determine the direction
                if (_IsControlEnabled)
                {
                    Vector3 lBaseForward = mActorController._Transform.forward;
                    if (mMotionController._InputSource != null && mMotionController._InputSource.IsEnabled)
                    {
                        if (mMotionController._CameraTransform != null)
                        {
                            lBaseForward = mMotionController._CameraTransform.forward;
                        }
                    }

                    // Create a quaternion that gets us from our world-forward to our actor/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 lToBaseForward = Quaternion.LookRotation(lBaseForward, mActorController._Transform.up);

                    // Determine the avatar displacement direction. This isn't just
                    // normal movement forward, but includes movement to the side
                    Vector3 lMoveDirection = lToBaseForward * lState.InputForward;

                    // Apply the direction and speed
                    lVelocity = lVelocity + (lMoveDirection * lAirSpeed);
                }

                // If momementum is enabled, add it to keep the player moving in the direction of the jump
                if (_IsMomentumEnabled)
                {
                    lVelocity = lVelocity + lMomentum;
                }

                // Don't exceed our air speed
                if (lVelocity.magnitude > lAirSpeed)
                {
                    lVelocity = lVelocity.normalized * lAirSpeed;
                }
            }

            return(lVelocity);
        }