- Home /
How IEnumerator Update() works?
U3D creates new corutine each time frame ticks for that object or is smart enough to wait until one has finished?
I'm not sure to understand your question. $$anonymous$$onoBehaviour.Update is not a coroutine.
if you call an IEnumerator from the Update function, then yes, you are calling it every frame
everything you put in Update is called every frame
if you say, for example:
void Update(){
if(canCallCoroutine)
StartCoroutine(RunCoroutine());
}
IEnumerator RunCoroutine(){
canCallCoroutine = false;
yield return new WaitForSeconds(1);
canCallCoroutine = true;
}
then that would be how you regulate it, with some sort of condition
@seth-bergman: almost ;) You didn't run your coroutine, you just create one but it never get executed because you have to use StartCoroutine to start a coroutine. In UnityScript the compiler implicitly calls StartCoroutine when you try to call a generator function.
LOL thanks, I never use c# these days, always forget these details
You help set me straight though :)
Answer by aldonaletto · Aug 06, 2012 at 02:42 PM
The question is unclear, but if you want to know if calling StartCoroutine each Update only starts a new coroutine when the previous one has finished, the answer is no: each StartCoroutine creates a new instance, and you may even crash your system after some time.
When you call StartCoroutine(SomeCoroutine) an instance of SomeCoroutine is created and runs until an yield instruction is found - the coroutine then returns to the calling code, and "sleeps" until next frame, when it's automatically resumed after the yield instruction. This cycle is repeated until the coroutine ends, when the instance is deleted without giving any warning to the caller code.
Since ther's no feedback from Unity about the end of the coroutine, you must provide it yourself - I usually have a boolean flag set at the beginning and reset at the end of the coroutine:
bool moving = false; // flag that shows when the coroutine is running
IEnumerator MoveObj(Transform obj, Vector3 dest, float duration){ moving = true; // coroutine running Vector3 org = obj.position; float t = 0; while (t < 1){ t += Time.deltaTime / duration; obj.position = Vector3.Lerp(org, dest, t); yield return 0; } moving = false; // coroutine ended }
// move owner object to random positions each 5 seconds: void Update(){ if (moving == false){ // never start the coroutine while the previous is running! Vector3 pos = transform.position; pos.x += 10 Random.Range(-10f, 10f); pos.z += 10 Random.Range(-10f, 10f); StartCoroutine(MoveObj(transform, pos, 5)); } }
Answer by Owen-Reynolds · Aug 06, 2012 at 05:10 PM
The point about "is smart enough to wait ... until ... finished?" is that sometimes you want to call same the same coroutine multiple overlapping times, not waiting until it has finished.
Say that when you're on fire a coroutine spawns/kills an emitter and subtracts 5HP over 5 seconds. If you get set on fire 2 seconds after the first time, running a second copy of the same coroutine is just fine.
Or, say a "fade out and die" coroutine takes the input of who to kill. You might want to run it three times on different dying objects. Maybe all at once, maybe overlapping.
Your answer
Follow this Question
Related Questions
Using Update loop vs Coroutine for exact timer 3 Answers
How to move GameObject after 1 second c# 2 Answers
IEnumerator in Update 2 Answers