Resetting y velocity breaks slope movement, here's how

okidoki, so on line 7 I set my moveDirection to be moveDirection but tilted in the direction of whatever I’m standing on and then on line 13 i set my movement in the y direction to be whatever the velocity of the rigidbody is. I call MovePlayer() in FixedUpdate.

Line 7 is to make slopes work, and line 13 is so that I don’t set my y velocity to 0 every update (Making gravity and jumping work like it should).

The problem I think is that when I am standing still my movement should align with the slope, meaning that it should have a y that is slightly less than 0 if I’m walking down and more than 0 if I’m walking up, but I set it to be zero.

In game if I walk on a slope my moveDirection will initially be straight out in front of me, before turning to the desired direction it should be while on a slope.

How can I make it so that gravity and jumping works as it should, but the moveDirection is pointing in the right direction on slopes.

If I didn’t explain this very well feel free to ask me anything.

private void MovePlayer()
    {
        Physics.Raycast(transform.position, Vector3.down, out slopeHit, playerHeight * 0.5f + 1.0f);
        
        moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
        
        moveDirection = Vector3.ProjectOnPlane(moveDirection, slopeHit.normal);


        Vector3 movement = moveDirection.normalized * moveSpeed;

        //This breaks my slopes. It's probably because i am supposed to have a negative y value when going down the slope, but i set it to 0.
        movement.y = rb.linearVelocity.y;

        rb.linearVelocity = movement;

If you use AddForce to move your character around then the gradual acceleration and deceleration will prevent your character from taking off on slopes. But if you’re setting the velocity directly because you don’t like inertia then only project the movement vector to the slope when the player is on the ground and the y velocity is below the jump velocity. Also, use SphereCast instead of Raycast.

You are exactly right in assuming that I don’t like the inertia. Did you mean only change y velocity for the player if the player is on the ground and the force is less than jump force? Because that kind of works. Not quite though but It is a lot closer than what I had before. Changing the part where I ProjectOnPlane however doesn’t do anything. Maybe I misunderstood?

SphereCast covers a wider area and will work on the corners of platforms. The radius should be the same as your character’s capsule radius.

    private void MovePlayer()
    {
        Vector3 movement = (orientation.forward * verticalInput + orientation.right * horizontalInput).normalized * moveSpeed;
        if (rb.velocity.y < 8 && Physics.SphereCast(transform.position, 0.5f, Vector3.down, out slopeHit, 0.6f)) // assumes you're using a capsule collider with a height of 2 and a radius of 0.5
            movement = Vector3.ProjectOnPlane(movement, slopeHit.normal);
        else
            movement.y = rb.velocity.y;

        rb.linearVelocity = movement;
    }

you are a legend