0

I am programming a task in VR where the user hears an audio file with a certain amount of numbers and needs to press a key after that. If he did it right then he should press "r" and an audio file that is one number longer will be played. If he did it wrong he should press "w" and if it was his first wrong answer after a right answer an audio file will be played that has the same amount of numbers than before. If he did it wrong and already did it wrong right before that the amount of numbers is reduced by one.

In total there will be 10 audio files which is why I decided to use a for loop.

But now I don't know how I can make the for loop wait for the user input. I've also read that it is in general not god to use a for loop when you have to wait for a user input but I don't know what else I can do.

Here is my code so far:

IEnumerator playDSBtask()
{
   bool secondWrong = false;

   fillList();

   for (int i = 0; i < 10; i = i + 1)
   {
        List<AudioSource> x = chooseList(score);
        AudioSource myAudio = x[0];
        float duration = myAudio.clip.length;
        myAudio.GetComponent<AudioSource>();
        myAudio.Play();

        yield return new WaitForSeconds(duration + 5);
        if (Input.GetKeyDown("r"))
        {
            score++;
            secondWrong = false;
        }
        else if (Input.GetKeyDown("f") && secondWrong == false)
        {
            secondWrong = true;
        }
        else if (Input.GetKeyDown("f") && secondWrong == true)
        {
            score--;
        }
    
        x.Remove(myAudio);
    }
}

But this won't work since the for loop will just continue if none of the if or else if statements are true and therefor executed.

1 Answer 1

2

Using a for loop in your case is totally fine since it is in a Coroutine where you yield inside of it so there will be no endless loop and therefore freeze of the main thread.

You could probably use WaitUntil something like

...
yield return new WaitForSeconds(duration + 5);

// Wait until any o the expected inputs is pressed
yield return WaitUntil(() => Input.GetKeyDown("r") || Input.GetKeyDown("f"));

// then check which one exactly
if (Input.GetKeyDown("r"))
{
...

alternatively this could also be done in a more generic way but also more error prone

...
yield return new WaitForSeconds(duration + 5);

// wait until something breaks out of the loop
while(true)
{
    // check if any key was pressed
    if(Input.anyKeyDown)
    {
        // handle r key
        if (Input.GetKeyDown("r"))
        {
            score++;
            secondWrong = false;

            // important!
            break;
        }
        else if (Input.GetKeyDown("f"))
        {
            if(!secondWrong)
            {
                secondWrong = true;
            }
            else
            {
                score--;
            }

            // Important!
            break;
        }
    }

    // if nothing called break wait a frame and check again
    yield return null;
}

x.Remove(myAudio);
...

In general you might want to use KeyCode.F and KeyCode.R instead of strings.


From a UX perpective though you would either want to reduce the 5 seconds wait or/and show some kind of UI feedback for when user input is handled/awaited.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for your answer! I will try that now! Is it possible to have to yield statements in a coroutine or would I have to combine the waitForSeconds and WaitUntil statements?
@sarahrht You can have as many yield lines in your IEnumerator as you want/need. Or do you mean you want to check both conditions at the same time so wait until either there is User Input or the time has passed?
Yes I meant if it is possible to have as many yield lines as I want to. Thanks a lot for your help, it works now!
@sarahrht please remember to accept answers that solved you question ()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.