How do I prevent the player from "air" movement while jumping using "THIS" script?

Hello all,

I am learning the C# at the moment and the script I am writing is all done by myself but I am NOT that good. In addition, I am comenting my own script the way I understood and if you see an error you can let me know if you will. Again, I am complete newb but here it is.

This script that I got here is allowing me to move, run and jump. However, while I am standing still and I jump I cannot move in any direction at all (like in real life) and that is what I do want. However, while I am walking or running (using the same script) and I jump my player will stop in the air in an instant (not like in real file). This is what I do NOT want. What I want is to retain the same think when jumping from idle but keep my momentum while walking/running and jumping (like in real life) but withouth being able to move my character left or right or any other direction.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
    [Header("Floats")]
    [SerializeField]
    [Tooltip("This is our player movement speed.")]
    private float movementSpeed = 1.0f;

    //Placeholder for jump velocity.
    private float jumpVelocity;

    [SerializeField]
    [Tooltip("Force of a jump going upwards.")]
    private float jumpForce = 17.0f;

    [SerializeField]
    [Tooltip("Player regular gravity (universal gravity).")]
    private float gravity = -9.8f;

    [SerializeField]
    [Tooltip("Force of a jump going downwards (falling).")]
    private float downForce = 24.0f;

    //Our CharacterController.
    private CharacterController _characterController;

    //Run it at the start.
    private void Start()
    {
        //This will get our CharacterController at the start of the game.
        _characterController = GetComponent<CharacterController>();
    }

    //Run it every frame.
    private void Update()
    {
        GetInput();
        PlayerJump();
        PlayerRun();
    }

    private void GetInput()
    {
        //If our cursor is locked then we can rotate our character and if not then we cannot.
        if (Cursor.lockState == CursorLockMode.None) return;

        //Get the axis input for our character.
        float horizontalAxis = Input.GetAxisRaw("Horizontal") * movementSpeed;
        float verticalAxis = Input.GetAxisRaw("Vertical") * movementSpeed;

        //We use vector3 to map out character movement.
        Vector3 movement = new Vector3(horizontalAxis, 0, verticalAxis);

        //Clamp the vector3 movement speed to be the same in all directions.
        movement = Vector3.ClampMagnitude(movement, movementSpeed);

        //This is our gravity.
        movement.y = gravity;

        //Multiply our movement speed with Time.deltaTime to make it frame per second independent.
        movement *= Time.deltaTime;

        //Transform the direction in order for our character be able to move (complex math).
        movement = transform.TransformDirection(movement);

        //An actual character movement.
        _characterController.Move(movement);
    }

    private void PlayerJump()
    {
        //If our cursor is locked then we can rotate our character and if not then we cannot.
        if (Cursor.lockState == CursorLockMode.None) return;

        //If our character is grounded then we can execute the following code.
        if (_characterController.isGrounded)
        {
            movementSpeed = 5.0f;
            //Our "jumpVelocity" stays the same and we are not applying the down-force as our character is not jumping yet.
            jumpVelocity = -downForce * Time.deltaTime;

            //get the input key/button for the jump.
            if (Input.GetButtonDown("Jump"))
            {
                //Convert "jumpVelocity" to "jumpForce".
                jumpVelocity = jumpForce;
            }
        }
        //If our character is not grounded then we can execute the following code.
        else if (!_characterController.isGrounded)
        {
            movementSpeed = 0.0f;
            //Now we are applying our down-force to get our player down as fast as possible.
            jumpVelocity -= downForce * Time.deltaTime;
        }

        //Creating a Vector3 to handle the jumping.
        Vector3 moveVector = new Vector3(0, jumpVelocity, 0);

        //An actual player jump.
        _characterController.Move(moveVector * Time.deltaTime);
    }

    private void PlayerRun()
    {
        //If our cursor is locked then we can rotate our character and if not then we cannot.
        if (Cursor.lockState == CursorLockMode.None) return;

        //If our character is grounded then we can execute the following code.
        if (_characterController.isGrounded)
        {
            if (Input.GetKey(KeyCode.LeftShift))
            {
                movementSpeed = 10.0f;
            }
            else if (Input.GetKeyUp(KeyCode.LeftShift))
            {
                movementSpeed = 5.0f;
            }
        }
    }
}

Could anyone kind enough let me know how this would work?

Thanks!
Regards,
AI

The problem is that you need to keep track of the players existing velocity and add the movement as acceleration. Then your player can maintain its velocity and you can control how much movement is applied on top of that (to prevent changing directions mid-air, etc)

Something like…

// deceleration. If you don't decelerate, your player will never stop!
velocity *= 0.5f;

// the way the deceleration is applied, it will never actually reach 0
// so set it to 0 if the velocity is less than a minimum threshold
if (velocity.magnitude < 0.01f) velocity = Vector3.zero;

// accelerate
velocity += movement;

_characterController.Move(velocity);

The way I’ve shown how to handle deceleration is very simplistic. You can do something more fancy to create a more realistic/controlled deceleration effect but that’s another question.

I’m just providing the idea here. This code is not going to work directly. It is up to you to understand how it should be applied in your code specifically.