我决定创建一个像游戏一样的小记忆,用unity3d学习游戏开发
在玩家点击卡片之后,游戏应该等待2秒钟
yield return new WaitForSeconds(2)
- 语句应该是完美的,但它有效果,没有执行函数行。
这是我的代码:
这会构建卡片网格(带按钮),并在单击卡片时调用功能以翻转卡片。
Card card = grid[i, j];
if (GUILayout.Button(new GUIContent((Texture) Resources.Load(card.getImg()), ""), GUILayout.Width(cardWidth))) {
Debug.Log("Call FlipCard");
FlipCardFaceUp(card);
Debug.Log("Returned from FlipCard");
}
这是翻转功能:
System.Collections.IEnumerable FlipCardFaceUp(Card card) {
Debug.Log("This isn't shown in the console");
card.isFaceUp = true;
if (!cardsFlipped.Contains(card)) {
cardsFlipped.Add(card);
if (cardsFlipped.Count >= 2) {
playerCanClick = false;
//Waiting 2 seconds before the cards are flipped back or are removed
yield return new WaitForSeconds(2);
if (cardsFlipped[0].id == cardsFlipped[1].id) {
cardsFlipped[0].isMatched = true;
cardsFlipped[1].isMatched = true;
} else {
cardsFlipped[0].isFaceUp = false;
cardsFlipped[1].isFaceUp = false;
}
cardsFlipped.Clear();
playerCanClick = true;
}
}
}
当我测试游戏并点击卡片时,这是控制台输出:
Call FlipCard
Returned from FlipCard
如果我删除了yield return
所需的东西,那么一切正常(除了玩家看不到第二张牌,因为它会立即翻回)。
我的收益率有什么问题?
答案 0 :(得分:5)
您需要使用StartCoroutine
启动协程:
StartCoroutine(FlipCardFaceUp(card));
正如Marc Gravell所说,需要枚举一个迭代器块来做任何事情,这就是StartCoroutine
所做的事情(异步,也可能是团结所需的其他东西)。 “异步”部分也是在Coroutine完成之前立即打印"Returned from FlipCard"
的原因。
如果您想在打印"Return from FlipCard"
之前等待Coroutine完成,您也可以使用yield
:
Debug.Log("Call FlipCard");
yield return StartCoroutine(FlipCardFaceUp(card));
Debug.Log("Returned from FlipCard");
请注意,您无法在yield
或Update
内使用FixedUpdate
。
OnGUI
方法中执行此操作,更好的方法可能是使用Card
类型的变量,以便您可以记住要翻转的卡片。然后,在Update
中,您可以检查该变量,如果它表示需要翻转卡片,则可以启动协程。
答案 1 :(得分:3)
通过添加yield return
,您已将其设为迭代器块。迭代器块仅在迭代时执行 - 它们演示“延迟执行”。因此,要实现此功能,您需要使用返回的枚举。最简单的是,这可能是:
foreach(var obj in FlipCardFaceUp(card)) {}
然而,可能还有一些其他方式,团结希望将其作为一个共同例程更新:来消费;看Botz3000的答案。在大多数UI中,更新代码中的阻塞是不好的(它阻止了绘制),但是如果没有统一知识,我就无法建议正确的实现。据我所知,它可能希望您将调用代码转换为迭代器块:
// the following is COMPLETE GUESSWORK - I've never coded unity
// update: wrong: see Botz3000's answer, and `StartCoroutine`
Card card = grid[i, j];
if (GUILayout.Button(new GUIContent((Texture) Resources.Load(card.getImg()), ""), GUILayout.Width(cardWidth))) {
foreach(var step in FlipCardFaceUp(card)) yield return step;
}
答案 2 :(得分:0)
如果您通过yield return new WaitForSeconds(2)
调用方法,则只能使用StartCoroutine
。您的第一个代码块将立即返回,但Unity3d将负责运行您的方法的其余部分(包括2秒等待并在之后继续)。