- Home /
C# yield error
So i wrote a code that looks like this:
if (Something == true)
{
//did something
yield return new WaitForSeconds(1);
//did something
}
and i placed it under FixedUpdate, but it gives an error that says:
error CS1624: The body of `ScriptName.FixedUpdate()' cannot be an iterator block because `void' is not an iterator interface type
So why is this happening ? I never ever used yield before, i don't even know what it is, i used invoke to a function instead, but i really want yield it's faster, so why, what's wrong.
Answer by Thom Denick · Jan 19, 2015 at 05:34 AM
As BM said, you don't every want to yield within any Unity Lifecycle such as Start, Update, or Fixed Update. This would result in your main thread hanging, probably crashing Unity if it had worked.
Instead, you want to run Yields in IEnumerators that are started via coroutine. There are exceptions to this, but as a beginner, this is how you should be using them. Here's a standard example:
private void Start()
{
StartCoroutine(WaitForAFew());
}
IEnumerator WaitForAFew()
{
//Do Something Before the Wait
yield return new WaitForSeconds(3.0f);
//Do Something After the Wait
}
If i had to use other functions i would just stick with Invoke... No other way to wait for a few seconds and then continue, but in fixed update ?
Your answer is right, hovewer please understand that unity coroutines and generator yelding have absolutely nothing to do with multithreading, and no locking will ever occur with coroutines
Unlike calling a normal method, calling a method that contains yield keyword is actually calling a generator constructor. This will return a new generator instance that you need to pass into StartCoroutine as argument. Therefore the StartCortoutine(myRoutine()) pattern. The unity engine remembers this generator, retrieves the next value (which executes your code until the yield) and retrieves the yielded value. Now depening on what was yielded, it may postpone the next iteration over the generator (for example, wait for some time). But the next iteration is run on the unity main thread, but outside your Update() or any other behaviour method execution. Unity simply retrieves the generator at the beginning of the loop and calls $$anonymous$$oveNext() on it, which executes another part of your code (and possibly yields another value).
An exercise: Ins$$anonymous$$d of calling StartCoroutine(), try to iterate over the routine yourself (using a foreach or just how you'd iterate over any other IEnumerable) and print every value inside.
Answer by Kiwasi · Jan 19, 2015 at 05:31 AM
You can't yield inside of FixedUpdate. Call another function, and yield there.
Answer by tanoshimi · Jan 19, 2015 at 07:21 AM
You might want to know that:
InvokeRepeating("x", 1,1);
is generally slightly faster than:
StartCoroutine("x");
IEnumerator x() {
yield return new WaitForSeconds(1);
}
There's plenty of other reasons to use coroutines, but "it's faster [than] invoke" is not one of them, so if that's your only reason for introducing yield, I'd stop now. Try one of the following to learn more:
I didn't know it's faster but i sure know that it's a lot easier, and i always used invoke, but i wanted to use yield for faster process, but nope, it wouldn't work in FixedUpdate and as Thom Denick said, it won't work in any Unity lifecycle
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How do I solve this error? 2 Answers
A bunch of errors that I can't fix 1 Answer
Error CS0029: Cannot implicitly convert type to UnityEngine.UI.Transform 1 Answer