1
\$\begingroup\$

I am pausing game by setting Time.timeScale to 0. And When the Game resumes Time.timeScale is set to 1f again, and game resumes. Now I want to add timer before actually resuming game. It shows 3,2,1,Go and player starts running. But problem is that It is not counting as Time.timeScale is set to zero. And if i set Time.timeScale to 1, the player starts running immidiately and countdown also starts perallaly. Actually I want to start countdown first and then to resume game. I've added the code below, that i've used. The game and timer both is activated perallally by following code.

IEnumerator WaitToResumeGame()
{   
    for (int i = 0; i <= 3; i++) {
        yield return new WaitForSeconds (1f);
        TimerText.GetComponent<Text> ().text = "" + i;
    }
    TimerText.SetActive (false);
}

public void ResumeGame()
{
    pausePanel.SetActive (false);
    TimerText.SetActive (true);
    Time.timeScale = 1f;
    StartCoroutine (WaitToResumeGame ());
}
\$\endgroup\$
3

4 Answers 4

2
\$\begingroup\$

You can use a little trick for that:

use the Time.realtimeSinsceStartup property

when you end the pause set a variable like

float endPause = Time.realtimeSinceStartup + 3; //for 3 Seconds countdown

and right after that:

while (Time.realtimeSinceStartup < endPause){
     yield return 0;
}
Time.timeScale = 1;

That will cause the game to wait another 3 seconds before continuing. Of course you need to modify it a little to display a countdown but that shouldn't be a problem for you.

\$\endgroup\$
2
  • \$\begingroup\$ As I'm new to Unity, I can not adjust that. Can you please help me. Your code helps me to freeze game for 3 second, But it starts countdown after that 3 second, means game and countdown starts perallaly. \$\endgroup\$ Commented Mar 2, 2016 at 11:49
  • \$\begingroup\$ Currently I'm at work so I don't have time to give you an example. I'll provide you one when I'm at home. \$\endgroup\$ Commented Mar 2, 2016 at 12:03
1
\$\begingroup\$

yield return new WaitForSeconds is very much affected by timeScale. So if timeScale is zero, that coroutine will never continue.

Jonas' answer is correct, but I'd like to add something you may find helpful: in Unity 5, you can write a class that does the same thing as WaitForSeconds, but with unscaled seconds instead of scaled. This is the class I use:

using UnityEngine;

public class WaitForRealSeconds : CustomYieldInstruction
{
    private float m_FinishTime;

    public WaitForRealSeconds(float seconds)
    {
        m_FinishTime = seconds + Time.realtimeSinceStartup;
    }

    public override bool keepWaiting
    {
        get
        {
            return m_FinishTime > Time.realtimeSinceStartup;
        }
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Good point! I also thouth about that but I thought it would become to complex, but I was wrong :) +1 from me \$\endgroup\$ Commented Mar 2, 2016 at 11:43
  • \$\begingroup\$ @JonasWirth It was a bit more complicated before Unity introduced CustomYieldInstruction. It was still possible, but not with the yield return new WaitXXX() syntax. \$\endgroup\$
    – piojo
    Commented Mar 3, 2016 at 3:35
1
\$\begingroup\$

Use WaitForSecondsRealtime on the place of WaitForSeconds. It will work.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This answer would be even better if it included a little explanation of how this differs from WaitForSeconds and how it solves the problem. (As-is, it flagged our auto-moderation systems for being so short 😉) \$\endgroup\$
    – DMGregory
    Commented May 11, 2020 at 12:21
0
\$\begingroup\$

The following code helps me to do both, Countdown and after that to resume game.

IEnumerator WaitToGetReady()
{
    TimerText.GetComponent<Text> ().text = "" + 3;
    yield return WaitToResumeGame ();

    TimerText.GetComponent<Text> ().text = "" + 2;
    yield return WaitToResumeGame ();

    TimerText.GetComponent<Text> ().text = "" + 1;
    yield return WaitToResumeGame ();

    Time.timeScale = 1f;

    TimerText.SetActive (false);
}

IEnumerator WaitToResumeGame()
{   
    float start = Time.realtimeSinceStartup;
    while (Time.realtimeSinceStartup < start + 1f) {
        yield return 0;
    }
}

public void ResumeGame()
{
    pausePanel.SetActive (false);
    TimerText.SetActive (true);
    StartCoroutine (WaitToGetReady ());
}
\$\endgroup\$

You must log in to answer this question.

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