IEnumerator JobsSpawnerCoroutine() { // ensure that the headset is connected and ready before starting any recording var nextFrameAwaiter = new WaitForEndOfFrame(); while (!FoveManager.IsHardwareConnected()) { yield return(nextFrameAwaiter); } // if the recording rate is the same as the fove rendering rate, // we use a coroutine to be sure that recorded gazes are synchronized with frames if (recordingRate == RecordingRate._70FPS) { // Coroutines give us a bit more control over when the call happens, and also simplify the code // structure. However they are only ever called once per frame -- they processing to happen in // pieces, but they shouldn't be confused with threads. StartCoroutine(RecordDataCoroutine()); } else // otherwise we just start a vsynch asynchronous thread { StartCoroutine(RecordFoveTransformCoroutine()); collectThread = new Thread(CollectThreadFunc); collectThread.Start(); } }