Search Unity

Question Trying to add Variable Jump Height Physics & Input

Discussion in 'Physics' started by mosulimo, Jan 26, 2021.

  1. mosulimo

    mosulimo

    Joined:
    Jan 18, 2021
    Posts:
    6
    Hey guys,

    I'm working on my jump physics for my 3rd Person Adventure game and so far the jumping works fine. I hit space the player jumps, but what I am looking for is to make him jump like Mario, with variable jump heights.

    I've followed some tutorials and had it working for a bit but after I've re-organized my inputs into Update and took them out of FixedUpdate, I ran into problems.

    Looking for a solution to this and get my player jumping based on how long the button is being held down. So far I'm using the JumpTimeCounter technique that sets a timer to see how long the button is held. Also, I'm trying to get him to only jump once, despite the button being held down.

    All help appreciated, thank you :)

    Code (CSharp):
    1.  
    2.  
    3. private void GetInput()
    4.     {
    5.         //Jumping Inputs
    6.         if (isGrounded && Input.GetButtonDown("Jump"))
    7.         {
    8.             isJumping = true;
    9.         }
    10.         else
    11.         {
    12.             isJumping = false;
    13.  
    14.         }
    15.  
    16.     }
    17.  
    18.  
    19.  
    20. private void Jump()
    21.     {
    22.         //jumping
    23.         if (isJumping)
    24.         {
    25.             jumpTimeCounter = jumpTime;
    26.             jumpTimeCounter -= Time.deltaTime;
    27.             Vector3 jumpVelocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z);
    28.             rb.velocity = jumpVelocity;
    29.         }
    30.         else { isJumping = false; }
    31.  
    32.     }
     
    Last edited: Jan 26, 2021
  2. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    Here is a quick example, the default values work for a 1kg rigidbody:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SimpleMove : MonoBehaviour
    6. {
    7.     [SerializeField] private float jumpForce = 1500;
    8.     [SerializeField] private float maxJumpForce = 500;
    9.  
    10.     private Rigidbody rb;
    11.     private float jumpTimer = 0;
    12.     private bool isGrounded = true;
    13.  
    14.     private void Start()
    15.     {
    16.         rb = GetComponent<Rigidbody>();
    17.     }
    18.  
    19.     private void Update()
    20.     {
    21.         GetInput();
    22.     }
    23.  
    24.     private void GetInput()
    25.     {
    26.         if (isGrounded)
    27.         {
    28.             if (Input.GetButton("Jump")) jumpTimer += Time.deltaTime;
    29.             if (Input.GetButtonUp("Jump")) Jump();
    30.         }
    31.     }
    32.  
    33.     private void Jump()
    34.     {
    35.         float force = jumpForce * jumpTimer;
    36.         if (force > maxJumpForce) force = maxJumpForce;
    37.         rb.AddForce(new Vector3(0, force, 0));
    38.         jumpTimer = 0;
    39.     }
    40.  
    41. }
    You need to code your own ground check in, as it is, it will always be true. Update isGrounded just before you check for input.
     
    mosulimo likes this.
  3. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    I should say that if you are going to add this to a more complex physics scene it would be a good idea to flag a jump as being required from the GetButtonUp and then check for it and apply the force in FixedUpdate. Whilst the previous code will work, it is good practice to apply forces in FixedUpdate, not Update.
     
    mosulimo likes this.
  4. mosulimo

    mosulimo

    Joined:
    Jan 18, 2021
    Posts:
    6
    Alright I'll figure out how to apply this. Thanks :)
     
  5. mosulimo

    mosulimo

    Joined:
    Jan 18, 2021
    Posts:
    6
    What I ended up doing instead was putting all of the JumpTimeCounter stuff in with the GetInput Function and it works perfectly. As you hold space, it adds +1 to the Counter and when it gets equal to the set JumpTime, it returns the jump false and resets the counter to 0.

    Code (CSharp):
    1.         //Jumping Inputs
    2.         if (isGrounded && Input.GetButtonDown("Jump"))
    3.         {
    4.             isJumping = true;
    5.         }
    6.         if (Input.GetButton("Jump") && jumpTimeCounter < jumpTime)
    7.         {
    8.             jumpTimeCounter += 1f;
    9.         }
    10.         else if (Input.GetButtonUp("Jump") || jumpTimeCounter >= jumpTime)
    11.         {
    12.             isJumping = false;
    13.             jumpTimeCounter = 0;
    14.         }