2012-10-24 47 views
2

我決定創建一個像遊戲一樣的內存,以用unity3d學習遊戲開發。
玩家點擊卡片後,遊戲應等待2秒鐘,然後再將卡片翻轉回來。
yield return new WaitForSeconds(2) -statement應該是完美的,但它的作用是不執行任何函數行。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,工作一切正常(除了玩家看不到第二張牌,因爲它立即翻轉)。

我的收益回報有什麼問題?

+2

+1我真的很喜歡戲劇性的標題。 –

回答

3

通過添加yield return,您已將其設置爲迭代器塊。迭代器塊在迭代時僅執行 - 它們展示「延遲執行」。所以爲了這個工作,你需要消耗返回的枚舉。在最簡單的,這可能是:

foreach(var obj in FlipCardFaceUp(card)) {} 

然而,也有可能是團結預計這一被消費作爲協程更新一些其他的方式:確實;看到Botz3000的回答。在大多數用戶界面中,更新代碼中的阻塞是不好的(它會阻止抽取),但是如果沒有統一知識,我不能建議正確的實現。據我所知,這可能需要您打開調用代碼到迭代器塊:

// 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; 
} 
5

您需要使用StartCoroutine啓動協程:

StartCoroutine(FlipCardFaceUp(card)); 

正如馬克Gravell說,一個迭代器塊需要被枚舉來做任何事情,這就是StartCoroutine所做的(異步地,可能是統一需要的其他東西)。 「異步」部分也是爲什麼在協程完成之前立即打印"Returned from FlipCard"

如果你想等待你的協程在打印"Return from FlipCard"前完成,你可以使用yield,太:

Debug.Log("Call FlipCard"); 
yield return StartCoroutine(FlipCardFaceUp(card)); 
Debug.Log("Returned from FlipCard"); 

請注意,您不能使用yieldUpdateFixedUpdate內。

編輯:看到您正在嘗試在OnGUI方法中執行此操作,更好的方法可能是僅使用Card類型的變量,以便您可以記住要翻轉哪個卡。然後,在Update中,您可以檢查該變量,如果它表示需要翻轉卡,則可以啓動協程。

+0

有趣;所以這是「團結期望這種消費作爲一個協同例程的其他方式」 –

+0

如果我用'StartCoroutine(「FlipCardFaceUp」,卡)調用方法沒有什麼變化' – Lennart

+0

@Lennart你是否嘗試過使用'yield return StartCoroutine (FlipCardFaceUp(card))'等待協程完成? (見編輯) – Botz3000

0

如果您通過StartCoroutine調用方法,則只能使用yield return new WaitForSeconds(2)。你的第一塊代碼將立即返回,但Unity3d將負責運行你的方法的其餘部分(包括2秒等待並繼續)。