Do I understand Time.deltaTime?

I have some simple code to rotate an object and I’ve had it suggested to me that it should really be using Time.deltaTime in order for it to behave smoothly. I understand that Time.deltaTime makes this frame rate independent and essential converts number into a per second calculation.

I feel like I haven’t got my head around exactly what the difference between having it and not having it is and I’m hoping someone can clarify.

For example, this original line used to push an object:

currentForcePerFrame = 300f;
rb.AddForce(transform.forward * currentForcePerFrame);

…was changed to include Time.deltaTime. To achieve the same result as the previous code the force value had to be significantly increased:

currentForcePerFrame = 30000f;
rb.AddForce(transform.forward * currentForcePerFrame * Time.deltaTime);

Note that separate code was created to cap the amount of force added per frame.

I thought I had it straight what was happening here but I’m now trying to apply the same thing to code that rotates my object and I’m having trouble. This rotates properly:

torqueForce = 5.0f;
rb.AddTorque (transform.up * torqueForce * moveHorizontal, ForceMode.Force);

…but adding Time.deltaTime to this line makes the rotation speed very very low and increasing the torque value does not increase the speed:

torqueForce = 500.0f;
rb.AddTorque (transform.up * torqueForce * moveHorizontal * Time.deltaTime, ForceMode.Force);

I’m assuming that either I’m misunderstanding Time.deltaTime or something else is impacting on my rotation like angularDrag or maxAngularVelocity.

Sincere apologies if I’m just being really thick here. I did search for questions on Time.deltaTime but could not find an answer.

deltaTime contains the amount of time that has passed since the last call of Update() in seconds. So if your game is running at a constant 60FPS deltaTime would be 1 second / 60 = 0.016666…
Which means when you multiply a value by deltaTime the semantics change from “Move this by 1 unity per frame” to “Move this by 1 unit per second”.
In the first case the movement speed would be dependent on how fast your game is running, if FPS are not capped and someone had a really good PC everything would move/rotate much faster, since Update() gets called way more often than on low FPS, and once FPS drops everything would slow down.

If you want something to change the same amount every second regardless of how much FPS you have, you multiply it by deltaTime. The higher the FPS, the lower deltaTime will be and the smaller the movement will be PER FRAME, so that after 1 second the movement will be the same distance.

For instance, let’s say you have a cube and want to move it 2 units per second, at 10FPS deltaTime would be 0.1, 2 x 0.1 = 0.2. So it moves 0.2 unity per frame and since it’s running at 10FPS, Update() will be called 10 times per second, so moving it 10 times 0.2 units will result in a total movement of 2 units after one second, which is what we want. If someone else plays the same scene but has 60FPS, deltaTime will be 0.016, Update() will be called 60 times per second so 2 x 0.016 will move the cube 0.032 units per frame, which also results in a movement of 2 unity after each second.

So the reason why you have to increase your values is because by multiplying it by deltaTime you are essentially dividing it by whatever FPS you’re app is running at. Multiplying by 0.016 (deltaTime if FPS are 60) is the same as dividing by 60.

Time.deltaTime is the time that elapsed since the last frame (multiplied by Time.timeScale). As the frame rate (FPS) is usually not constant, Time.deltaTime also varies from frame to frame (at 60 FPS the value should be around 1f / 60 = 0.016f). In every frame Update() is called, so if you have some logic that does things every frame, then to account for a variable frame rate, you should include Time.deltaTime into that calculation.

As Time.deltaTime is such a small value, it drastically scales down other values.

However, physics changes should be done in FixedUpdate(), which is called at a fixed interval, Time.fixedDeltaTime, which by default is 0.02f (can be changed in Edit → Project Settings → Time → Fixed Timestep). Physics is updated at a fixed rate, because otherwise physics simulation would be (even) less reliable.

So in your case, you should have the code you posted in FixedUpdate(), and not use Time.deltaTime at all, and only use Time.fixedDeltaTime if you want to apply velocity (probably would need to combine with ForceMode.VelocityChange as well).

If these physics changes are done in FixedUpdate() is there any need to use time at all?

I’m unclear on why it’s necessary. The FixedUpdate() Scripting reference gives an example of adding force in FixedUpdate() without adding Time.fixedDeltaTime.