Coroutine Stacking - Multiple calls into a coroutine

So I have this logic that occurs every time the game hits a specific point in execution. When this point is hit, 4-5 methods are called to do various things.

On a PC or tablet, its very fast and you don’t notice any stutter. On an iPhone 4, you see a slight stutter.

So, in the middle of these 4-5 methods, I decided to throw in some "yield return null;"s so that it could spread these instructions out over a couple frames or so.

It worked wonderfully… all stutter disappeared completely on the iPhone 4. Until I started noticing some object placement issues.

It turns out, that the specific point in execution that triggers this logic can, in fact, occur again before the other yielded calls are finished.

So what is happening is:

  1. FRAME 0001 Coroutine BETA is called initially and yields
  2. FRAME 0002 Coroutine BETA continues from yield and yields again
  3. FRAME 0003 Coroutine BETA is called a second time at the beginning before the last frame’s version continues yielding.
  4. Now I have 2 versions of BETA running at different points in their code.

So what I need to know is, is it possible to have Coroutines synchronous across the entire method? Because what I described above is asynchronous across the method.

What I need is the ability to block the second call to BETA from doing ANYTHING until the first call of beta is finished. This means: the entire scope of the first BETA call is done (including passing all YIELD statements) before the second version of BETA starts.

If it worked like this then all of the work done in between would absolutely work.

Is this possible?

A little more background: I am porting an engine I created for the iPhone on cocos2d a little over a year ago. I was able to thread these calls and access all of the cocos2d items within each individual thread as long as I made sure I accessed things in a thread-safe manner.

I did some research on threading these methods in Unity using C#'s basic threading model but everything I have read says you cannot access any Unity items within these threads. What I am doing in these methods is changing positions and changing UVs of GameObjects… that seems to me to be Unity specific. Is this the case?

Thanks!

PAR

I think @Louis has your coroutine locking nailed in his comment, basically lock it yourself with a counter. You can update meshes in a second thread because that just involves manipulating the Vectors associated with the mesh, so long as you actually put these back into the mesh on the main thread. This Unity Gems article covers doing that.

I wish there was a way to say that both @Louis and @whydoidoit had the correct answers.

Between the both of you I figured it out. A combination of Louis’s blocking and whydoidoit’s queuing and its working perfectly.

Here’s the gist:

protected Queue<int> coroutineQueue = new Queue<int>();
...
public IEnumerator myCoroutine() {    		
    int myCoroutineFrame = Time.frameCount;
	coroutineQueue.Enqueue(myCoroutineFrame);
    		
	while(coroutineQueue.Peek() != myCoroutineFrame) {
		yield return null;
	}

	/*
		do stuff...
	*/

    coroutineQueue.Dequeue();
}

Performance seems pretty good so far. I am not using Unity Pro so I can only do my own profiling but it seems that C#'s Queue class isn’t that bad performant-wise when dealing w/ plain 'ol ints.

Thanks a lot guys!

PAR