Jumping with slight air control while retaining velocity

Hi all,

Hopefully I can find a solution here as this has been driving me mad. I’m creating an FPS Controller, movement has been going great however I’ve hit a problem with jumping and maintaining velocity.

When my character jumps, it behaves as expected. Moving forward and jumping moves at a reasonable speed compared to the characters walking speed. However if I stop moving forward whilst mid air, the character stops on a dime mid air. I want the character to continue moving in the direction they were jumping in regardless of the player stopping movement input. This itself is straightforward but I also want the player to have some slight air control, similar in the sense of games like Overwatch or Halo.

I’ve gotten a temporary solution, however jumping seems to take the player velocity and THEN add the movement on top, making the player seem to leap further and faster than i’d expect.

Here is my code currently:

public float walkingSpeed = 6.0f;
public float jumpHeight = 5.0f;
public float gravity = 20.0f;
private Vector3 movement;
private Vector3 jumpVelocity = Vector3.zero;
private float airSpeed = 4.0f;
private float airFriction = 0.65f;
private void Update()
        movement = new Vector3(xInput, 0, zInput);
        movement = transform.TransformDirection(movement);
        if (controller.isGrounded)
            controller.slopeLimit = 45.0f;
            movement *= walkingSpeed;
            if (Input.GetButton("Jump"))
                jumpVelocity = movement * airFriction;
                jumpVelocity.y = jumpHeight;
                controller.slopeLimit = 90.0f;
                jumpVelocity = Vector3.zero;
            movement *= airSpeed;
        jumpVelocity.y -= gravity * Time.deltaTime;
        controller.Move((movement + jumpVelocity) * Time.deltaTime);

I’ve left out the movement, but it is a simple Input.GetAxisRaw(Horizontal) etc etc.

Is there anyway I can achieve this effect without the player rocketing ahead whilst moving in mid air?


There’s no two ways about it, you need to store the previous velocity.

You already do so with the jumping velocity, simply rename that velocity. If your player is on the ground, simply change the x and z value to your input. If the player is not on the ground, simply add the x and z value of the input to the velocity, multiplied by Time.deltaTime and by a small airSpeedMultiplier.

To prevent the player from skyrocketing during flight, simply check if their lateral velocity is already greater than their maximum ground velocity before adding an input that would increase it.