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

Issue with rigidbody.AddForce inconsistent when jumping.

Discussion in 'Editor & General Support' started by carmine, Oct 23, 2014.

  1. carmine

    carmine

    Joined:
    Jan 4, 2012
    Posts:
    394
    Here is the code to control my player. On the first jump, it goes really high, jumps after that are normal behaves as I would expect. Every 5 or 6 jumps or so it changes to being high again and then is what I would expect. Any ideas?

    Code (csharp):
    1.  
    2. void FixedUpdate()
    3. {
    4.      if (this.transform.position.y < -10) this.transform.position = new Vector3(0, 2, 0);
    5.  
    6.     if (Input.GetKey(KeyCode.LeftArrow)) this.rigidbody.AddForce(-20, 0, 0, ForceMode.Force);
    7.     if (Input.GetKey(KeyCode.RightArrow)) this.rigidbody.AddForce(20, 0, 0, ForceMode.Force);
    8.  
    9.     if (touchingPlatform)
    10.     {
    11.          if (Input.GetKeyDown(KeyCode.Space))
    12.          {
    13.            this.rigidbody.AddForce(0, 12, 0, ForceMode.Impulse);
    14.          }
    15.     }
    16. }
    17.  
    Link to project (it's literally 1 .cs file and some cubes):
    https://www.dropbox.com/s/dlcoxnobztu5og1/JumpinCube.zip?dl=0
     
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,490
    You're not going to have good results calling Input.GetKeyDown inside FixedUpdate. You will miss jumps because Unity's input system does not update input in FixedUpdate, only Update. This will become very obvious when your frame rate is really high (if you disable VSync for example) because you will have potentially dozens of Update frames for every FixedUpdate that goes by. Your GetButtonDown will show as TRUE in only ONE of these Update frames, so by the time you get to FixedUpdate, it's false again.

    In the case of the super jump, the same thing is happening, only in reverse. GetButtonDown is returning True twice in a row doubling your force. This would mean that FixedUpdate ran twice before Update ran again. You can verify this by adding this line:

    Code (csharp):
    1.  
    2. if (Input.GetKeyDown(KeyCode.Space))
    3. {
    4.     Debug.Log("JUMP "+Time.time);
    5.     this.rigidbody.AddForce(0, 12, 0, ForceMode.Impulse);
    6. }
    7.  
    You will see "Jump" in your console twice during the times you get a super jump.

    The solution to this is to do your input in Update, not fixed update. Or use an input plugin that can handle getting input in FixedUpdate such as my Rewired input system.

    You could also try to filter out the extra jump ignoring the input issue. Your floor detection system using the trigger isn't preventing your cube from being grounded in the very next frame after you set your force mode, so it's allowing the extra TRUE returned by GetKeyDown to trigger the jump twice. If you set touchingPlatform = false immediately after the jump it will solve it. OnTriggerExit is not necessarily called immediately when you set the force mode because the cube may not have cleared the -0.01 Y extension distance of the trigger in that one frame of movement.
     
    Last edited: Oct 24, 2014
    path14 and Zealot2018 like this.