Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Framerate independent jump

Discussion in 'Scripting' started by KhenaB, Jul 13, 2018.

  1. KhenaB

    KhenaB

    Joined:
    Aug 21, 2014
    Posts:
    223
    Hey,

    I'm trying to build a raycast based character controller and I can't make the Jump method framerate independent no matter what I try, here is a test project from one of the tutorials I've been following, which is also not framerate independent.

    Just press play, move with arrows or wasd and jump with spacebar, and try to clear the pillar. Now change the public variable "Target Framerate" on the Player script from 30 to 60+ and try again. Why is the jump affected by the framerate in this scenario?

    Thanks
     

    Attached Files:

  2. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,688
    It's better to post your code rather than requiring a download.
    I noticed this line in the player:
    velocity.y += gravity * Time.deltaTime;

    A compiler will do multiplication before addition, so I think you want:
    (velocity.y += gravity) * Time.deltaTime;

    I didn't try it or anything.
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    630
    Ditto on the posting of the relevant code, not a whole project.

    Anyway, so that others can assist, here's that code of yours:

    Code (CSharp):
    1. public class Player : MonoBehaviour {
    2.  
    3.     public int targetFramerate = 30;
    4.  
    5.     public float moveSpeed = 6;
    6.     public float jumpVelocity = 6;
    7.     public float gravity = -25;
    8.  
    9.     Controller2D controller;
    10.  
    11.     void Start()
    12.     {
    13.         controller = GetComponent<Controller2D> ();
    14.     }
    15.  
    16.     void Update()
    17.     {
    18.         Application.targetFrameRate = targetFramerate;
    19.  
    20.         if (controller.collisions.above || controller.collisions.below)
    21.             velocity.y = 0;
    22.  
    23.         Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical"));
    24.  
    25.         //JUMP
    26.         if (Input.GetKeyDown (KeyCode.Space) && controller.collisions.below)
    27.             velocity.y = jumpVelocity;
    28.  
    29.         //GRAVITY
    30.         velocity.y += gravity * Time.deltaTime;
    31.  
    32.         //MOVE
    33.         velocity.x = input.x * moveSpeed;
    34.        
    35.     }
    36. }
    Some reactions:

    It looks like you're applying gravity even when grounded. Maybe you shouldn't be doing that?

    As for the framerate issue, my hunch is that it's because you're multiplying by Time.deltaTime twice. I'd need to do some math on that to verify it, but it seems weird. You're reducing the velocity by a deltaTime-based amount, and then moving a deltaTime-based amount. Perhaps its compounding the time in a weird way.

    Maybe it should be like this?

    Code (CSharp):
    1.         //JUMP
    2.         if (Input.GetKeyDown (KeyCode.Space) && controller.collisions.below)
    3.             velocity.y = jumpVelocity;
    4.  
    5.  
    6.         //MOVE
    7.         velocity.x = input.x * moveSpeed;
    8.  
    9.         velocity *= Time.deltaTime;
    10.  
    11.         //GRAVITY
    12.         velocity.y += gravity * Time.deltaTime;
    13.      
    14.         controller.Move (velocity);
     
  4. KhenaB

    KhenaB

    Joined:
    Aug 21, 2014
    Posts:
    223
    I've figured out why this is happening thanks to Eno-Khaon on Unity Answers

    It's easier to understand by looking at it visually so I suggest taking a look at what he posted, basically the more frames, the smaller the subtracted amount will be (because it's multiplied every frame by delta) so the higher it will jump.

    I'll keep looking for a solution

    @dgoyette thanks for posting the code
     
  5. KhenaB

    KhenaB

    Joined:
    Aug 21, 2014
    Posts:
    223