Avoiding the Unity Freeze

Unity is wonderful, and so is its debugging system. You can print log messages, errors, or warnings, and filter easily. You even get a full stack trace for everything.

Infinite loops, though – they’re a real killer. The problem is that the Windows OS halts interaction on threads stuck in a super long (or infinite) loop. If the thread doesn’t communicate with outside threads, the program’s stuck. Unity freezes up and the only option is to kill it and restart.

I’ve known this for a long time, but I still make this same mistake. Sometimes it’s hard to see how a loop can end up running forever.

The solution is to stop the loop after some set number of cycles, more than the loop should run. This takes some extra code and processing, but it’ll send you straight to the loop which could have frozen Unity.

Say you have a while loop that goes until some condition isDone is met.

while( !isDone ) {
    // do stuff
 
    // possibly in some other method
    if( someCondition ) {
        isDone = true;
    }
}

If someCondition is never true, this loop could lock up Unity. The solution is to count the number of loops and not let it get over a set amount.

int loops = 0;
while( !isDone ) {
    // do stuff
 
    // possibly in some other method
    if( someCondition ) {
        isDone = true;
    }
 
    // infinite loop prevention bit
    ++loops;
    if( loops > 100 ) {
        Debug.LogError( "Infinite loop detected" ); // this will show us a stack trace in Unity
        break; // or return if you want to skip the rest of the method
    }
}

If you’re doing this a lot, it might help to store a MAX_LOOPS constant in some globally accessible class so you don’t have to stick a magic number in there. I’ve thought about automating this code into a macro, but since it needs the variable outside the loop and it’s so little code, that would probably be more pain than it’s worth.

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 <code>Application.IsEditor()</code> is true, meaning it’s not a stand-alone release. That’s a bit too much extra code for me, though.

So, that’s how I stop myself from getting annoyed when I screw up and lock Unity in an infinite loop. Hope you’ll find that helpful. Now back to Beat Warp with me.

Leave a Comment