首页 > 解决方案 > 使用 Yield 使函数等到某事为真 Unity C#

问题描述

我正在尝试使用 Yield,因此如果已达到最大数量,我的功能会等待在场景中生成更多敌人。但是现在函数在整个循环中跳过了所有这些。我从来没有使用过产量,所以也许我在阅读文档时理解错了它的作用。也可能有更好的方法来做到这一点。

while ( i < clonesASpawnear.Length)
    {          

        if (j <= endList)
        {      
                if (clonesASpawnear[i] == null)
                {

                    if (sPCurrent == sPMax)
                    {
                        sPCurrent = 0;
                    }                   

                yield return new WaitUntil(() => aliveEnemies < maxAmmoutOfEnemiesOnStage);

                clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
                    clonesASpawnear[i].SetActive(true);
                    clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
                    aliveEnemies += 1;

                    clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
                    j++;
                    i++;
                    sPCurrent++;


                }
            }               

        else
        {
            j = startList;
        }            



    }
}

按要求编辑:这是调用函数的更新

 void Update()
{
    if (pdh.playerIsDead == false && roundOver==false)
    {

        playerAliveTime += Time.deltaTime;
    }



    if (waveNumer <= 3 )
    {



        timeForNextSpawn -= Time.deltaTime;
        if (timeForNextSpawn <= 0 && aliveEnemies == 0)
        {


            nextWaveTextUI.text = nextWaveText;

            int waitT = (int)waitTimeForNewWave;
            StartCoroutine(delayXSeconds(waitT));


            timeForNextSpawn = waitTimeForNewWave;
            auxWaveThisRound--;

            waveNumer++;

            spawnEnemies();

        }
    }
    else
    {

        if(aliveEnemies == 0 && auxWaveThisRound <= 0)
        {
            clearedRoundTextUI.text = clearedRoundText;
            roundOver = true;



            StartCoroutine(waiterReset());


        }


    }

    accuracy = successfulProjectiles / projectileFired;


}

以及上面代码所在的完整函数

IEnumerator spawnEnemies()
{

    int percentForWave=0;
    int percentForType=0;

    int TotalEnemies = (int)enemySpawnsThisRound;
    if (waveNumer == 1)
    {
        Debug.Log("Entro al wave 1");
        percentForWave = 20;
        percentForType = 20;
        startList = 0;

    }
    if (waveNumer == 2)
    {
        Debug.Log("Entro al wave 2");
        percentForWave = 70;
        percentForType = 70;
        startList = endList;

    }
    if (waveNumer == 3)
    {
        Debug.Log("Entro al wave 3");
        percentForWave = 10;
        percentForType = 10;
        startList = endList;
    }


    int enemiesThisWave = Decimal.ToInt32(Math.Round(TotalEnemies * ((decimal)percentForWave / 100), 1));
    int enemiesForType = Decimal.ToInt32(Math.Round(lenghtList * ((decimal)percentForType / 100), 1));

    endList = enemiesForType + startList;

    clonesASpawnear = new GameObject[enemiesThisWave];
    int i = 0;
    int j = startList;



    while ( i < clonesASpawnear.Length)
    {



        if (j <= endList)
        {
                if (clonesASpawnear[i] == null)
                {

                    if (sPCurrent == sPMax)
                    {
                        sPCurrent = 0;
                    }
                yield return new WaitUntil(() => aliveEnemies < maxAmmoutOfEnemiesOnStage);

                clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
                    clonesASpawnear[i].SetActive(true);//lo activo
                    clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
                    aliveEnemies += 1;

                    clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
                    j++;
                    i++;
                    sPCurrent++;


                }
            }

        else
        {
            j = startList;
        }


    }

}

标签: c#unity3dyield

解决方案


不要使用 while 循环。相反,使用“更新()”。

void Update() {

    if (aliveEnemies < maxAmmoutOfEnemiesOnStage && j <= endList)
    {      
            if (clonesASpawnear[i] == null)
            {

                if (sPCurrent == sPMax)
                {
                    sPCurrent = 0;
                }                   

            clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
                clonesASpawnear[i].SetActive(true);
                clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
                aliveEnemies += 1;

                clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
                j++;
                i++;
                sPCurrent++;


            }
        }               

    else
    {
        j = startList;
    }   

}

这就是更新框架的想法。每一帧都会触发这里的逻辑。只有当敌人数量低于最大值时才会继续。这个方法必须进入一个扩展 MonoBehaviour 的类,否则它不会被调用。鉴于预期的逻辑,将其附加到一些主“游戏监控”游戏对象是有道理的,该游戏对象管理游戏的元数据以及胜利状态等。

编辑(更多内容后):这是一个问题“spawnEnemies();”。那是一个 IEnumerator,但你不使用“StartCoroutine(spawnEnemies())”。所以该方法实际上不会执行。不会有错误,但方法中不会发生任何事情。


推荐阅读