Character Jumping Strange While Moving Up Slopes

Hello,
I have made an FPS player movement script using CharacterController and there is an issue when the player is moving up a slope and jumps. It seems that when the player jumps up a slope it does a ‘mini jump’ sorta thing, and if I stop during that jump the player continues the jump upwards?

It’s hard to explain so I made this really bad diagram:

Here is the code I use to make the player jump:

if (Input.GetKeyDown(JumpKey) && isGrounded)
{
velocity.y = Mathf.Sqrt(JumpHeight * -2f * Gravity);
}

This is a result of passing the input values directly into CharacterController.Move. When you release input the character quickly stops moving on the horizontal plane but it still has the upward velocity from the jump.

It’s possible to give the character controller more realistic movement or inertia by adding the input to a velocity vector but it’ll still be a little quirky in certain situations because the character controller wasn’t made to be realistic. Alternatively you could consider using a rigidbody based character.

I’m not really going for realistic movement, that is just the only way I know how to make the player jump. Is there an alternative method that will stop this issue from occurring?

I would suggest using a rigidbody based character, they are usually much better. If you don’t know how to make one of these, look up any number of tutorials on google, there’s a billion of them.

(Rigidbody is better because it allows for physics interactions that make more sense, and allows for many more options, especially later when you might be adding additional mechanics to your game)

So there isn’t a solution to the problem I’m having and switching to a Rigidbody based movement system would stop this from happening?

You just need to kill any upwards velocity if your controller passes a grounded check, though likely only after a ‘grace period’ after they have initially jumped.

A character controller with inertia:

using UnityEngine;
public class SimpleController : MonoBehaviour
{
CharacterController cc;

    void Start()
    {
        cc = GetComponent<CharacterController>();
    }

    void Update()
    {
        Vector3 velocity=cc.velocity+(Physics.gravity*Time.deltaTime);  // Get the current "velocity" and add gravity
        if (Physics.SphereCast(transform.position,0.5f,Vector3.down,out RaycastHit hit,0.6f))  // CharacterController's isGrounded can be unreliable when jumping up slopes and so I'll use SphereCast instead
        {
            if (Input.GetButtonDown("Jump"))
                velocity.y+=5;
            else
            {
                velocity+=((transform.right*Input.GetAxisRaw("Horizontal"))+(transform.forward*Input.GetAxisRaw("Vertical"))).normalized*50*Time.deltaTime;
                velocity-=velocity*4*Time.deltaTime; // ground friction
                velocity.y=-6; // helps to keep the character pinned to the ground when going down slopes
            }
        }
        cc.Move(velocity * Time.deltaTime);
    }
}

There is a solution, but more problems like this will probably appear as you continue development, which is why I suggest switching to a rigidbody base.

While you will still need to fix this problem with a rigidbody base, it will be easier than continuing with the character controller.