【问题标题】:The Coroutine in Unity functionality anamoly after condition checking条件检查后 Unity 中的 Coroutine 功能异常
【发布时间】:2018-05-16 06:42:40
【问题描述】:

我是 Unity 新手,我只是在创建一个简单的银河射击游戏,我希望只有在玩家出现时才会生成敌人。所以我创建了一个协程来检查playerExists 条件,如果结果是true,它应该进一步每5 秒产生一次敌人。但由于某种原因,它只产生一个敌人。我在这里错过什么了吗? 下面是我的 SpawnManager,其中控制了生成行为。

public class SpawnManager : MonoBehaviour {

[SerializeField]
private GameObject _enemyShipPrefab;
[SerializeField]
private GameObject[] _powerUp;
UIManager _uimanager;


// Use this for initialization
void Start () {
    _uimanager = GameObject.Find("Canvas").GetComponent<UIManager>();
    StartCoroutine(SpawnPowerUps());
    StartCoroutine(SpawnEnemy());

}

IEnumerator SpawnEnemy(){
    while (_uimanager.playerExists == true)
    {
            Vector3 position = new Vector3(Random.Range(-8.23f, 8.23f), 5.7f, 0.0f);
            Instantiate(_enemyShipPrefab, position, Quaternion.identity);
            yield return new WaitForSeconds(5.0f);
    }

}

}

下面是我的 UIManager,我在其中控制播放器的存在。

public class UIManager : MonoBehaviour {

// Use this for initialization
public bool playerExists = false; 
public int playerScores = 0; 
public Sprite[] lives;
public Image playerLivesImagesToBeShown;
public Text playerScoreToBeShown;
public Image titleImage;
public GameObject playerPrefab;
void Start()
{

}

void Update()
{

        if (Input.GetKeyDown(KeyCode.Space) && playerExists == false){
            titleImage.gameObject.SetActive(false);
            Instantiate(playerPrefab, new Vector3(0, 0, 0), Quaternion.identity);
            playerScores = 0;
            playerScoreToBeShown.text = "Score : 0";
            playerExists = true;
        }


}


public void updateLives(int livesToView ){
    playerLivesImagesToBeShown.sprite = lives[livesToView];
            if(livesToView == 0){
                playerExists = false;
                titleImage.gameObject.SetActive(true);
            }
}

【问题讨论】:

    标签: c# unity3d coroutine


    【解决方案1】:

    乍一看您的代码(以及所描述的问题),我会说,您的 SpawnEnemy() Coroutine 会运行并随后退出。 您必须将其锁定在某个循环中,如下所示:

    IEnumerator SpawnEnemy ()
    {
        while (true) // Keep checking
        {
            if(_uimanager.playerExists == true)
            {
                Vector3 position = new Vector3(Random.Range(-8.23f, 8.23f), 5.7f, 0.0f);
                Instantiate(_enemyShipPrefab, position, Quaternion.identity);            
                yield return new WaitForSeconds (5.0f);  // After spawning waits 5secs
            }
            yield return null; // Starts loop with next frame.
        }
    }
    

    【讨论】:

    • 谢谢 :) @Smartis @Programmer。但是,while (_uimanager.playerExists == true) 已经在检查并且 yeild 只是说每 5 秒检查一次条件的 while 条件不是吗?抱歉,我是 Unity 和 C# 的新手,发现协程有点难以掌握。
    • @ReshmaSuresh 在您的代码中,SpawnEnemyStart 函数中调用一次。在SpawnEnemy 内部,while (_uimanager.playerExists == true) 代码将永远运行,直到_uimanager.playerExists 不再是true。当_uimanager.playerExists 变为false 时,while 循环完成。完成后,在 while 循环之后,该函数中没有其他代码可以运行,因此函数退出。
    • Smartis 回答把你的代码放在while(true) 中,这样函数就永远不会退出yield return null; 用于使代码等待一帧,以便在每个循环结束时每个帧,以便 Unity 不会在 while(true) 循环中冻结。只有当if(_uimanager.playerExists == true) 为真并且在实例化之后,yield return new WaitForSeconds (5.0f); 才会用于等待 5 秒。只需阅读代码中的re cmets即可。
    猜你喜欢
    • 2015-08-05
    • 1970-01-01
    • 2011-02-13
    • 2014-08-21
    • 2019-11-16
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多