简体   繁体   中英

Keep player velocity on slopes using Character Controller

I am using Unity's Character Controller tool to move my character.

I am using my own movement, gravity, etc, but it seems to be not affecting directly to the movement. I've checked my whole code and reduced it to the minimum just to seek the problem.

I've printed velocity, movement, magnitudes... Everything shows up that the movement it's exactly the same being on a flat surface or on slopes.

I don't know how the Character Controller's script works, so a kind of calculation might being causing that behaviour.

This is how I calculate my movement:

private void SetMovement() {
    horizontalMovement = isometricHorizontal * Input.GetAxisRaw(horizontalButton);
    verticalMovement = isometricVertical * Input.GetAxisRaw(verticalButton);
    movement = (horizontalMovement + verticalMovement).normalized;
    MovementModifier();
}

private void MovementModifier() {
    if (isSprinting) {
        movement.x *= sprintFactor;
        movement.z *= sprintFactor;
    }
}

private void Move() {
    if (movement != Vector3.zero)
        characterController.Move(movement * Time.deltaTime * moveSpeed);
}

The velocity down slopes increases at least 30% and is being reduced almost the same when going up.

I would like to keep the same velocity on any surface without needing to apply a movement modificator or reducing it while being over a certain area like slopes or stairs.

EDIT:

This is how I apply gravity.

private void ApplyGravity() {
    if (!characterController.isGrounded) {
        gravity += Physics.gravity * Time.deltaTime * gravityFactor;
        if (gravity.y > 0 && !Input.GetButton(jumpButton) && !isFalling)
            gravity += Physics.gravity * Time.deltaTime * gravityFactor * (lowJumpMultiplier - 1);
    }
    else if (!isJumping) gravity = Vector3.down;
    CheckCollisionFlags();
    movement += gravity;
}

private void CheckCollisionFlags() {
    switch (characterController.collisionFlags) {
        case UnityEngine.CollisionFlags.Above:
            gravity = Vector3.down;
            break;  
    }
}

Without seeing how you implement gravity, I can't be 100% sure but I would assume that something like this is happening ( treating it as if you were making a 2D side scroller ):

Your character would have horizontal movement, and as that is normalized you would get a constant horizontal speed.

However when you apply gravity, you are accelerating vertically, causing the velocity downwards to increase.

As you go down a slope, your horizontal movement is constant, but your vertical movement caused by gravity is getting added to your velocity after your velocity was normalized, resulting in a larger velocity when on a slope.


To get around this, you would probably need to do something like this:

Check if you are grounded, if you are then you are moving on a flat surface or on a slope, and you should normalize your velocity after adding the vertical movement caused by gravity.

I've just find out that I had to increase the CharacterController's Step Offset property. It seems that it was making some conflict while going up slopes or stairs and deducting the movement.

I achieved now the same movement speed going up and down slopes, that is higher than in flat surfaces, but it is easier to manage so far.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM