[unity] fixedDeltaTime + physics problems?

edited in Questions and Answers
I'm using a very simple thing to make the game slow down and speed up, but it does really weird things to my physics - I've made completely sure that I've got no other forces acting on my game in code, and somehow, when I use these code to go slow and speed back up, some mysterious force acts on my objects (a bunch of jointed things).

Slow:
Time.timeScale = 0.05f;
Time.fixedDeltaTime = Time.timeScale * 0.02f;

Return to normal speed:
Time.timeScale = 1f;
Time.fixedDeltaTime = Time.timeScale * 0.02f;

I know it's the fixedDeltaTime line's problem, because if I take those lines out, the physics work fine. But the visual update becomes choppy.

What's going on?????? :X

Comments

  • Isn't fixedDeltaTime the time since the last frame? Shouldn't it be fixedTimeScale or something?
  • What are you doing in your fixed update? It might be that you have to scale your calculations by fixedDeltaTime (the way that you would with the varying Time.deltaTime).
  • What are you doing in your fixed update? It might be that you have to scale your calculations by fixedDeltaTime (the way that you would with the varying Time.deltaTime).
    The thing is I was actually doing *nothing* with physics or anything anywhere else - the wonkiness comes from the rigidbodies and joints and things, natural forces.

    I had left it to be choppy but that's not ideal. I think that's okay for now but I really would like to know what the problem is :/
  • Maybe in the rigidbodies you can set them to interpolate to smooth things out?
  • Maybe in the rigidbodies you can set them to interpolate to smooth things out?
    Thanks for that suggestion... Ran through all my rigidbodies and changed them to interpolate, and.... Nope, still the same...
  • I just tried it on one of my projects here and I don't see choppiness. :/ I can't think of anything else to try.
  • The choppiness is when I implement the Time.timeScale change without changing the Time.fixedDeltaTime with Time.fixedDeltaTime = Time.timeScale * 0.02f;

    If I do implement the Time.fixedDeltaTime change then mysterious forces start affecting my stuff...
  • Actually I just tried something - upped the physics solver iteration from the default 6 to 12 then to 18............ I think that worked... Or at least it minimised the problem enough that I think it's okay now. Hmmmm.
  • So that didn't actually fix it... I've gone back to choppiness, will have to accept it for the time being :)
  • Hey @Tuism. Instead of updating the physics timestep, which should probably not be needed, have you tried using LateUpdate for anything that is visuals related?
  • The issue has nothing to do with any code I have - I started with clean code that didn't do anything to do with physics, built a bunch of stuff in joints, and applied the slow-time code as described above.

    LateUpdate has to do with when things get updated. I'm trying to get a slow-motion effect on everything, and I don't see what LateUpdate has to do with achieving that?
  • Try this for yourself: Make a new scene, join things with joints, and set Time.deltaTime to 0.1f. You'll see everything being slowed down but things become frame-by-frame-by-frame choppy. Then add "Time.fixedDeltaTime = Time.timeScale * 0.02f;" to it and you'll see it smooth out.

    I'm having trouble because the behaviour I observe in non-code generated physics are different between when the second line (Time.fixedDeltaTime = Time.timeScale * 0.02f;) is in effect or not. In theory the behaviour should be the same but slower, but instead I'm getting wonky forces that I didn't apply.
  • OK.

    So I have tried this and I do not see the choppiness you described above.

    Just a note: when you return to "normal" time you should set fixedDeltaTime back to its "default"

    Time.fixedDeltaTime = 0.02f;

    i.e. no need to multiply it by anything.
  • Maybe your Time.fixedDeltaTime is too low, in slow motion it will update physics every 0.001 (seconds?) that's every millisecond, can you try and make your slow motion a bit higher and see if that changes anything?
  • Okay, so what you're doing is correct. Without adjusting the fixed time step, you are only getting one physics update per several frames, ergo choppiness:

    TimeStep = 1
    Update 16ms
    Physics 20ms
    Update 32ms
    Physics 40ms etc

    Timestep = 0.25 without adjusting Time.fixedDeltaTime
    Update Realtime Time 16ms Virtual Time 4ms
    Update Realtime Time 32ms Virtual Time 8ms
    Update Realtime Time 48ms Virtual Time 12ms
    Update Realtime Time 64ms Virtual Time 16ms
    Update Realtime Time 80ms Virtual Time 20ms
    Physics 20ms
    Update Realtime Time 96ms Virtual Time 24ms

    What is more interesting it the weird forces you're seeing when you set fixedDeltaTime. Bear in mind if the physics time step is higher, you're getting a "more" accurate physics simulation as it's being integrated more often, and therefore it won't be EXACTLY the same as when it's running full speed. But I wouldn't expect to be seeing phantom forces. Perhaps you could post a gif of what's happening that shouldn't be happening?
  • Damn the semantics, let me rephrase.

    By lowering the Time.fixedDeltaTime to 0.001 seconds, during slow motion, you are increasing the physics update to 1000 updates per second. At 60fps the update loop runs at ~16ms, which means in your current slow motion mode, you are updating the physics 16x per frame. I'm not sure how much physics you have in there, but I doubt 1ms is enough time to calculate anything substantial. Also, IIRC the physics updates are handled with an interrupt and having it happen every 1ms, your own code outside the fixed update function will be interrupted many times per frame.
  • Okay so, I still have no idea what's happening, but Ruan suggested something on twitter and it alleviates a lot of the problem - there are still unknown forces acting on the system but it's really a lot less pronounced now. What he suggested was:

    Put this in LateUpdate:
    Time.timeScale = Mathf.MoveTowards(Time.timeScale, targetTimescale, Time.unscaledDeltaTime * 3f);

    And change targetTimeScale in Update as normal, along with Time.fixedDeltaTime = Time.timeScale * 0.02f;

    My latest version works well enough with this :D
  • edited
    I'm still curious what the unknown forces are. I'd expect the code you supplied originally to work perfectly fine.

    I tried scaling down the timescale to 0.05 and the fixeddeltatime accordingly in my physics cricket game, and the only difference I noticed was that the chains of joints seemed slightly stiffer, like they had extra angular drag on them (and of course everything was moving super slowly and smoothly). There were no phantom forces, and the scene had a few dozen joints in it (it had two cricketeers and some ropes hanging off of them).
  • I suppose it wasn't so much "phantom forces" but a really complicated set of joints and such had forces that were exaggerated. Danny explained it to me as many tiny collisions and forces acting on each other in proportionally larger ways when there are more steps in the same given time because of the slow down. I think that's what he meant. So the only way to really have a simulation that works the same way slow as fast is to avoid having large amounts of tiny collisions - which was unavoidable in the complex jointed system I had.

    I *think* that's what he meant :)
    Thanked by 1EvanGreenwood
  • In my experience, complex physics simulations simply do not like having the fixed timestep being changed while the game is running. In your case it sounds like setting timestep to 0.01 (or even lower!) from the start and then just changing timescale should be fine, keeping in mind that all VR games run at a physics timestep of 90hz anyway and the average game will be less CPU/GPU intensive than the average VR game.

    Smoothly changing the physics timestep/timescale as I suggested hides the problem a bit but does not make it go away.
Sign In or Register to comment.