Why Is This Coroutine Freezing my Unity5 editor?

I feel bad posting this question since it has been posted so many times in so many different ways,

Such as here: Why does this coroutine freeze my game? - Questions & Answers - Unity Discussions

And here: Waiting for Input via Coroutine - Questions & Answers - Unity Discussions

And here also: Reddit - Dive into anything

But I have come to my wits end! Even when I copy the exact code I’m seeing on those pages, my Unity player still freezes as soon as I hit play. What I am trying to do is write a dirt-simple function that waits for a button input from the user, using a coroutine. I’ve tried several ways of doing this, and they all freeze my game:

	private void SpaceBarToContinue () {
		print ("Press spacebar to continue...");
		StartCoroutine(WaitForButtonPress(KeyCode.Space));
	}

	/*
           //This freezes the game
	private IEnumerator WaitForButtonPress (KeyCode button) {
		do {
			yield return null;
		} while (!Input.GetKeyDown (button));
	}

           //This also freezes the game
	private IEnumerator WaitForButtonPress (KeyCode button) {
		while (true) {
			if(Input.GetKeyDown (button))
				yield break;
			yield return null;
		}
	}

           //Surprise! This freezes the game
	private IEnumerator WaitForButtonPress (KeyCode button) {
		while (true) {
			if(!Input.GetKeyDown (button))
				yield return null;
			yield break;
		}
	}

	*/

           //Hey maybe this time- nope! This freezes the game
	private IEnumerator WaitForButtonPress (KeyCode button) {
		while (true) {
			if(!Input.GetKeyDown (button))
				yield break;
		}
		yield return null;
	}

When I run the debug, the program just keeps cycling forever, never giving me the opportunity to end the cycle with button input. I’ve force-quit about 20 times now trying lots of different variations on the above, and I’ve finally just decided to ask for help.

Can someone please clue me in to as what simple thing I must be missing here? I would greatly, greatly appreciate any assistance on this matter.

It’s freezing because you’ve written an infinite loop that never hands over control back to the main thread. Coroutines run on the MAIN THREAD. So if you keep it locked in a loop nothing else can happen.

try this:

private IEnumerator WaitForButtonPress (KeyCode button) {
     while (true) {
         if(!Input.GetKeyDown (button)) {
             break;
          }
          // Release the thread until the next game loop.
          yield return new WaitForFixedUpdate();
     }
 }

Tried this myself and ran into an issue using “break” to get out of the loop. A more readable way to handle this is to set a bool inside of the coroutine itself and check against that. Here’s a C# script that worked on a Unity 5.4 project:

using UnityEngine;
using System.Collections;

public class TestingCoroutine : MonoBehaviour {


	void Start () {
		//Start up and run the SpaceBarToContinue
		SpaceBarToContinue ();
	
	}
		
	private void SpaceBarToContinue () {
		print ("Press spacebar to continue...");
		StartCoroutine(WaitForButtonPress(KeyCode.Space));
	}

	private IEnumerator WaitForButtonPress (KeyCode button) {
		//Set your own toggle
		bool waiting = true;

		//While loop based on this toggle being true
		while (waiting) {
			//Check for "button" being pressed down. In this case KeyCode.Space
			if(Input.GetKeyDown (button)) {
				//It was pressed, toggle waiting off so the coroutine will end
				waiting = false;
				//Do what you want now
				Debug.Log("SPACE BAR PRESSED. DO WHAT YOU WANT");
			}

			//If the space bar wasn't pressed, wait for the next fixedupdate and check again
			yield return new WaitForFixedUpdate();
		}
	}
}