fixedDeltaTime changes how physics work

I have two scripts. One for gravity, and one for a tornado that works like negative gravity while the player is inside it. The player thus bounces on top of it. However, the bounce becomes smaller if I decrease Time.fixedDeltaTime, and bigger if I increase it. Here’s the code:

Gravity

_entityRigidbody.velocity += direction.normalized * velocity * Time.fixedDeltaTime * 10;

Tornado

rigidbody.velocity += Vector3.up * velocity * Time.fixedDeltaTime * 10;

I made sure that both were called exactly once per FixedUpdate. Is there a way to eliminate this strange phenomenon?

Visualization:

fixedDeltaTime unmodified:
6726670--774103--upload_2021-1-15_2-40-58.png

fixedDeltaTime * 0.1
6726670--774106--upload_2021-1-15_2-42-8.png

fixedDeltaTime * 10
6726670--774109--upload_2021-1-15_2-42-53.png

Also, the bigger fixedDeltaTime, the longer the player is inside the tornado.

So, you are saying that

    rigidbody.velocity += Vector3.up * velocity * Time.fixedDeltaTime * 10;

the bounce is strongest than

    rigidbody.velocity += Vector3.up * velocity * Time.fixedDeltaTime * 0.1f;

Is that what you mean?

This is completly normal. You are not changing the fixedDeltaTime, you are changing a constant, so the first one is 100x “strongest” than the second one.

Your formula is this one rearranged

 rigidbody.velocity = rigidbody.velocity + (K*velocity*Time.fixedDeltaTime)*Vector3.up

In the first case, Kvelocity = 10velocity. In the second one, kvelocity = 0.1velocity.

Your are not affecting the time step, you are multiplying your formula by a factor
If you want to change your fixedDeltaTime, change it here:

Just remove Time.fixedDeltaTime from the calculations.Velocity is a time-independent magnitude in this context. Simply specify the desired velocity in m/s and the physics engine will move the rigidbody at that velocity, no matter the actual fixed deltatime value.

Additional note 1: When you need to read the delta time it is advised to use Time.deltaTime instead of Time.fixedDeltaTime, also within FixedUpdate. Time.deltaTime yields the correct value depending on where you are reading it from. See: https://docs.unity3d.com/ScriptReference/Time-fixedDeltaTime.html

Additional note 2: Typically it’s better to use AddForce with ForceMode.VelocityChange instead of modifying the velocity directly. Modifying Rigidbody.velocity overrides the calculations from the physics engine, which may cause other adverse effects. See an example here:
https://discussions.unity.com/t/759159/11

No I am.

My function to update time

public void UpdateTimeScale()
    {
        float tmp = currentTimeScale;
        Time.timeScale = tmp;

        if (affectFixedUpdate)
        {
            Time.fixedDeltaTime = initialFixedDeltaTime * tmp;
            Time.maximumDeltaTime = initialMaximumDeltaTime * tmp;
        }
    }

The reason why I am also changing fixedDeltaTime is because otherwise have fun playing a game with like 20 ticks per second. If you want to slow down time for your player, you have to change this.

I am specifically avoiding AddForce (also AddTorque btw), since they turned out to be quite buggy sometimes. I mean if you know how rotations and vectors work there’s little reason to not just manage the forces on your own.

After some testing my guess is that because the time steps are so little, the forces negate themselves earlier when they are more often applied at smaller magnitudes. I guess it’s impossible to negate this phenomenon, but you can try and keep it reasonably low at low values for time.fixedDeltaTime. But that would probably require me to change how my game works, and is sure to bring other unwanted side effects :frowning:

No, and indeed slowing down the time for the player using Time.fixedDeltaTime is a bad idea.

Just leave Time.fixedDeltaTime untouched (0.02), remove it from your calculations, set standard velocities in m/s, and use Time.timeScale to adjust the player time.

  • Time.timeScale = 1.0f is normal time
  • Time.timeScale = 0.1f is very slow time (1/10 of normal time)
  • Time.timeScale = 2.0f is twice as fast of normal time

Physics, velocity and everything else will work correctly.

I make extensive use of these in my realistic simulations and never found any bug. But changing Time.fixedDeltaTime dynamically surely can make them behave like they’re buggy.

Collisions and frictions. Those are really difficult to resolve by yourself realistically without almost re-writing the physics engine.

Moreover, it turns out that setting Rigidbody.velocity directly interferes with the physics engine, as you’re overwriting the results from the physics solver. This causes another set of side effects. But using AddForce with ForceMode.VelocityChange allows the engine to apply your velocity and resolve the physics correctly at the same time, including collisions, frictions, etc.

Imma post a video how it looks like and then you be the judge. Maybe you can more easily understand my problem based on that.

EDIT: Nvm, too lazy to do that now.

Seems like I need to reconsider this one.

Yes but no cuz I’m doing something very minimalistic and nothing realistic.

1 Like