WokerHead
WokerHead

Reputation: 967

Unity3D: How to control spawner, doesn't stop instantiating when waiting for wave to finish

Unity3D 2018.2.4 C#

In this spawner code, it keeps instantiating. How do I stop the spawning from instantiating until all enemies are destroyed that were spawned.

I'm checking

if (destroyedEnemyCounter == enemyStartAmount)

because I'm counting all destroyed enemies and how much the wave spawner is multiplying the enemyStartAmount BUT the code keeps instantiating even when I placed the wave forwarding inside the if statement.

How would I add a limit on stopping the spawner from instantiating until the count for that wave/round are destroyed and able to move to the next wave/round?

Here is the code I have so far

private int enemyStartAmount = 2;
private int multiply = 2;
private float startWait = 30.0f;
private float spawnWait = 2.0f;
private float waveWait = 28.0f;

//  Start
private void OnEnable()
{
    startCountDownTimer = startWait;
    waveCurrentCount = 1;

    StartCoroutine(SpawnWaves());
}

//  Update
private void FixedUpdate()
{
    //  For Text: StartTimer
    if (isStartTimerFinished == false)
    {
        startCountDownTimer -= Time.deltaTime;
    }

    //  For Text: When StartTimer isFinished
    if (isStartTimerFinished == false && startCountDownTimer <= 0f)
    {
        isStartTimerFinished = true;
    }

    //  For Text: When startTimer ends and Spawner Starts
    if (isStartTimerFinished == true)
    {
        //  Game Timer
        stopWatchTimer += Time.deltaTime;

    }
}

//  Main: Spawn Waves
IEnumerator SpawnWaves()
{
    //  Start when First Countdown isFinished
    yield return new WaitForSeconds(startWait);
    while (true)
    {
        for (int i = 0; i < enemyStartAmount; i++)
        {
            //  Each Wave is a different way
            switch (waveCurrentCount)
            {
                case 1:
                    Transform spawnPoint = innerLevelSpawns[(int)Random.Range(0, innerLevelSpawns.Length)].transform;
                    Quaternion spawnRotation = Quaternion.identity;
                    Instantiate(enemyTypes[(int)Random.Range(0, 0)], spawnPoint.position, spawnRotation);
                    break;

                 ...

                case 8:
                    Transform spawnPoint8 = outerLevelSpawns[(int)Random.Range(0, outerLevelSpawns.Length)].transform;
                    Quaternion spawnRotation8 = Quaternion.identity;
                    Instantiate(enemyTypes[(int)Random.Range(0, 0)], spawnPoint8.position, spawnRotation8);
                    break;
                default:
                    Transform spawnPoint9 = outerLevelSpawns[(int)Random.Range(0, outerLevelSpawns.Length)].transform;
                    Quaternion spawnRotation9 = Quaternion.identity;
                    Instantiate(enemyTypes[(int)Random.Range(0, enemyTypes.Length)], spawnPoint9.position, spawnRotation9);
                    break;
            }
            yield return new WaitForSeconds(spawnWait);
        }

        //  Check if enemyCount has been destroyed -> then send next wave
        enemiesInScene = GameObject.FindGameObjectsWithTag("Enemy");
        enemiesInSceneText.text = "Total Spawned: " + enemiesInScene.Length.ToString();

        //  Next Wave -----------Hold Spawn when Wave Amount Destroyed--------------------------

        if (destroyedEnemyCounter == enemyStartAmount)
        {
            Debug.Log("Next Wave Incoming");

            //  Multiply Enemy Count
            enemyStartAmount = enemyStartAmount * multiply;

            //  Count Waves
            waveCurrentCount = ++waveCurrentCount;

            yield return new WaitForSeconds(waveWait);
        }
    }
}

Upvotes: 1

Views: 101

Answers (2)

Replace

if (destroyedEnemyCounter == enemyStartAmount)

With

yield return new WaitUntil(() => destroyedEnemyCounter == enemyStartAmount);

Upvotes: 2

Fredrik Widerberg
Fredrik Widerberg

Reputation: 3108

After you check

if (destroyedEnemyCounter == enemyStartAmount)

the loop will start again, spawning enemyStartAmount once more.

What you could do is add a condition around the spawning-logic, for example have a bool readyForNextWave that you set to true inside if (destroyedEnemyCounter == enemyStartAmount)

if(readyForNextWave)
{
    readyForNextWave = false;
    for (int i = 0; i < enemyStartAmount; i++)
    {
        //  Each Wave is a different way
        // ...
        yield return new WaitForSeconds(spawnWait);
    }
}

// ...

if (destroyedEnemyCounter == enemyStartAmount)
{
    readyForNextWave = true;
    Debug.Log("Next Wave Incoming");
    // ...
}

Upvotes: 2

Related Questions