Multiple Mathf.SmoothSteps in a Coroutine not staying in proportion?

I’m trying to make a script that slows down the game speed with Time.timeScale but he maintains their normal movement speed, jump, etc. when using rigidbody.velocity for movement. Before moving to rigidbody movement this was a simple as changing to Time.unscaledDeltaTime, however this doesn’t work anymore so I wrote a coroutine that slows time whilst speeding up player movement to match using Mathf.SmoothStep. The issue I’m having is that they don’t seem to be staying in proportion with each other which results in the player briefly gaining speed/being able to jump higher/lower during the SmoothStep. My assumption here is that as lerp uses a percentage of the value that they should stay in proportion but that doesn’t seem to be the case.

    private IEnumerator TimeWarpSlowDown(float warpTimeTo, float warpSpeedTo, float warpJumpTo, float transitionTime)
    {
        Debug.LogWarning("Time Warp Slow Down starting at " + Time.time);

        float currentTimeScale = Time.timeScale;
        float currentGravity = Physics.gravity.y;
        float currentSpeedScale = playerControllers[0].speedScale;
        float currentJumpScale = playerControllers[0].jumpScale;
        float t = 0f;

        while (Time.time < timeWarpTransitionEndTime)
        {
            t += (1 / transitionTime) * Time.unscaledDeltaTime;

            // Gradually slow down time over x seconds, using mathf.smoothstep, updating gravity and player speed
            Time.timeScale = Mathf.SmoothStep(currentTimeScale, warpTimeTo, t);
            Physics.gravity = new Vector3(0, Mathf.SmoothStep(currentGravity, currentGravity * warpSpeedTo, t), 0);
            foreach (var player in playerControllers)
            {
                player.speedScale = Mathf.SmoothStep(currentSpeedScale, warpSpeedTo, t);
                player.jumpScale = Mathf.SmoothStep(currentJumpScale, warpJumpTo, t);
            }

            // The time of physics steps needs to change with time to prevent jerky movement
            Time.fixedDeltaTime = defaultFixedDeltaTime * Time.timeScale;

            yield return null;
        }

        // After lerping set values to ensure it is set to the correct value
        Time.timeScale = warpTimeTo;
        Physics.gravity = new Vector3(0, currentGravity * warpSpeedTo, 0);
        foreach (var player in playerControllers)
        {
            player.speedScale = warpSpeedTo;
            player.jumpScale = warpJumpTo;
        }

        Debug.LogWarning("Time Warp Slow Down finished at " + Time.time);
    }

Any idea why this is happening?

Time scale takes effect in the next update. The manual has additional notes to consider: Unity - Scripting API: Time.timeScale

Gravity should scale along with time. perhaps you don‘t need to do that.

I would prefer to only adjust the timescale in a LateUpdate method.

1 Like

Ahhh okay, I thought it might be out of sync but couldn’t see how, thanks for the help.

Also re: gravity, it does scale with time which is the issue I was having. Though I increased the move speed and jump velocity to counter the decrease in timeScale, it meant the player would then fall slowly after jumping, so I needed to scale up gravity as timeScale decreased.