Trouble getting framerate independency with Time.deltaTime

Hi all,
I’m having some problems when using the conventional method of making movement framerate independent. I’m using Time.deltaTime in Update() to compensate for slower framerate when adding or subtracting movement related values, but there seems to be something wrong with my code which makes my character jump in different y speed even though I’m multiplying the gravity with Time.deltaTime.

The code below is reduced to its core functionality. When the jump reaches apex the y value of the characters position varies quite a lot when the framerate is fluctuating.

void Update () {
		
		
		isGrounded = controller_.isGrounded;
	
		isJump = inputController_.GetIsJumping();
		if(isJump && isGrounded) {
			reachedApex = false;
			verticalSpeed_.y = junpStrength;
		}
		else if(!isGrounded) {
			if(verticalSpeed_.y < 0f && !reachedApex) {
				reachedApex = true;
				Debug.Log(transform.position.y); // Big differences in this value
			}
			verticalSpeed_.y -= gravity*Time.deltaTime;
		}
		else if(isGrounded) {
			verticalSpeed_.y = -gravity*Time.deltaTime;
		}
		CollisionFlags flags = controller_.Move(verticalSpeed_ * Time.deltaTime);
	}

Have I gotten this method all wrong or what?
Any thoughts would be much appreciated.

Thanks!

This might not be entirely applicable, but you are applying gravity in a wrong way!

As stated here (read it if you want an explanation)

You need to apply gravity half before and half after, otherwise jumping will vary with framerate. (especially low ones)

So instead of doing:

velocity -= Vector3(0, gravity, 0)*Time.deltaTime;
characterController.Move(velocity*Time.deltaTime);

You need to do:

velocity -= Vector3(0, gravity/2*Time.deltaTime, 0);
characterController.Move(velocity*Time.deltaTime);
velocity -= Vector3(0, gravity/2*Time.deltaTime, 0);

Hope this helps, if not I can just delete this answer :slight_smile:
Benproductions1

You have asked (I believe),

how to use .Move rather than setting the position.

To set the position:

transform.position.y =
StartingVelocity * (Time.time - _startTime)
- 0.5 * 9.8 * (Time.time - _startTime) * (Time.time - _startTime);

To use .Move:

newYValue = // same as above
.Move( Vector3(0, newYValue-transform.position.y, 0 ) );

NB, one of your control structures appears to be incorrect:

else if(!isGrounded) {...}
else if(isGrounded) {...}

Regarding your arithmetic as presented:

[8894-threelinebounce.zip|8894]


To animate the usual way:

transform.position.y =
StartingVelocity * (Time.time - _startTime)
- 0.5 * 9.8 * (Time.time - _startTime) * (Time.time - _startTime);

[8931-twodemos.zip|8931]

Note - try as Update, FixedUpdate, there is no difference.


Next, I wrote a run loop that happens at random times: “harsh demo”

You will see that it makes no difference.

Both projects are included in the previous link.


“having a hard time grasping the formula you just provided” x = x0 + v0 t + 1/2 g t2

eg explaination

You say “when the framerate is fluctuating” and “big difference” - these are pretty subjective. What numbers are you seeing, and what do you expect?

Your code is correct, but if you’re getting huge variations in framerate it’s quite possible for one frame to take so long to process that you miss part of the jump’s apex. For instance you could skip from +1u/s to -1u/s, completely missing the 0u/s speed, and ending up with your apex marked at the point where you had +/-1u/s (a lower point). There’s no reason for you to code around this in a video game (though it’s possible) - you want to get rid of the fluctuation instead.

You’ve probably already done this, but it’s a good idea to also go through your script and double-check that nothing else is modifying your vertical speed value. :slight_smile: