Search Unity

Question Help adding a double jump to the Unity Starter Assets script

Discussion in 'Scripting' started by omery15, Jul 12, 2021.

  1. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    So I've ditched my simple player controller script in favor of unity's because I was having a bug were my character would stop responding at times and continue moving in a straight line unless I pause and unpause the game.

    Long story short, I've adopted unity's starter assets and I'm trying to add a double jump functionality, but the script is a little too complex for me right now.

    My simple script for double jumping was
    Code (CSharp):
    1.         if(jump.triggered && isGrounded)
    2.         {
    3.             canDoubleJump = true;
    4.             playerVelocity.y = Mathf.Sqrt(jumpHeight * -2.0f * gravityValue);
    5.         }
    6.  
    7.         else //this allows player to double jump
    8.             {  
    9.                 if(jump.triggered && canDoubleJump)
    10.                 {
    11.                     playerVelocity.y = Mathf.Sqrt(jumpHeight * -2.0f * gravityValue) * doubleJumpMultiplier;
    12.                     canDoubleJump = false;
    13.                 }
    14.             }
    Whereas unity's TPC script for jumping is:
    Code (CSharp):
    1.         private void JumpAndGravity()
    2.         {
    3.             if (Grounded)
    4.             {
    5.                 // reset the fall timeout timer
    6.                 _fallTimeoutDelta = FallTimeout;
    7.  
    8.                 // update animator if using character
    9.                 if (_hasAnimator)
    10.                 {
    11.                     _animator.SetBool(_animIDJump, false);
    12.                     _animator.SetBool(_animIDFreeFall, false);
    13.                 }
    14.  
    15.                 // stop our velocity dropping infinitely when grounded
    16.                 if (_verticalVelocity < 0.0f)
    17.                 {
    18.                     _verticalVelocity = -2f;
    19.                 }
    20.  
    21.                 // Jump
    22.                 if (_input.jump && _jumpTimeoutDelta <= 0.0f)
    23.                 {
    24.                     // the square root of H * -2 * G = how much velocity needed to reach desired height
    25.                     _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
    26.  
    27.                     // update animator if using character
    28.                     if (_hasAnimator)
    29.                     {
    30.                         _animator.SetBool(_animIDJump, true);
    31.                     }
    32.                 }
    33.  
    34.                 // jump timeout
    35.                 if (_jumpTimeoutDelta >= 0.0f)
    36.                 {
    37.                     _jumpTimeoutDelta -= Time.deltaTime;
    38.                 }
    39.             }
    40.             else
    41.             {
    42.                 // reset the jump timeout timer
    43.                 _jumpTimeoutDelta = JumpTimeout;
    44.  
    45.                 // fall timeout
    46.                 if (_fallTimeoutDelta >= 0.0f)
    47.                 {
    48.                     _fallTimeoutDelta -= Time.deltaTime;
    49.                 }
    50.                 else
    51.                 {
    52.                     // update animator if using character
    53.                     if (_hasAnimator)
    54.                     {
    55.                         _animator.SetBool(_animIDFreeFall, true);
    56.                     }
    57.                 }
    58.  
    59.                 // if we are not grounded, do not jump
    60.                 _input.jump = false;
    61.             }
    62.  
    63.             // apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
    64.             if (_verticalVelocity < _terminalVelocity)
    65.             {
    66.                 _verticalVelocity += Gravity * Time.deltaTime;
    67.             }
    68.         }
    Help would be appreciated :)
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Just replace the _input.jump = false part with a simple if hasDoubleJump -> then no has double jump anymore, otherwise _input.jump = false, and you can reset this bool at the srart of the if (Grounded) branch
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    Exactly what gorbit suggests above, OR... if you want to see other approaches, go check out some tutorials on double jump so you understand the condition-test-action flow that gorbit listed above.
     
  4. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Thanks for the response. I tried to follow your approach the best way I was able to understand, but I didn't know when to exactly call this code. The best I can come up with is this, but the character double jumps from a single press of jump key.

    Code (CSharp):
    1.         private void JumpAndGravity()
    2.         {
    3.             if (Grounded)
    4.             {
    5.                 // reset the fall timeout timer
    6.                 _fallTimeoutDelta = FallTimeout;
    7.                 canDoubleJump = true;
    8.  
    9.                 // update animator if using character
    10.                 if (_hasAnimator)
    11.                 {
    12.                     _animator.SetBool(_animIDJump, false);
    13.                     _animator.SetBool(_animIDFreeFall, false);
    14.                 }
    15.  
    16.                 // stop our velocity dropping infinitely when grounded
    17.                 if (_verticalVelocity < 0.0f)
    18.                 {
    19.                     _verticalVelocity = -2f;
    20.                 }
    21.  
    22.                 // Jump
    23.                 if (_input.jump && _jumpTimeoutDelta <= 0.0f)
    24.                 {
    25.                     // the square root of H * -2 * G = how much velocity needed to reach desired height
    26.                     _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
    27.  
    28.                     // update animator if using character
    29.                     if (_hasAnimator)
    30.                     {
    31.                         _animator.SetBool(_animIDJump, true);
    32.                     }
    33.                 }
    34.  
    35.                 else if (_input.jump && canDoubleJump)
    36.  
    37.                     {
    38.  
    39.                         _verticalVelocity = Mathf.Sqrt(JumpHeight * -2.0f * Gravity) * doubleJumpMultiplier;
    40.  
    41.                         canDoubleJump = false;
    42.  
    43.                     }
    44.  
    45.                 // jump timeout
    46.                 if (_jumpTimeoutDelta >= 0.0f)
    47.                 {
    48.                     _jumpTimeoutDelta -= Time.deltaTime;
    49.                 }
    50.             }
    51.             else
    52.             {
    53.                 // reset the jump timeout timer
    54.                 _jumpTimeoutDelta = JumpTimeout;
    55.  
    56.                 // fall timeout
    57.                 if (_fallTimeoutDelta >= 0.0f)
    58.                 {
    59.                     _fallTimeoutDelta -= Time.deltaTime;
    60.                 }
    61.                 else
    62.                 {
    63.                     // update animator if using character
    64.                     if (_hasAnimator)
    65.                     {
    66.                         _animator.SetBool(_animIDFreeFall, true);
    67.                     }
    68.                 }
    69.  
    70.                 // if we are not grounded, do not jump
    71.          
    72.                 if(canDoubleJump == false)
    73.  
    74.                 {
    75.  
    76.                     _input.jump = false;
    77.  
    78.                 }
    79.             }
    80.  
    81.             // apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
    82.             if (_verticalVelocity < _terminalVelocity)
    83.             {
    84.                 _verticalVelocity += Gravity * Time.deltaTime;
    85.             }
    86.         }
     
    Last edited: Jul 12, 2021
  5. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    If you have any tutorials that you recommend I would love to have a look at them.

    I got and understood the first simple method I shared from watching tutorials but the fall timeout and jump timeout have really thrown me off. I'm not sure if they are forcing the player down or if they are preventing the double jump all together.

    And I tried to find something related to explaining the follow of the TPC in the starter assets but it seems that it's still relatively new and little has been created in that area.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    I have no idea what that even means.

    How would you describe each of those effects?

    - conditions to trigger
    - results of triggering
    - user interaction?
    - user indication?
     
  7. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    - conditions to trigger: certain conditions that when met will result in an action
    - results of triggering: if said action is done, so and so will happen
    - user interaction?: if user provided a specific input then do so and so
    - user indication? I have no idea
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    You cannot make something until you can describe it.

    Go find a game that has this "fall timeout" feature and "jump timeout" feature, then type into Youtube something like

    unity make game XXXX

    ...where XXXX is the game you find with the above undefined features that I have never heard of.
     
  9. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Oh my bad I think I misunderstood your question.

    So these fall timeout and jump timeout are included in the latest starter assets by unity, they are a part of the ThirdPersonController class and are included in the JumpAndGravity() method.

    I decided to use the starter assets because I figured that code would be bug free and I would probably run better than the simple code I had written.

    What I'm looking for is a simple double jump mechanic to embed into this code, basically pressing jump a second time will cause the player to make another mid air jump.
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    Okay, gotcha. So what you need to do is decide a course of action:

    1- continue using the standard assets and figure out what is causing you to say:

    or:

    2- go on youtube as I suggested above and try any one of the 27 million double jump tutorials out there to roll your own jump / doublejump script.

    If you choose step 1, here are some useful tips to help figure out what is happening. Remember, staring at functioning code someone else wrote isn't a thing, so you have to run it and figure out what it is doing.

    To help gain more insight into how this 'fall timeout' and 'jump timeout' are 'throwing you off,' I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
  11. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    I already have a working script for double jump, but I am having a hard time including it in this ready made controller, I just cant seem to find the proper place it have it
     
  12. Pixelith

    Pixelith

    Joined:
    Jun 24, 2014
    Posts:
    578
    Honestly I've always liked the number jumps approach more. So an int that checks how many jumps you have, and every jump subtracts one. Can't jump if it equals zero, and being on the ground resets this number to a maxJumps int value.

    That way in your case you could just specify 2 jumps and now you have double jumps. Wanna add a triple jump upgrade? Just change it to three.

    This way you won't need tons of if statements either.
     
  13. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Yea thanks for the advice, I considered using the max jumps integer approach and might end up switching to it, my issue right now is I don't know how to change the code above (the one included in the starter assets) in a way that will allow me to double jump