Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in 'Scripting' started by n0mad, Nov 23, 2010.

  1. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    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 :

    Code (csharp):
    1. public Coroutine _sync(){
    2.         return StartCoroutine(PauseRoutine()); 
    3.     }
    4.    
    5. public IEnumerator PauseRoutine(){
    6.         while (_myPauseState) {
    7.             yield return new WaitForFixedUpdate(); 
    8.         }
    9.         yield return new WaitForEndOfFrame();  
    10.     }
    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) :

    Code (csharp):
    1. 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.
     
  2. _joe_

    _joe_

    Joined:
    Nov 14, 2012
    Posts:
    3
    Just wanted to say thank! Great script!
     
  3. Sherlock-jr

    Sherlock-jr

    Joined:
    Oct 2, 2014
    Posts:
    11
    What if i want to pause a coroutine that has a "yield return new WaitForSeconds(3);"?
    Where should i call to "yield return _sync();"?
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,505
    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:
    https://code.google.com/p/spacepupp...unk/SpacepuppyBase/RadicalCoroutineManager.cs

    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/spacepupp...owse/trunk/SpacepuppyBase/RadicalCoroutine.cs

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

    Code (csharp):
    1.  
    2. this.StartRadicalCoroutine(this.MyRoutine(), RadicalCoroutineDisableMode.Pauses);
    3.  
    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:
    https://code.google.com/p/spacepupp...pacepuppyBase/IRadicalYieldInstruction.cs#252

    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.
     
    Last edited: Apr 9, 2015
    ThermalFusion likes this.