0
\$\begingroup\$

I'm trying to simulate physics manualy in a Unity 3D game. I've turned off Physics "Auto Simulation" in Project Settings and wrote this piece of code (it is more or less the unity doc sample)

private void Update()
{
    this.timer += Time.deltaTime;
    while (this.timer >= Time.fixedDeltaTime)
    {
        this.timer -= Time.fixedDeltaTime;

        controller.ApplyForces(controls);
        Physics.Simulate(Time.fixedDeltaTime);
    }
}

But when I play the game, movements are lagging a lot.
In fact, I can explain it: my game runs at 120 fps. The Time.fixedDeltaTime is set to 0.01667 (60fps). So 1 out of 2 frames are not simulating physics! In other words, half of my Update calls don't enter the while loop, which produce the jump effect.

I'm sure i'm missing something... what is the recommended way to do this? Should I call Physics.Simulate in FixedUpdate?

EDIT:

As someone asked me in the comments (then deleted the comment), I'm simulating Physics manually for networking reason. With manual physics, I can do predictions and corrections. Here's a link that describes the problem

EDIT2:

Thanks to @DMGregory and his excellent answer, I figured out that the problem comes from the lack of interpolation of my player rigidbody:
InterpolationMode seems to be handled by Unity when autosimulation is set to ON, which is not my case.

So now I'm looking how to handle this myself.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Normally mismatches between the physics tick rate and display framerate are solved with interpolation. \$\endgroup\$
    – DMGregory
    Commented Apr 19, 2022 at 16:18
  • \$\begingroup\$ Arg, I was afraid of this answer. Thanks for the link, I will check it out! \$\endgroup\$
    – Martin
    Commented Apr 20, 2022 at 8:42
  • \$\begingroup\$ Oh! @DMGregory I just read your other post (gamedev.stackexchange.com/a/105113/139279) and just understood one thing : Unity, with autosimulation ON, magically interpolates rigidbodies with "interpolate" mode, but does NOT with autosimulation OFF!. I have the exact same problem by turning my RBs to "no interpolation" mode even with auto-simulating physics! \$\endgroup\$
    – Martin
    Commented Apr 20, 2022 at 14:02
  • 1
    \$\begingroup\$ Fortunately, you can roll your own interpolation. Have two copies of each GameObject: one that's invisible and used for simulation, and one that's visible, with a script that interpolates its parameters according to updates from its simulated copy. \$\endgroup\$
    – DMGregory
    Commented Apr 20, 2022 at 14:59
  • \$\begingroup\$ Can we reasonably affirm that Unity does this with autosimulation and interpolated rigidbodies? \$\endgroup\$
    – Martin
    Commented Apr 20, 2022 at 15:13

2 Answers 2

2
\$\begingroup\$

After a lot of research, I have a better understanding of this.

  1. the problem I describe is a very common problem due to unsync between frame rendering timestep and physics fixed timestep. Unity solves this automatically with the interpolationMode = interpolate of rigidbodies.

  2. when simulating physics manually, Unity do not interpolate thoses rigidbodies for us anymore. We have to do it manually, as @DMGregory suggests

  3. another option is lower fixedDeltaTime a lot to minimize desyncs, as @shingo suggests. But rendering timestep is not constant! And if the game runs at 120fps, the fixedTimestep whould be very small and CPU instensive.

  4. I highly recommand to read this article, which suggests to use Application.targetFrameRate and fixedDeltaTime to synchronise those timesteps to the same framerate.

Finally, I set the framerate to 60Hz whith those two properties: this is ok for rendering and not too intensive for CPU physics. And the game seems fluid again.

\$\endgroup\$
1
\$\begingroup\$

You are right, you need a small fixedDeltaTime value (eg. 0.01).

You can simulate physics in Update, but you'd better drag this script to the front row in Script Execution Order settings.

\$\endgroup\$
4
  • \$\begingroup\$ But if I want my game to run 120fps, I need 0.008s. of fixed delta time, which is very, very low. I don't want physics to run that frequently, I'm sure there are some better solutions \$\endgroup\$
    – Martin
    Commented Apr 20, 2022 at 8:48
  • \$\begingroup\$ Could you tell me why do you believe there is a better solution? You have to call Physics.Simulate to move objects, otherwise do it manually. \$\endgroup\$
    – shingo
    Commented Apr 20, 2022 at 8:58
  • \$\begingroup\$ Maybe I'm wrong, but I have the feeling that lowering the fixed delta time will be more CPU intensive, specially with simulation correction due to networking problems (however, I'm also considering this option) \$\endgroup\$
    – Martin
    Commented Apr 20, 2022 at 9:07
  • \$\begingroup\$ Yes, high fps is more CPU intensive. For an online game maybe you just want to synchronize the states in a low frequency. \$\endgroup\$
    – shingo
    Commented Apr 20, 2022 at 9:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .