[C#] How to write a generic yield return WaitForCondition with an expression as argument ?
I wondered how one could write something like a yield return new WaitForCondition
which allows you to wait until a condition is matched. I thought about making it with a helper function and a while
- loop but I am not very satisfied with it, since it requires an unqiue WaitForCondition for each usage, as well as reference to a field and it does not allow expressions, like in if
- statements, they are converted into a value, not preserving the expression as is.
In the end, I would like to be able to do something like this:
public class MyClass{
bool myBool = false;
public IEnumerator MyWait(){
yield return new WaitForCondition(myBool == true);
// doSomething
}
}
I do know that in this example, I could instead write it similar to the accepted solution to this question: Waiting for Input via Coroutine
However, on purpose, I would like to require a bool expression as argument, no matter whether it is yield return new WaitForCondition( b == true );
or yield return StartCoroutine(WaitForCondition(b == true));
The examples might be misleading in terms of usability, imagine more complex bool expressions.
How would I achieve this ? I do know there are workarounds using Properties, but I would like to force this way. The main problem for me is preserving the expression as is instead of converting it to a value, as one is waiting for a condition to be matched, hence requiring to continuously checking for it.
Answer by jdean300 · Feb 10, 2017 at 08:52 PM
This already exists: https://docs.unity3d.com/ScriptReference/WaitUntil.html
Just to explain things a bit more - you cannot pass a statement like b == true
into a function and expect it to be evaluated multiple times - the statement is evaluated once and then given to the function. If you want a function to act based on some passed in argument that needs to be evaluated multiple times, you have to pass a lambda.
A lambda is fancy speak for a function. $$anonymous$$ore precisely it is a function with an execution context(local variables and such) wrapped up into one. What WaitUntil does is take a lambda that you give it that returns a bool and calls it every frame. When it returns true, WaitUntil breaks.
Here is an example of using WaitUntil with a typical function (alan$$anonymous$$emp already posted a lambda example):
private IEnumerator LookAt$$anonymous$$e() {
// pass a function to WaitUntil
yield return new WaitUntil(BIsTrue);
}
// this function will be called by WaitUntil every frame
private bool BIsTrue() { return b == true; }
Thank you very much! I hanged myself a bit with the term "condition", wondered why Unity would not have something like this as default. Great to know this exists! Also, a great thank you for your explanation!
Answer by dan_ginovker · Feb 16 at 09:42 AM
If you're like me and want a custom implementation of WaitUntil or WaitForSeconds, check out CustomYieldInstruction:
https://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html
Your answer
Follow this Question
Related Questions
Checking Internet inside a Coroutine 0 Answers
Cannot Call Function from Another Function 1 Answer
Nothing after coroutine gets executed 1 Answer
IEnumerator skips remaining function after yield 1 Answer
Listening keypresses out of Update? 1 Answer