How to pause any coroutine according to your global pause state :

Hello,

as coroutines are very important in optimization processes, making them compatible with a game paused state could be vital.

So here we go :

In your class containing those coroutines (or in any abstract/singleton you want), put these functions :

public Coroutine _sync(){
		return StartCoroutine(PauseRoutine());	
	}
	
public IEnumerator PauseRoutine(){
		while (_myPauseState) {
			yield return new WaitForFixedUpdate();	
		}
		yield return new WaitForEndOfFrame();	
	}

with _myPauseState being your global pause state.

then in any Coroutines, put this at the end (or at any place you want to check for a pause) :

yield return _sync();

I personally prefer to put the first code block into a generic baseClass, derived from MonoBehaviour , and then derive all my other “pause-able” classes from it. So I don’t have to rewrite the block in all the new pause-able classes.

Just wanted to say thank! Great script!

What if i want to pause a coroutine that has a “yield return new WaitForSeconds(3);”?
Where should i call to “yield return _sync();”?

I’m not sure if they’re going to respond 4.5 years later…

Personally I don’t use unity Coroutines, and instead I have my own ‘RadicalCoroutine’ that wraps around the unity Coroutine.

One feature of it is controlling how the coroutine pauses when the MonoBehaviour/GameObject it was called with gets enabled/disabled or activated/deactivated.

Here is the manager for said radicalcoroutines pausing:

It automatically gets added to the GameObject if you create a coroutine that behaves unlike the default behaviour. As you can see in the RadicalCoroutine itself:
https://code.google.com/p/spacepuppy-unity-framework/source/browse/trunk/SpacepuppyBase/RadicalCoroutine.cs

Then in code, when you start a RadicalCoroutine you can say something like:

this.StartRadicalCoroutine(this.MyRoutine(), RadicalCoroutineDisableMode.Pauses);

What I usually do is I have a game state machine that will disable any critical gameobjects that get paused during ‘pause’ mode.

Now, with all that… you may notice in the Start/Resume methods, it checks the most recent ‘IRadicalYieldInstruction’ and pauses/unpauses it.

Basically what I did was create a ‘WaitForDuration’ yield instruction:

This mimics the behaviour of ‘WaitForSeconds’, BUT is pausible (and also scalable, using ITimeSupplier, which is something else I have in my framework). If you yield a WaitForDuration, or yield a WaitForSeconds in a coroutine that is pausible which then gets converted to a WaitForDuration, and the coroutine gets paused. This WaitForDuration doesn’t count time for the duration of that pause.

1 Like