Article: Avoiding The Unity Freeze

Unity is a wonderful system for developing real-time software such as games, and its debugging system is top-notch. You can print log messages, errors, or warnings, and filter easily. Each issue even presents a full stack trace and you can link to a debugger for even finer control.

Infinite loops, though, are a real killer. The operating system halts interaction on threads stuck in a super long (or infinite) loop. If the thread is stuck, it can't communicate with outside threads, and the entire system has no way to detect its own stuck-ness. So, Unity freezes and the only option is to kill it and restart.

No matter how aware you are of this problem, it's easy to make mistakes when writing infinite loops, which are often necessary (or at least preferred) in the structure of real-time software.

The solution is to count the number of loops and stop after an inconceivable number of cycles have run. This takes a little extra code and processing, but it'll stop Unity from freezing and alert you to the problem area..

Let's say you have a while loop that goes until some Boolean condition isDone is met:

while (isDone == false) {
    // ...
    // your code here
    // ...

    if (someCondition)
        isDone = true;
}

If someCondition is never true, this loop could run forever and lock up Unity. The solution is to count the number of loops and break when we've run too many times.

int loops = 0;
while (isDone == false) {
    // ...
    // your code here
    // ...

    if (someCondition)
        isDone = true;

    // prevent an infinite loop
    ++loops;

    // set this value to a number of loops that could never happen
    // (this will depend on exactly what the loop is doing)
    if (loops > 100000) {
        // LogError if this is a critical problem; otherwise LogWarning
        // this shows a stacktrace and tells you where the problem occurred
        Debug.LogError ("Infinite loop detected in {name}");

        // you may want to return here instead if following code depends
        // on the loop completing successfully
        break;
    }
}

If you use several infinite loops, it may help to store a MAX_LOOPS constant in a globally accessible class so you don't have to use a magic number.

If you're worried about performance (which you really shouldn't be - this is a pretty minor hit), then you can have this code only run if Application.IsEditor() is true, so it won't run in your release build.

So, this is how I stop Unity from locking in an infinite loop and avoid the frustrating need to kill it through task manager. Hope you find this article helpful.

If you're interested in game development, be sure to join our community of game developers and our monthly game jams.