2017-01-02 102 views
0

我正在爲移動設備製作一個簡單的塔防遊戲。我寫了一個函數來檢查,如果放置塔將阻止敵人到達他們的目標:檢查navmesh路徑是否被阻塞需要太長時間

public bool CheckPathNotBlocked(Vector3 pos) 
{ 
    navmesh_obstacle_tester.gameObject.SetActive(true); 
    navmesh_obstacle_tester.position = pos; 
    NavMeshPath path = new NavMeshPath(); 
    botsInPlay[botsInPlay.Count - 1].CalculatePath(enemyBase.position, path); 
    navmesh_obstacle_tester.gameObject.SetActive(false); 
    return path.status == NavMeshPathStatus.PathComplete; 
} 

的navmesh_obstacle_tester是一個空的遊戲物體附有一個NavMeshObstacle。 BotsInPlay是敵方NavMeshAgents的列表,所以我使用最近生成的敵人來檢查路徑。其實,這工作,但沒有及時阻止我從塔被置於:

public void PlaceTower(Vector3 pos, int tType) 
{ 
    if (!F_BotsManager.bots.CheckPathNotBlocked(pos)) return; 

    // rest of my code to place a tower 
} 

函數退出,如果路徑被完全阻斷,但將將例如,方框的路徑塔前不會退出一旦我在所有敵人周圍形成了一個塔形環,就不會再放置塔,但是放置完成環的最後一座塔。

我已閱讀in the docs路徑計算可能需要幾幀,這可能是問題的原因?我該如何解決這個問題?

回答

0

您沒有顯示調用PlaceTower函數的方式和位置。這對了解如何提供幫助非常重要。

我該如何解決這個問題?

任何需要這麼長時間才能做的事情,你必須在Unity中等待它,應根據事情做一個協程或一個線程。在這種情況下,應該使用協程來等待代碼中的其他內容可以繼續運行。

public IEnumerator PlaceTower(Vector3 pos, int tType) 
{ 
    while (!F_BotsManager.bots.CheckPathNotBlocked(pos)) 
    { 
     Debug.Log("waiting!"); 
     yield return null; 
    } 

    // rest of my code to place a tower 
} 

現在,任何你調用這個函數的地方現在都應該用StartCoroutine(PlaceTower(yourPost,yourIntType));代替。您必須重構整個代碼以適應協程的使用。

+0

感謝您的回覆,但CheckPathNotBlocked函數在我的文章中清晰可見!通過在固定更新中單擊鼠標來發生地點塔。將CheckPathNotBlocked放在while循環中將導致無限循環 - 它返回一個布爾值;第一次被稱爲路徑永遠不會被阻止。我知道你是一位優秀的編碼員,過去曾多次幫助過你 - 請你重新閱讀我的文章?謝謝。 – Absinthe

+0

嗨,我剛剛意識到'CheckPathNotBlocked'在你的問題。我不知道我是如何錯過的。 *「將CheckPathNotBlocked放在while循環中會導致無限循環」*這在非協程函數中是正確的。這就是爲什麼我使用'yield return null;'的協同函數。請嘗試我的答案。只要您的'CheckPathNotBlocked'函數在某個點返回'true',它就不應該處於無限循環。 – Programmer

+0

感謝您的澄清。我按照你的建議嘗試過,沒有無限循環,但沒有奏效,塔仍然放置。最後一個塔樓的NavMeshPathStatus = PathComplete,並且僅在隨後嘗試放置塔樓時才顯示「未完成」。我已經嘗試將CheckPathNotBlocked與IF語句放在不同的方法中,然後調用PlaceTower,但結果相同。我試過在重生點上使用NavmeshAgent,而不是最後一個產生的敵人,仍然是一樣的。我已經改變了NavMesh障礙物在各種可能組合中的設置,但沒有歡樂。有任何想法嗎? – Absinthe