Search Unity

For those struggling with air control and velocity when jumping (Character Controller)

Discussion in 'Getting Started' started by BigBadSlug, Nov 19, 2019.

  1. BigBadSlug

    BigBadSlug

    Joined:
    Oct 15, 2019
    Posts:
    4
    Edit: Currently looking into a more reliable method for this, will update as soon as I've had time to implement and test.

    Hi all,

    I'm mainly posting this for those of you who have just picked up Unity and are trying to tweak your character controller to be exactly how you want it.

    My problem was with jumping and maintaining velocity, the player could walk around and jump just how I wanted, except that as soon as I let go of the input keys, it would stop dead mid-air and fall to the ground helplessly. I scoured google, the forums and any other resource I could to try and find a solution to this issue however nothing seemed to work or would result in ballistic jumping, loss of movement during a jump.

    Eventually, I stumbled across the following thread: https://gamedev.stackexchange.com/q...3d-c-can-t-move-through-the-air-while-jumping

    I gave Ilmari Karonen's second method a try, however this caused my player to speed up ridiculously when jumping, causing every jump to essentially be a bunny hop. After hours of trying to figure this out, I eventually came across a fix that I was satisfied with and felt that I had to share it just to save some people a few hours of frustration.

    Here is my First Person Controller code, excluding things such as user input handling:
    Code (CSharp):
    1.  
    2. //Variables for reference
    3. public float walkingSpeed = 6.0f;
    4. public float jumpHeight = 5.0f;
    5. public float gravity = 20.0f;
    6. private Vector3 movement;
    7. private Vector3 jumpVelocity = Vector3.zero;
    8. private float airSpeed = 4.0f;
    9. private float airFriction = 0.65f;
    10.  
    11. private void Update()
    12.     {
    13.         GetPlayerInput();
    14.  
    15.         movement = new Vector3(xInput, 0, zInput);
    16.         movement = transform.TransformDirection(movement);
    17.         if (controller.isGrounded)
    18.         {
    19.             controller.slopeLimit = 45.0f;
    20.             movement *= walkingSpeed;
    21.             if (Input.GetButton("Jump"))
    22.             {
    23.                 jumpVelocity = movement * airFriction;
    24.                 jumpVelocity.y = jumpHeight;
    25.                 controller.slopeLimit = 90.0f;
    26.             }
    27.             else
    28.             {
    29.                 jumpVelocity = Vector3.zero;
    30.             }
    31.         }
    32.         else
    33.         {
    34.             movement *= airSpeed;
    35.         }
    36.  
    37.         jumpVelocity.y -= gravity * Time.deltaTime;
    38.         controller.Move((movement + jumpVelocity) * Time.deltaTime);
    39.  
    40.     }
    Now by no means is this the optimal way to do this, I'm a novice at best but this seems to do the trick. Adding some air resistance to the initial jumpVelocity reference seems to work out the super speed.

    Please, feel free to correct me/critique this method. As mentioned I'm a novice and just wanted to put this out there for anyone else who had a hard time with this.

    Note:
    I deliberately avoided using a Rigidbody simply to bypass any bugginess that could come from it and chose to handle physics myself.

    Thanks all! I hope this helps some of you.
     
    Last edited: Nov 25, 2019
    KhuracKen likes this.
  2. zach_iduknow

    zach_iduknow

    Joined:
    Sep 6, 2019
    Posts:
    1
    This just saved my character controller, thank you!