-1
\$\begingroup\$

I am currently programming a custom programming language and using Unity to run it. My current issue is that while loops freeze the game when their done. Is there a simple way to wait until end of frame in unity or wait for time?

\$\endgroup\$
1
  • \$\begingroup\$ Sounds like you want a Coroutine. Try implementing your solution based on the documentation there, and if you have trouble applying it to your case, edit your question to show us more details of where you need help. \$\endgroup\$
    – DMGregory
    Nov 18 at 18:03
1
\$\begingroup\$

Instead of using a while loop in Unity, you need to use a Coroutine. To demonstrate how to do this, I will show you what you would normally do, and then show how a coroutine is different.

Traditional While Loop

void Loop()
{
    while(running)
    {
        // Do stuff here
    }
}

Explaination

Coroutines are a lot like threads. They are created as an instance and can be called many times. This can cause many issues, so make sure to lock the coroutine using a bool.

You can do that two ways:

  1. with a lock that doubles as the while loop condition See: Standard;
  2. you can have a separate while loop condition, and release the lock after the loop. See: Alternate;

Instead of void, our return type becomes IEnumerator.

Standard

using System.Collections;
using System.Collections.Generic;

IEnumerator Loop()
{
    if(!running)
    {
        running = true;
        while(running)
        {
            //Do stuff here
            yield return null;
        }
    }
    yield return null;
}

Alternate

using System.Collections;
using System.Collections.Generic;

bool looping = false;
bool running = true;
IEnumerator Loop()
{
    if(!looping)
    {
        looping = true;
        while(running)
        {
            //Do stuff here
            yield return null;
        }
        looping = false;
    }
    yield return null;
}

Step through

(What this does line by line)

  1. We check if the a coroutine is already running.
  2. if not running we set it to running : if is running skip to step 6
  3. we begin the loop
  4. we do our work
  5. we terminate our loop by setting running to false. Note that this can be done outside the loop.
  6. if a loop gets called while running, we skip right to the end and yield return null (wait for the next frame).

We start a Coroutine as follows:

StartCoroutine(Loop());

Valuable Tips

We can break out of the Coroutine using yield break;

If you do not yield return null inside the loop, the coroutine does not return between frames and will wait for the loop to end as in a normal while loop.

We can break out of the while loop in the Coroutine, by using break as per normal.

Links

For more information regarding the proper implementation and use of coroutines:

\$\endgroup\$
1
  • 1
    \$\begingroup\$ "This can cause many issues, so make sure to lock the coroutine using a bool." You shouldn't need to do this. Coroutines run single-threaded on the main thread in Unity taking turns with the rest of the engine loop, so you don't need to worry about something in the main thread or another coroutine changing things while a coroutine is midway through its execution. \$\endgroup\$
    – DMGregory
    Nov 18 at 20:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.