制作一个for循环等待用户输入

Making a for loop wait for user Input

我正在 VR 中编写一个任务,用户听到一个包含一定数量数字的音频文件,然后需要按一个键。如果他做对了,那么他应该按“r”,然后将播放一个长一个数字的音频文件。如果他做错了,他应该按“w”,如果这是他在正确答案后的第一个错误答案,将播放一个与之前数量相同的音频文件。如果他做错了,而且之前已经做错了,那么数字减一

总共会有 10 个音频文件,这就是我决定使用 for 循环的原因。

但现在我不知道如何让 for 循环等待用户输入。我还读到,当您必须等待用户输入时,使用 for 循环通常不是上帝,但我不知道我还能做什么。

到目前为止,这是我的代码:

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);
    }
}

但这不会起作用,因为如果 if 或 else if 语句的 none 为真并因此执行,for 循环将继续。

在你的情况下使用 for 循环是完全没问题的,因为它在协程中,你在其中屈服,所以不会有无限循环,因此会冻结主线程。

您可能会使用 WaitUntil 类似

的东西
...
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"))
{
...

或者,这也可以以更通用的方式完成,但也更容易出错

...
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);
...

一般来说,您可能希望使用 KeyCode.F and KeyCode.R 而不是字符串。


从用户体验的角度来看,尽管您可能想要减少 5 秒的等待时间 or/and 当用户输入 handled/awaited.[=17= 时显示某种 UI 反馈]