It’s great when the frame rate is low to be able to pause too many scripts running at once. for example when too many events happen in the same frames, it’s good to sense a slow down and desynchronise some of the events.

I found that this line is good for pausing and desynchronising, but it’s not great:

for (var n:int = 0; n < 1000; n ++){
if (  Time.deltaTime > 0.04 ){yield WaitForSeconds (Random.Range (0.04, .2)); }
else break;

and Bunny83 tells me that RealTimeSinceStartup would provide a better way to do it, although i didnt understand why because, RealTimeSinceStartup doesnt depend on frame rate?

and also, there must be more sophisticated ways of detecting when many cooperative multitasking system .NET / Mono Generators occur? and making them go smoothly through?

any tips?

Note: convenience edit for future readers: from the comments below:

The technique here is pretty much explained
in the Advanced Coroutines tutorial on unityGEMS.com


Well you could hijack the coroutine system and measure how long each one was taking, then stop doing any more if a certain threshold was passed. You’d need to use Stopwatch or DateTime to get an accurate measurement and you’d need to wrapper all of your coroutines in something that did it.

     public static class CoroutineWrapper
     {
            static int lastFrame;
            static float millisecondsThisFrame;
            public static float maxMillisecondsPerFrame = 10;
             
            static object Execute(IEnumerator coroutineFunction, ref bool result)
            {
                    var start = System.DateTime.Now;
                    result = coroutineFunction.MoveNext();
                    millisecondsThisFrame += (float)(System.DateTime.Now - start).TotalMilliseconds;
                    return coroutineFunction.Current;
            }

            public static IEnumerator TimeLimit(this IEnumerator coroutineFunction, bool important = false)
            {
                   var result = true;
                   do
                   {
                       if(lastFrame != Time.frameCount) 
                       {
                          lastFrame = Time.frameCount;
                          millisecondsThisFrame = 0;
                       }
                        if(millisecondsThisFrame > maxMillisecondsPerFrame)
                        {
                            yield return null;
                            if(important)
                            {
                                yield return Execute(coroutineFunction, ref result);
                            }
                        }
                        else
                        {
                             yield return Execute(coroutineFunction, ref result);
                        }
                  } while(result);
            }

            public static IEnumerator Monitor(this IEnumerator coroutineFunction)
            {
                   var result = true;
                   do
                   {
                       if(lastFrame != Time.frameCount) 
                       {
                          lastFrame = Time.frameCount;
                          millisecondsThisFrame = 0;
                        }
                       yield return Execute(coroutineFunction, ref result);
                   } while(result);
            }

     }

And call it like this:

       StartCoroutine(YourCoroutine(someParameter).TimeLimit(true));  //Important one, will only miss one frame
       StartCoroutine(YourCoroutine(someParameter).TimeLimit()); // Will only run when not too much time has passed
       StartCoroutine(YourOtherCoroutint().Monitor()); //Measures but doesn't pause