Some yield mess

Hi there. I'll try to put this across in the clearest manner possible, because it's been really nerve-racking over the past couple of days trying to sort this one out. I have a switch statement in JS, something like this:

switch(x){
  case 1:
    Debug.Log("line 1");
    yield Function1();
    Debug.Log("line 2");
    break;
  case 2:
    Debug.Log("line 3");
    yield Function2();
    Debug.Log("line 4");
    break;
//a couple of cases more...
}

function Function1(){
    //do something and yield some other functions
    yield Function3();
    Debug.Log("line 5");
    //return
}

function Function2(){
    //do something and yield some other functions
    yield Function3();
    Debug.Log("line 6");
    //return
}

function Function3(){
    //do something yield some other functions
}

Now, when x is 1, case 1 executes as expected, and the statements are printed as follows:

line 1

line 5

line 2

The bizarre thing occurs when x is 2, because only

line 3

and

line 6

are logged to the console, i.e. I never get to see "line 4", which is the command that should execute immediately after Function2() returns. At first I suspected it might be getting stuck in an infinite loop somewhere down the chain of function calls Function2() makes, so I inspected all of them (all the functions getting called during this procedure) and each and every one of them printed the Debug.Log messages, as they should. Besides, if execution were indeed left looping somewhere, "line 6" wouldn't be printed, would it?:/(all the functions in the chain are called thru yield, and "line 6" is the last line of code in Function2()) Now removing the yield from the Function2() call in case 2 would print "line 4" on the console, of course, but wouldn't produce the desired result from the game's perspective. What adds to the oddness of all this, is that removing the yield from the Function3() call in Function2() also results in "line 4" being printed, which is all the more bizarre, since "line 6" is logged anyway. Any advice would be most welcome!

N.

Wow. What the heck are you trying to do with all of these Yields? I would wager your design is likely in need of some re-evaluation because this seems like a convoluted approach, but that's your call to make in the end.

I don't even know how you got it to run. I tried the code that you posted and it would not compile, giving an error about yielding to a function with a void return. Co-routines (as indicated by the yield statement) must return an IEnumerator. The following code does work:

var x : int = 2; //Change this in the inspector

switch(x){
  case 1:
    Debug.Log("x = 1");
    yield Function1();
    Debug.Log("done");
    break;
  case 2:
    Debug.Log("x = 2");
    yield Function2();
    Debug.Log("Done");
    break;
}

function Function1() : IEnumerator {
    yield Function3();
    Debug.Log("Function1");
}

function Function2() : IEnumerator {
    yield Function3();
    Debug.Log("Function2");
}

function Function3() : IEnumerator {
    Debug.Log("Function3");
}

Thank you very much for your answer, mate. Indeed, our design may have considerable room for improvement, however, all those yields have their purpose. And the purpose is that both Function1() and Function2() carry out some checks and, if need be, call Function3() to do some animation. During this time, the mouse must be disabled, so the player cannot tamper with the checks and animations (we couldn't think of a better way to prevent the player from clicking while the animation is on). So, in actuality the switch statement I posted above is a simplified part (NOT the actual code) of an OnMouseDown() function. The idea was to disable the mouse at the beginning of each case (in the above code lines Debug.Log("line 1") and Debug.Log("line 3")), perform the necessary routines (player just watching, or clicking like mad, but unable to wreak any havoc on the game) and re-enable it just before the break statement (lines Debug.Log("line 2") and Debug.Log("line 4") above). I am NOT trying to compile nor run the above code as it is - this was meant to be simply an illustrative example of what we're actually doing. I know that I cannot yield a void function. It must either explicitly, or implicitly return IEnumerator. Function1() and Function2() above contain a yielded call to Function3(), so, to my understanding at least, they do not need the IEnumerator in their signatures (of course, it might be a better programming style to include one). Function3() also contains yielded calls to other functions I didn't mention for brevity. Perhaps I should've :/.

In short, it is imperative that execution should return from Function1() and Function2() (in the example) so the mouse can be unlocked and the game can resume. Function2(), however, still evades us. I would be eternally grateful, if somebody would try and show us a way out of this conundrum.

I use this opportunity to thank Mike for his comment. I've been trying to read some of your other posts as well, hopefully I find a solution. According to the api, however, yield does the same as yield StartCoroutine(), in the WaitAndPrint(2.0) example at least http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StartCoroutine.html?from=index Is it true?

Thanks,

N.