- Home /
Why doesnt my coroutine ever end?
Hi there. I wanted to use a Coroutine to make my game pause for a couple seconds whilst the players state changes (eg. Small or big player like in Super Mario).
Everything looks fine to me after studying the docs, but the code after the coroutine which I wanted to use to unpause the game never gets called and the game stays paused:
void SwitchPowerStates(PowerState newState)
{
currentPowerState = newState;
switch (currentPowerState)
{
case PowerState.SMALL:
{
// code that changes the size
break;
}
case PowerState.BIG:
{
// code that changes the size
break;
}
}
StartCoroutine(PauseAndWaitFiveSecs(2f));
Debug.Log("this gets called before the coroutine is started");
}
void PauseGame()
{
Time.timeScale = 0f;
}
void UnPauseGame()
{
Time.timeScale = 1f;
}
IEnumerator PauseAndWaitFiveSecs(float waitTime)
{
PauseGame();
Debug.Log("before time = " + Time.time);
yield return new WaitForSeconds(waitTime);
// WHY IS NONE OF THE FOLLOWING CODE CALLED???
Debug.Log("after time = " + Time.time); // doesnt happen?
UnPauseGame(); // doesnt happen?
}
I commented the area of code where I expected to be able to unpause the game. I think i included all the relevant code.
Really hope someone can help me.
Thanks
Answer by Bunny83 · Dec 15, 2017 at 04:33 AM
Setting the time scale to 0 affects all game time dependent things which includes Time.deltaTime, Time.time and WaitForSeconds as well. You can use "WaitForSecondsRealtime" instead.
Answer by JVLVince · Dec 15, 2017 at 04:31 AM
Well I believe you read the document carefully but maybe you not mentioned this point.
The actual time suspended is equal to the given time multiplied by Time.timeScale. See WaitForSecondsRealtime if you wish to wait using unscaled time.
The WaitForSeconds yield is base on Time.time to count (If I not wrong) so when you set Time.timeScale to 0 in your pause function, then the Time.time will just stop at the moment, the time counter inside the WaitForSeconds will never reach waitTime. So instead of using WaitForSeconds, you should use WaitForSecondsRealtime.
One more thing I think I have to mentioned you is that if you pause by set Time.TimeScale to 0, all object of your games will stop FixedUpdate, so you have to be careful with this approach. Since I don't know what you decide to implement so I just can advice this.
Hope this help. Cheers!!
Ahh, too slow ^^. +1
ps: setting the timeScale to 0 will still "update" the gameobjects. So they still get their Update methods called. Just FixedUpdate and the physics system is completely halted (mainly because the calling of FixedUpdate depends on the game time).
Thank you both lots. I clearly didnt read the docs properly enoudh. Hopefully this can $$anonymous$$ch me a lesson coz I should have easily seen this. Cheers very much though
Tks @Bunny83 for correct me. :) I will edit my answer
Hey Vince, I accept his answer as it appears he was first, but i rewarded you some of my Rep as I felt bad and appreciate both your help :]
Im not really sure how to implement this. I saw it as instructions somewhere , but they clearly arent that accurate as I dont think it said PauseForRealTime in the instructions. I probably just make a bool flag isPaused and set it true when I start the routine and false when it ends , then I can pause all the update loops etc in my game (pain in ass, when I was coding pure code in Libgdx or LWJGL I could access the very "top-most" update loop (reallly wanted to remember the correct word but that will do lol) and stick a small bool in there and it would suspend all updating for the game loop
I think you should take a look at this. It's have various way to pause a game, including your approaching :D . Cheers
Your answer
Follow this Question
Related Questions
Coroutines IEnumerator not working as expected 2 Answers
understanding coroutines 0 Answers
How to force Coroutine to finish 1 Answer
Startcoroutine not working second time 2 Answers
Coroutines and states 1 Answer