IEnumerator AddRandomNote() { while (true) { // Update rest tracker int lastNoteIndex = Song.Count - 1; string lastNoteName = ((Note)Song[lastNoteIndex]).name; if (lastNoteName == "REST") { elapsedSinceRest = 0; } else { elapsedSinceRest += Song[lastNoteIndex].duration; } // Randomize note name, unless it's time for a compulsory rest string newNoteName = lastNoteName; if (elapsedSinceRest < MaxTimeBetweenRests) { while (newNoteName == lastNoteName) { newNoteName = NotesAllowed[UnityEngine.Random.Range(0, NotesAllowed.Count)]; // Note: min inclusive, max exclusive } } else { newNoteName = "REST"; } float newNoteDur = UnityEngine.Random.Range(1, (int)(maxNoteDuration)); // Fill in note properties Note newNote = new Note(newNoteName, newNoteDur); newNote.yOffset = newNoteName == "REST" ? Song[lastNoteIndex].yOffset : notePosLookup[newNoteName]; // Add note to song Song.Insert(lastNoteIndex + 1, newNote); if (WritingOn) { ReaderWriter.WriteSong(Song, "HELLO.txt", 60, bassClefMode); } // Spawn corresponding platform SpawnPlatform(lastNoteIndex + 1); // Calculate the timing error (negative if we're ahead, positive if we're behind) float error = addNoteTime - currTime; // Set the next new note to spawn as soon as this new one's duration has elapsed float durInSec = newNoteDur * 60 / BPM; addNoteTime += durInSec; // Add the current error from the next iteration's delay, so that errors don't build up. yield return(new WaitForSeconds(durInSec + error)); } }