Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Calcualte time in Jump

Discussion in 'Scripting' started by ShadowSharpened, Jun 8, 2022.

  1. ShadowSharpened

    ShadowSharpened

    Joined:
    Jul 23, 2017
    Posts:
    11
    Hey, I'm trying to create a game that every time you jump you jump higher. The problem with that is that I need to know the time that will last the jump. I have made this for the jump:


    Code (CSharp):
    1. public class Jump : MonoBehaviour
    2. {
    3.     private Rigidbody rb;
    4.     float jumpHeight = 2f;
    5.  
    6.  
    7. void Start()
    8. {
    9.     rb = GetComponent<Rigidbody>();
    10. }
    11.  
    12. void Update()
    13. {
    14.     if(IsGrounded() && Input.GetButtonDown("Jump"))
    15.     {
    16.         rb.velocity = Vector3.up * jumpHeight;
    17.         jumpHeight += 0.1f;
    18.     }
    19. }
    20.  
    21. public bool IsGrounded()
    22. {
    23.     return Physics.Raycast(transform.position, Vector3.down, 1.001f);
    24. }

    The problem with that is that I don't have control of the time you have been jumping, and for long jumps I would like to create a bar with the time.
    I have thought that I can use transform.Translate but also I don't have control of the time of the jump.
    I need the jump time because if the jump like 15 min and you close the app I need to instanciate the player on the correct position (jumping of falling).
    Do you have any idea on how I can do it?
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    You'll probably want to not use rigidbody physics and instead use a deterministic trajectory formula to calculate your character's position over time.

    That way you can save the timestamp of the player's last jump, and using the current time you can calculate where along the jump parabola they should be and place them there.

    https://www.omnicalculator.com/physics/projectile-motion#projectile-motion-equations

    https://physics.stackexchange.com/a/322110

    You could also do your jumps with a tween using DOTween perhaps, using the Rigibody DOJump function, and using the ManualUpdate feature, passing in the elapsed time since the jump and then resuming the tween.
     
    Last edited: Jun 8, 2022
    ShadowSharpened likes this.
  3. ShadowSharpened

    ShadowSharpened

    Joined:
    Jul 23, 2017
    Posts:
    11
    The problem with that is that the jump is only for the Y axie. I don't need X cord.
     
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    That just makes the math even easier. Check out the stack exchange answer, there is a separate formula for solving for Y.

    You will use that formula to calculate your Y position, and each jump will increase the initial velocity value. You will want to save the datetime of the last jump, and save the jump force of the last jump, so if the game closes you can use those values the next time the game opens.
     
    Last edited: Jun 8, 2022
  5. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    Here's a little example component for you. Put this on a sprite and drag the "time" field and you'll see it jump. It will be at the origin by default.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class JumpTest : MonoBehaviour
    4. {
    5.     public Vector3 initialPosition;
    6.     public float initialJumpForce = 10f;
    7.     public float time;
    8.  
    9.     private void OnValidate()
    10.     {
    11.         // keep time positive
    12.         time = Mathf.Max(0, time);
    13.  
    14.         transform.position = initialPosition + (Vector3.up * GetJumpOffset(initialJumpForce, time));
    15.     }
    16.  
    17.     private float GetJumpOffset(float jumpForce, float time)
    18.     {
    19.         float y = (0.5f * Physics2D.gravity.y * time * time) + (jumpForce * time);
    20.         // keep offset positive (without this it will fall forever as time increases)
    21.         y = Mathf.Max(0, y);
    22.         return y;
    23.     }
    24.  
    25.     private float GetJumpTotalDuration(float jumpForce)
    26.     {
    27.         return 2 * (jumpForce / Physics2D.gravity.y);
    28.     }
    29. }
    Hope it helps.
     
  6. ShadowSharpened

    ShadowSharpened

    Joined:
    Jul 23, 2017
    Posts:
    11
    Thanks!! And what do you think is better for the jump,
    this:
    Code (CSharp):
    1. rb.velocity = new Vector3(0, Mathf.Sqrt(-2.0f * Physics.gravity.y * jumpHeight));
    or this:
    Code (CSharp):
    1. rb.velocity = Vector3.up * jumpHeight;
     
  7. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    Well since you know you will always be jumping in one dimension, the simpler the better I say.
     
  8. ShadowSharpened

    ShadowSharpened

    Joined:
    Jul 23, 2017
    Posts:
    11
    So, GetJumpOffset() it's not working. If the jumpForce is 150f jump offset returns 145 and the player jumps 1145 units.
     
  9. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    GetJumpOffset takes JumpForce and Time.

    It's like saying "If I jumped with X amount of force, where would I be after Y amount of time?". So you will get a vertical offset based on where the character should be.

    Note that in my example I'm not using rigidbody velocity, because the idea is to have the exact position calculated based on time. (rigidbody uses the physics simulation to control the transform position)

    Again -- the idea is to not rely on rigidbody simulation here. The GetJumpOffset should return the exact Y offset for your character's jump.

    My example component works, so try to understand what I'm doing there and apply it to your code.

    If you need a rigidbody for collisions, you could do rb.MovePosition or something, but the idea is not to use the physics simulation, and instead to manually position the transform with the calculation based on time
     
    Last edited: Jun 14, 2022