Beispiel #1
0
    //Apply friction to both vertical and horizontal momentum based on 'friction' and 'gravity';
    //Handle sliding down steep slopes;
    void HandleMomentum()
    {
        //If local momentum is used, transform momentum into world coordinates first;
        if (useLocalMomentum)
        {
            momentum = _characterGameObject.transform.localToWorldMatrix * momentum;
        }

        Vector3 _verticalMomentum   = Vector3.zero;
        Vector3 _horizontalMomentum = Vector3.zero;

        //Split momentum into vertical and horizontal components;
        if (momentum != Vector3.zero)
        {
            _verticalMomentum   = VectorMath.ExtractDotVector(momentum, _characterGameObject.transform.up);
            _horizontalMomentum = momentum - _verticalMomentum;
        }

        //Add gravity to vertical momentum;
        _verticalMomentum += _characterGameObject.transform.up * gravity * Time.deltaTime;

        //Remove any downward force if the controller is grounded;
        if (_state == LocomotionState.Grounded)
        {
            _verticalMomentum = Vector3.zero;
        }

        //Apply friction to horizontal momentum based on whether the controller is grounded;
        if (_state == LocomotionState.Grounded)
        {
            _horizontalMomentum = VectorMath.IncrementVectorTowardTargetVector(_horizontalMomentum, groundFriction, Time.deltaTime, Vector3.zero);
        }
        else
        {
            _horizontalMomentum = VectorMath.IncrementVectorTowardTargetVector(_horizontalMomentum, airFriction, Time.deltaTime, Vector3.zero);
        }

        //Add horizontal and vertical momentum back together;
        momentum = _horizontalMomentum + _verticalMomentum;


        //Project the current momentum onto the current ground normal if the controller is sliding down a slope;
        if (_state == LocomotionState.Sliding)
        {
            momentum = Vector3.ProjectOnPlane(momentum, _characterMover.GetGroundNormal());
        }

        //Apply slide gravity along ground normal, if controller is sliding;
        if (_state == LocomotionState.Sliding)
        {
            Vector3 _slideDirection = Vector3.ProjectOnPlane(-_characterGameObject.transform.up, _characterMover.GetGroundNormal()).normalized;
            momentum += _slideDirection * slideGravity * Time.deltaTime;
            momentum  = Vector3.ClampMagnitude(momentum, slidingMaxVelocity);
        }

        //If controller is jumping, override vertical velocity with jumpSpeed;
        if (_state == LocomotionState.Jumping)
        {
            //momentum = VectorMath.RemoveDotVector(momentum, _characterGameObject.transform.up);
            //momentum += _characterGameObject.transform.up * jumpSpeed;
            if (JumpVelocity != Vector3.zero)
            {
                momentum.x   = 0f;
                momentum.z   = 0f;
                momentum    += JumpVelocity;
                JumpVelocity = Vector3.zero;
            }
        }

        if (useLocalMomentum)
        {
            momentum = _characterGameObject.transform.worldToLocalMatrix * momentum;
        }
    }