制作一个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 反馈]
我正在 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 反馈]