7
\$\begingroup\$

I have a coroutine that smoothly changes a variable in my UI, but when I pause the game, the coroutine pauses too. How can I fix that?

Code:

using UnityEngine;
using System.Collections;

public class HUDController : MonoBehaviour {
    public void PauseGame() {
        FreezeTime();
        StartCoroutine(ShowPauseMenu());
    }

    private void FreezeTime() {
        Time.timeScale = 0;
    }

    private IEnumerator ShowPauseMenu() {
        var pauseMenuCanvasGroup = GameObject.FindWithTag("PauseMenu").GetComponent<CanvasGroup>();
        var alphaValue = 1f;
        var velocity = 0f;
        var time = 0.15f;

        while (!Mathf.Approximately(pauseMenuCanvasGroup.alpha, alphaValue)) {
            pauseMenuCanvasGroup.alpha = Mathf.SmoothDamp(pauseMenuCanvasGroup.alpha, alphaValue, ref velocity, time);
            yield return null;
        }

        pauseMenuCanvasGroup.alpha = 1; // Since float is not accurate, manually set the alpha to 1
        pauseMenuCanvasGroup.interactable = true;
    }
}
\$\endgroup\$
  • \$\begingroup\$ I'm unable to reproduce this issue in Unity 5. In my tests, coroutines that yield return null or new WaitForEndOfFrame() keep humming along just fine when Time.timeScale = 0 - it's only yield return new WaitForSeconds(delay) that pause. Can you confirm what version of Unity you're running? \$\endgroup\$ – DMGregory Jan 10 '16 at 14:00
  • \$\begingroup\$ @DMGregory 5.2.3f1 \$\endgroup\$ – Milen Jan 10 '16 at 14:01
  • \$\begingroup\$ How sure are you that the timescale is the cause? Have you tried to not set the timescale to zero and still run the coroutine? \$\endgroup\$ – Athos vk Jan 10 '16 at 14:09
  • \$\begingroup\$ Yes, I removed the timescale and it runs just fine \$\endgroup\$ – Milen Jan 10 '16 at 14:42
  • \$\begingroup\$ Can anyone help? \$\endgroup\$ – Milen Jan 10 '16 at 18:59
12
\$\begingroup\$

This is sure to happened because Mathf.SmoothDamp uses Time.deltaTime in default calculation. When you set Time.timeScale = 0 then Mathf.SmoothDamp won't give the expected value but only first value, repeatedly.

You can further verify by printing alpha value to console, print it in your while loop so that you can confirm it by the unlimited logs of same value.

Here is the Documentation on Mathf.SmoothDamp.

You can fix this by passing your own deltaTime to keep it from using its default Time.deltaTime. Just add one more parameter to the end of the call:

pauseMenuCanvasGroup.alpha = Mathf.SmoothDamp(
  pauseMenuCanvasGroup.alpha, 
  alphaValue, 
  ref velocity, 
  time,
  1000,          // <-- Fifth parameter Optionally allows you to clamp the maximum speed.
  1.0f/30.0f);   // <-- Add a sixth parameter representing your framerate.

You can use a function that measures realtime elapsed instead of a constant, if your rendering framerate is variable.

\$\endgroup\$
  • 2
    \$\begingroup\$ Dontcha love it when methods do something totally unexpected for completely reasonable (if hard to discern) reasons? \$\endgroup\$ – Draco18s Jan 11 '16 at 19:15
  • \$\begingroup\$ It doesn't work. It still gives only the first value. \$\endgroup\$ – Milen Feb 18 '16 at 20:59
  • \$\begingroup\$ @Milen yup, that was a little mistyping there, actually that should be the 6th parameter instead of 5th, 5th is the max speed. Check the edits \$\endgroup\$ – Hamza Hasan Feb 18 '16 at 21:38
  • \$\begingroup\$ @Milen now the code is tested thoroughly :) Give it a try :) \$\endgroup\$ – Hamza Hasan Feb 18 '16 at 22:08
0
\$\begingroup\$

I had this problem and the situation was like this, and I SOLVED IT. User presses the pause button then some objects goes off (these objects has couroutine(s) ). THIS IS THE PROBLEM. I must not turn off those game objects. The coroutines working fine while the game object is on and when you turn them off every thing is going to be mess.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.