- Home /
Is there a way to make WaitForSeconds ignore time.timescale?
Is there a way to make WaitForSeconds ignore time.timescale, or in the situation below, is there a replacement for WaitForSeconds I can use instead?
I'm using:
while (!clicked)
{
yield return new WaitForSeconds(0.01f);
}
to wait for "clicked" to be true before continuing execution of a coroutine.
I would like to be able to pause the game, but discovered that time.timescale = 0 prevents WaitForSeconds from completing so the while loop can exit.
I'm aware that I may just have to disable GameObjects/scripts/animations etc manually in order to pause them, but I wondered if there was a better way.
Thank you for reading. Any help is appreciated.
i don't know the type of your game but i faced almost the same problem i had game over background i wanted to show a seconds after the player hit enemy and i had to set time.timescale to 0 so i stop enemies been instantiated again but time.timescale stops WaitForSeconds so finally and after long time i found this idea just changed the position of the player out the screen and called the time.timescale after the game over background show up
If you actually need the time to go on, there's another solution. I think Eric came up with it ^^
Just set Time.timeScale to a very small number. Not to 0. That way you can simply scale all wait values as well. If you for example use 0.0001f one game second would take 10000 real seconds (~2.77 hours). For most things that's enough to make it appear "frozen". Now if you need a something to wait for 1 real second, just scale it with the same value:
yield return new WaitForSecond(1f * 0.0001f);
That makes you wait only for a tenthousands of a second, but since the time is passing that slow it would take one real second.
Usually you only need it to go on for a few seconds. Once you're ready to actually pause your game you can set timescale to 0 to avoid if the player sits in pause for hours so he didn't actually move ^^.
Never occurred to me. One of those "obvious when you see it" things. Very clever.
Answer by Bunny83 · Oct 18, 2015 at 10:35 AM
No, WaitForSeconds always uses Time.timeScale. However in your case you can simply use
yield return null;
You try to wait for 0.01f seconds. Usually your framerate is lower than 100fps. So the time between two frames is already longer than the time you want to wait.
If you actually need something like WaitForSecond, you can use a coroutine like this:
public IEnumerator _WaitForRealSeconds(float aTime)
{
while(aTime >0f)
{
aTime -= Mathf.Clamp(Time.unscaledDeltaTime,0, 0.2f);
}
}
public Coroutine WaitForRealSeconds(float aTime)
{
return StartCoroutine(_WaitForRealSeconds(aTime));
}
Those can be used like this in another coroutine:
while(true)
{
yield return WaitForRealSeconds(2f);
// every 2 seconds, regardless of timescale.
}
You might want to have a look at my CoroutineHelper class. It uses a singleton to run helper coroutines indepentently from a GameObject. At the moment it doesn't contain a wait function that uses unscaledTime / unscaledDeltaTime but it could be easily added.
@Bunny83 When using your solution, it says the coroutine (your enumerator) has to return with a value. What should that be?
@Bunny83 This is more like the way I've done things more recently, but when I first started using Unity I did this kind of thing by just looking at System.DateTime.Now. I'm curious, any potential pitfalls you can think of with that? It seemed to work ok.
For me, I put a yield return null
at the end of the loop in the IEnumerator and it works just fine. I use this for UI scripting, because at character death, I scale the time down but still want to use my UI.