C# 返回新的WaitForSeconds(2)销毁函数
我决定创建一个类似记忆的小游戏,用unity3d学习游戏开发。C# 返回新的WaitForSeconds(2)销毁函数,c#,unity3d,yield-return,C#,Unity3d,Yield Return,我决定创建一个类似记忆的小游戏,用unity3d学习游戏开发。 游戏应在玩家点击卡片后等待2秒钟,然后再将卡片翻转回来。 yield return new WaitForSeconds(2)-语句应该非常适合这一点,但它的效果是不执行函数的任何一行 这是我的密码: 这将构建卡片网格(带有按钮),并在单击卡片时调用一个函数来翻转卡片 Card card = grid[i, j]; if (GUILayout.Button(new GUIContent((Texture) Resources.Lo
游戏应在玩家点击卡片后等待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
如果我移除了收益回报所需的东西,一切正常(除了玩家看不到第二张牌,因为它会立即翻转回来)
我的收益率返回有什么问题?通过添加收益率返回
,您已经将其设置为迭代器块。迭代器块仅在迭代时执行——它们显示“延迟执行”。因此,要使其工作,您需要使用返回的枚举。最简单的情况是:
foreach(var obj in FlipCardFaceUp(card)) {}
然而,unity可能会以其他方式将其作为共同例程更新来使用:的确;见Botz3000的答案。在大多数UI中,更新代码中的阻塞是不好的(它会阻止绘制),但是如果没有unity知识,我就无法建议正确的实现。据我所知,它可能希望您将调用代码转换为迭代器块:
// 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;
}
您需要使用以下命令启动协同程序:
正如Marc Gravell所说,需要枚举迭代器块才能执行任何操作,startcroutine
就是这样做的(异步的,可能还有unity需要的其他东西)。“异步”部分也是在协同程序完成之前立即打印“从FlipCard返回的”
的原因
如果您想在打印“从FlipCard返回”
之前等待合作程序完成,您也可以使用收益率
:
Debug.Log("Call FlipCard");
yield return StartCoroutine(FlipCardFaceUp(card));
Debug.Log("Returned from FlipCard");
请注意,您不能在Update
或FixedUpdate
中使用yield
编辑:看到您正试图在
OnGUI
方法中执行此操作,更好的方法可能是在那里使用Card
类型的变量,以便记住要翻转的卡。然后,在Update
中,您可以检查该变量,如果该变量表示需要翻转卡片,则可以启动协同程序。如果您通过startcroutine
调用方法,则只能使用yield return new WaitForSeconds(2)
。您的第一块代码将立即返回,但Unity3d将负责运行方法的其余部分(包括2秒钟的等待和随后的继续)。+1我真的很喜欢戏剧标题。有趣;这就是“unity希望将其作为协作例程使用的另一种方式”如果我使用start例程(“FlipCardFaceUp”,card)”调用该方法,则不会发生任何变化@Lennart您是否尝试过使用yield return start例程(FlipCardFaceUp(card))
等待协作例程完成?(请参见编辑)如果我尝试此操作,则不会再创建我的卡。可能需要知道的是,该方法是由OnGUI()方法调用的。我要发布我所有的代码吗?@Lennart OnGUI可以在每帧调用几次,不应该被延迟。据我所知,你不能从那里开始合作。你为什么不在另一个事件中处理呢?
Debug.Log("Call FlipCard");
yield return StartCoroutine(FlipCardFaceUp(card));
Debug.Log("Returned from FlipCard");