Jitter in physics objects when lerping TimeScale to 0

Hi, fairly new to all this

I’m trying to implement pause functionality with the following coroutines, called when the pause button is pressed, to smoothly transition to a paused state:

    IEnumerator PauseGameTransition(float duration)
    {
        Debug.Log("Pausing Game");

        while (Time.timeScale > 0f)
        {
            if (Time.timeScale - (Time.unscaledDeltaTime / duration) < 0f) break;
            Time.timeScale -= Time.unscaledDeltaTime / duration;

            yield return null;
        }

        Time.timeScale = 0f;
    }

    IEnumerator UnpauseGameTransition(float duration)
    {
        Debug.Log("Unpausing Game");

        while (Time.timeScale < 1f)
        {
            Time.timeScale += Time.unscaledDeltaTime / duration;

            yield return null;
        }

        Time.timeScale = 1f;
    }

This works fine for non physics object; I can see the clouds in the background smoothly transition to frozen.

But looking at the player character they kinda judder to a standstill instead of the smooth motion I’m after.

This is most noticeable as timeScale approaches 0.

You would have to show the details of the player character’s Rigidbody configuration and how it moves.

Also it’s pretty standard practice to decrease the fixed timestep proportionally with the deceased time scale in order to keep the real number of physics simulation steps per real life second the same.

1 Like

Yeah sorry, I’m not in front of it atm - it’s pretty much a default Rigidbody2D, that receives a single upwards impulse on player input, affecting it in FixedUpdate

Ahhh I think this might be the root. I had assumed that the fixed interval scales according to the current value of timeScale.

So for example adding something like this in the while loop should fix it: Time.fixedDeltaTime -= defaultFixedDTime / duration;
I’ll give this a shot as soon as I’m back in the chair!:slight_smile:

Make sure interpolation is enabled on the rigidbody. Without interpolation the movement would become very jerky as timeScale approached zero.

1 Like

I implemented scaling Time.fixedDeltaTime to and from 0 and it’s original value and it seems be working :slight_smile:

    private void Awake()
    {
        fupdatedelta = Time.fixedDeltaTime;
    }

    IEnumerator PauseGameTransition(float duration)
    {
        Debug.Log("Pausing Game");

        while (Time.timeScale > 0f)
        {
            if (Time.timeScale - (Time.unscaledDeltaTime / duration) < 0f) break;
            Time.timeScale -= Time.unscaledDeltaTime / duration;
            Time.fixedDeltaTime = fupdatedelta * Time.timeScale;
            yield return null;
        }

        Time.timeScale = 0f;
        Time.fixedDeltaTime = 0f;
    }

    IEnumerator UnpauseGameTransition(float duration)
    {
        Debug.Log("Unpausing Game");

        while (Time.timeScale < 1f)
        {
            Time.timeScale += Time.unscaledDeltaTime / duration;
            Time.fixedDeltaTime = fupdatedelta * Time.timeScale;
            yield return null;
        }

        Time.timeScale = 1f;
        Time.fixedDeltaTime = fupdatedelta;
    }

Hmm, I tried flipping this on and it kinda broke the movement even when no input is made, timeScale isn’t change, and the object is just falling under gravity.

No idea what’s going on there - changing to Extrapolate fixes this but it still does nothing for the judder as timeScale ramps up and down.

Sorry that’s what I meant - I reverted the code to the original sample I posted but w/ interpolation on and got the weird results

I expect it will be just about impossible to get rid of jitter at very slow time scales, because any delta time you are using will be used as a divisor in many formulas. The smaller the divisor, the bigger the computed value. The float only has 23 bits of mantissa resolution and the gap between possible computed values after dividing will be farther and farther apart.

You might want to just ramp from 1.0 to 0.1f and then snap to a stop, to avoid the worst effect of this math limitation.

1 Like