Search Unity

Question How can I make a better jump curve?

Discussion in 'Scripting' started by imaginereadingthis, Jan 9, 2023.

  1. imaginereadingthis

    imaginereadingthis

    Joined:
    Jul 25, 2020
    Posts:
    97
    Hello everyone,

    I'm working on a very basic first-person movement system, and I'm having a problem with the jump. As it is, the jump feels okay. But there's something missing. I noticed that jumping up feels more accelerated and sudden than falling down. I used a trail to illustrate what I mean:
    upload_2023-1-8_22-10-27.png
    As you can see, the jumping up part (on the right) is much less linear than the falling down part. I want to change this so that jumping up will be more gradual (but not completely linear) and falling down will feel faster. Visually speaking, I'd like to reverse the curve above and stretch it out a bit. Kinda like this (forgive me for my horrendous art skills):
    upload_2023-1-8_22-26-4.png

    Here's the code from my jump function:
    Code (CSharp):
    1. void Jump() {
    2.         if (Input.GetButtonDown("Jump") && grounded) {
    3.             rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
    4.             rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
    5.         } else if (rb.velocity.y < 0f) {
    6.             rb.velocity += Vector3.up * Physics.gravity.y * fallMultiplier * Time.deltaTime;
    7.         }
    8. }
    Do you guys have any ideas?
     
    Last edited: Jan 9, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,866
    Best bet is to look at various easing in and easing out and similar algorithms that are easily search-able on the internet. And the end of the day it's a single value that goes from positive to negative while you're off the ground, you just need to manipulate it in the right manner.

    Notably this means you won't be able to get away with Rigbidbody.AddForce alone. You'll likely end up solely manipulating the
    .velocity
    property of the Rigidbody.
     
    imaginereadingthis likes this.
  3. imaginereadingthis

    imaginereadingthis

    Joined:
    Jul 25, 2020
    Posts:
    97
    UPDATE:

    I ended up simulating a fake sense of downward acceleration by using a coroutine and making a few checks. The code is pretty ugly, but if anyone is stuck with the same issue, this is what I did:


    Code (CSharp):
    1. void Jump() {
    2.         if (Input.GetButtonDown("Jump") && grounded) {
    3.             // Reset y velocity and jump
    4.             rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
    5.             rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
    6.         } else if (rb.velocity.y < 0f) {
    7.             // Fall faster
    8.             rb.velocity += Vector3.up * Physics.gravity.y * fallMultiplier * Time.deltaTime;
    9.             if (rb.velocity.y > terminalVelocity) {
    10.                 StartCoroutine(FallFaster());
    11.             }
    12.         } else if (rb.velocity.y >= 0f) {
    13.             // Reset fall multiplier
    14.             fallMultiplier = originalFallMultiplier;
    15.         }
    16.     }
    17.  
    18.     // Fake acceleration
    19.     IEnumerator FallFaster() {
    20.         yield return new WaitForSeconds(0.1f);
    21.         fallMultiplier += fallAccelerationRate;
    22.     }