//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; } }