Is it possible to have a function that can recursively call itself that also has yield statements? ie
function MyFunction () {
yield;
MyFunction();
}
Is it possible to have a function that can recursively call itself that also has yield statements? ie
function MyFunction () {
yield;
MyFunction();
}
Yes, though you have to explicitly give the function a type of IEnumerator.
#pragma strict
function Start () {
MyCoroutine();
}
function MyCoroutine() : IEnumerator {
Debug.Log("MyCoroutine() Called: " + Time.time);
yield WaitForSeconds(1.0);
MyCoroutine();
}
Though I wonder if InvokeRepeating will do what you want to do? Unity - Scripting API: MonoBehaviour.InvokeRepeating
If you only want to execute a coroutine repeatedly, then starting a new one for each pass introduces some overhead that’s easily avoided by using a while loop:
function MyCoroutine() {
while true {
Debug.Log("Hello");
yield WaitForSeconds(1);
}
}
I had tried typing it as IEnumerator, but then it doesn’t seem to execute when called. ie, I have a Debug.Log at the top of the function that is never sent.
My function isn’t as simple as the example I gave. It has logic that branches in different directions based on its input. It’s not a problem of just repeated calling of the function.
After I gave up on this last night, I was reading Programming Pearls. Oddly enough, the first thing I read was talking about how most of the time you can/should use while loops in place of recursive functions. After a night’s sleep and that little insight, it’s a pretty obvious solution. I just got done tinkering and it took less than 3 minutes to update my function.
Thanks guys.
I tried running this code in unity 3.3 and it did not work. It never went through the function a second time.
I would consider using Startcoroutine to fire of the routine again or alternatively don’t call itself again but instead just do proper looping.
Recursion with anything asyncronous is really a can of worms that can easily bite your butt.
i’m with dreamora, worms in worms never ending!
Hey, sorry guys. I know this is super old, but I’m confused why it’s such a problem. How is this:
private IEnumerator RecursiveCoroutine()
{
yield return null;
StartCoroutine(RecursiveCoroutine());
}
any different than:
private IEnumerator LoopCoroutine()
{
while(true)
{
yield return null;
}
}
I’m not entirely sure if Unity’s coroutines are different in this context, but if not, then the top method will cause a StackOverflowException, while the bottom method will not.
Method calls exist in the stack until they’re finished executing, and since the top method keeps calling itself, it never finishes executing while continuously creating more copies of itself on the stack, eventually using up all available system memory to do so.
Okay, wow, first off thanks for the quick response. Secondly, I tested what you said for the last 30 minutes running 20 instances of the two Coroutines. This definitely sounds neurotic lol, BUT for 15 minutes I ran one of them, and the next 15 I ran the other.
I monitored my system resources and saw that with the recursive Coroutine, my memory usage went up linearly over time. On the other hand, the loop Coroutine did not have any memory increase after the game began. Both of them executed the same number of times, despite the memory increase for the recursive Coroutine.
I’m not sure if this is a very solid experiment, but either way my curiosity is quenched. I absolutely thank you for helping me where I couldn’t find any information available. I will definitely use loops in my Coroutines in the future!