我正在制作一个基本的游戏而且我卡住了。这个想法是创建一个随机数字阵列并在屏幕上打印数字,并要求用户根据规则点击按钮。例如,规则可以是:如果数字是偶数则单击左按钮,如果数字是奇数则单击右按钮。用户有2秒钟回答每个号码,两秒钟后打印下一个号码。如果用户在2秒之前单击按钮,则答案将保存在阵列中并打印下一个数字(无需等待2秒钟即可完成)。问题是我无法在循环中使用cancelWait变量实现等待协程。它看起来像在循环中所有协同程序由于某种原因同时被解雇。这是我的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DemoGM : MonoBehaviour {
int[] numberArray = new int[10];
public Text mainText;
private float waitSystem;
// Use this for initialization
void Start () {
for (int i = 0; i < 10; i++) {
numberArray[i] = Random.Range(0, 10);
print(numberArray[i]);
}
StartGame();
}
// Update is called once per frame
void Update () {
}
void StartGame() {
StartCoroutine(PrintNumbers());
}
IEnumerator PrintNumbers() {
mainText.text = "Rule";
yield return new WaitForSeconds(3);
for (int i = 0; i < 10; i++) {
mainText.text = numberArray[i].ToString();
StartCoroutine(WaitForSecondsOrTap(3));
}
}
public void OddButtonClicked() {
//Save Answer
cancelWait();
}
public void EvenButtonClicked()
{
//Save Answer
cancelWait();
}
IEnumerator WaitForSecondsOrTap(float seconds)
{
waitSystem = seconds;
while (waitSystem > 0.0)
{
waitSystem -= Time.deltaTime;
yield return 0;
}
}
private void cancelWait()
{
waitSystem = 0.0f;
}
}
答案 0 :(得分:1)
有许多方法可以中断协同程序功能。您可以使用yield break
退出协同程序功能。将waitSystem
变量设置为0
,就像你做一样,退出WaitForSecondsOrTap
协程功能应该工作,但最好使用StopCoroutine
的功能。
启动WaitForSecondsOrTap
协程,获取StopCoroutine
函数返回的引用,当需要停止它时,将该引用传递给StopCoroutine
函数。您也可以将该变量用于yield
或等待该协程完成。
它看起来像在循环中所有协同程序同时被解雇 某种原因
这是因为您的for循环不等待每个WaitForSecondsOrTap
调用完成。要等待每个WaitForSecondsOrTap
来电,请将其投放。因此,StartCoroutine(WaitForSecondsOrTap(3));
应为yield return StartCoroutine(WaitForSecondsOrTap(3));
这就是代码的样子。它显示了停止corutine的正确方法,并阻止在当前调用完成或返回之前调用WaitForSecondsOrTap
。:
Coroutine waitCoroutine;
void StartGame()
{
StartCoroutine(PrintNumbers());
}
IEnumerator PrintNumbers()
{
mainText.text = "Rule";
yield return new WaitForSeconds(3);
for (int i = 0; i < 10; i++)
{
mainText.text = numberArray[i].ToString();
//stop old coroutine
cancelWait();
//Start new one then return a reference of it
waitCoroutine = StartCoroutine(WaitForSecondsOrTap(3));
//Wait for this instance of coroutine to finish then continue with the program
yield return waitCoroutine;
}
}
public void OddButtonClicked()
{
//Save Answer
cancelWait();
}
public void EvenButtonClicked()
{
//Save Answer
cancelWait();
}
IEnumerator WaitForSecondsOrTap(float seconds)
{
waitSystem = seconds;
while (waitSystem > 0.0)
{
waitSystem -= Time.deltaTime;
yield return 0;
}
}
private void cancelWait()
{
if (waitCoroutine != null)
StopCoroutine(waitCoroutine);
}
答案 1 :(得分:0)
StartCoRoutine()
几乎立即返回,所以是的,循环中的所有协程都将立即开始并将同时执行。相反,如果相反,在StartGame()
中,您使用重复设置为2秒来启动InvokeRepeating()
,并使用索引的类变量调用打印新数字的例程。索引将在打印数字之前或之后递增,以及用户单击鼠标按钮时。此外,无论何时单击鼠标按钮,您都可以使用cancelInovke()
取消当前InvokeRepeating()
,并为InvokeRepeating()
发出新的0
初始延迟,并为重复发出2延迟。
我可能在那里遗漏了一些东西,但我认为这会让你接近你所追求的东西。听起来像一个有趣的游戏。