2015-04-17 83 views
3

我在Unity3d工作(這更多的是C#的問題,所以我懷疑這是一個問題)。我正在研究一個像在Civilization中發現的運動系統。我有一個循環設置,所以你可以每回合移動2格。這工作正常。我點擊10格外的方格,然後需要5回合才能到達那裏。現在即時嘗試使塊之間的典當lerp。我有lerp工作,問題是,它從當前的瓷磚跳到第一個瓷磚,然後過渡到它應該是的第二個瓷磚。我使用一個協程來完成這項工作,而不是更新功能(因爲更新會導致它只能到最終目的地,而不是從當前,到第一,到第二)。因此,即將進入的是循環,通過棋子所經過的每一步棋,在繼續其自己的循環之前不等待協程完成。這裏是代碼使循環等待動作來完成

public void MoveNextTile() 
{ 
    float remainingMoves = moveSpeed; 
    while (remainingMoves > 0) 
    { 

     if (currentPath == null) 
      return; 
     //Get the cost from current tile to next tile 
     remainingMoves -= map.CostToEnterTile(currentPath[0].x, currentPath[0].y, currentPath[1].x, currentPath[1].y); 

     //Move us to the next tile in the sequence 
     toVector = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y); 
     Vector3 fromVec = transform.position; 
     StartCoroutine(MoveObject(fromVec, toVector, 1.0f)); 


     //transform.position = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y); 

     //Remove the old current tile 

     this.tileX = currentPath[0].x; 
     this.tileY = currentPath[0].y; 
     currentPath.RemoveAt(0); 
     if (currentPath.Count == 1) 
     { 
      this.tileX = currentPath[0].x; 
      this.tileY = currentPath[0].y; 
      currentPath = null; 
     } 


    } 

} 
IEnumerator MoveObject(Vector3 source, Vector3 target, float overTime) 
{ 
    float startTime = Time.time; 
    while (Time.time < startTime + overTime) 
    { 
     transform.position = Vector3.Lerp(source, target, (Time.time - startTime)/overTime); 
     yield return null; 
    } 
    transform.position = target; 

} 

我知道這是一個菜鳥問題。我從來沒有必要在C#中做到這一點。預先感謝所有幫助

+0

我不熟悉團結協程,但好像你可以使用這個ManualResetEvent的,只是調用協程開始後做ManualResetEvent.WaitOne,並在MoveObject程序時,它是完整的呼叫的ManualResetEvent.Set –

+0

標籤[tag:Unity]的第一句話是**「不要在關於UNITY GAME ENGINE的問題上使用(改用:[tag:unity3d])!!」** –

回答

3

我建議你研究協程的工作方式。

您的協同程序沒有完全執行,然後返回以完成MoveNextTile函數的其餘部分。它實際上執行直到第一個yield語句,然後繼續執行MoveNextTile。每個後續幀將繼續運行協程的「步驟」,直到下一個yield語句嘗試複製異步方法。

你想要做的是告訴你的程序明確地等待你的協同程序完成。爲此;

yield return StartCoroutine(MoveObject(fromVec,toVector,1.0f));

當然,你只能在IEnumerator中使用這個語句。所以你將不得不將你的voidNextNextTile函數改爲IEnumerator MoveNextTile。你最終得到如下的東西;

public IEnumerator MoveNextTile() { 

    // Ommited 
    while (remainingMoves > 0) { 
     //Ommited 
     yield return StartCoroutine(MoveObject(fromVec, toVector, 1.0f)); 
     // Now MoveNextTile will continue after your MoveObject coroutine finishes. 
    } 
}