c# - Loops using coroutines -
i have question coroutine behaviour in case of loops, see following code extract example done on unity c# script:
void start() { startcoroutine(fsm()); } ienumerator fsm() { state="state1"; while (true) { debug.log("state "+state); yield return startcoroutine(state); } } ienumerator state1() { while (true) { if (statetransitioncond) { state = "nextstate"; yield break; } yield return null; } }
the status machine works fine, while current status status1 (statetransitioncond==false
), due yield return null
inside loop of state1()
routine, expecting loop inside fms()
performs iteration generating debug log 'debug.log("state "+state);'.
in other words expecting lot of debug log (one each iteration of state1() routine, when status status1) in reality 1 execution performed while status status1.
so suppose miss yield functionality, there can explain me behaviour?
your issue stems fact code not break out of state1()
method until statetransitioncond == true
.
the method starting coroutine, fsm()
, not returned until state1
finished. in other words, control flow not return calling method until coroutine complete. believe due fact yield
-ing state1
inside fsm
(yielding coroutine). obviously, "normal" methods not wait coroutine finish before continuing execution.
please see code sample below illustrative example:
using unityengine; using system.collections; public class coroutinetest : monobehaviour { // current fsm state public string state = ""; void start() { startcoroutine(fsm()); } ienumerator fsm() { state = "state1"; while (true) { debug.log("state: " + state); // executeonce execute once before returning outer function yield return startcoroutine(executeonce()); // executeindefinitely execute indefinitely until while() loop broken // uncomment test //yield return startcoroutine(executeindefinitely()); } } ienumerator executeonce() { debug.log("calling executeonce()"); yield return new waitforseconds(1f); } ienumerator executeindefinitely() { debug.log("calling executeindefinitely()"); while (true) { debug.log("inside executeindefinitely()"); yield return new waitforseconds(1f); } } }
Comments
Post a Comment