首页 > 解决方案 > I want to make it so that the next scene loads after the waves are done but for some reason I can't figure out how to prevent it from happening early

问题描述

In the second level of my game I made a wave system with 3 different types of zombies. This wave system spawns in three different waves. My problem is that I cannot think of a way to start the next scene because whatever I try makes it start the next scene within 1 wave. I have tried using the bools that check if the waves have ran but the problem is that I have to have one of the true or else the second and third wave spawns together. I tried putting it in the spawner for the third wave but that didn't work. I tried adding ZKLeft.Length == 0 but that didn't work. Do you know any possible ways to prevent the next scene starting early without starting a wave early? Thanks!

Sorry if the code is bad I am a student

using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;


public class Waves : Zombie
{    
    public GameObject behemoth;    
    public GameObject runner;    
    public GameObject zombie;    

    private bool HasSecondWaveRan = false;
    private bool HasThirdWaveRan = true;

    private int xPos;

    public GameObject[] ZKleft;

    // Start is called before the first frame update
    private void Start()
    {
        ZKleft = GameObject.FindGameObjectsWithTag("Zombie");

        for (int i = 0; i < 10; i++)
        {
            xPos = Random.Range(31, -14);            
            Instantiate(zombie, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            
        }

        for (int i = 0; i < 3; i++)
        {
            xPos = Random.Range(31, -14);            
            Instantiate(runner, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            
        }
        
    }

    // Update is called once per frame
    private void Update()
    {
        ZKleft = GameObject.FindGameObjectsWithTag("Zombie");        

        if (ZKleft.Length == 0)
        {
            StartCoroutine(SecondWave());
            HasSecondWaveRan = true;
        }

        if (ZKleft.Length == 0)
        {
            StartCoroutine(ThirdWave());
            HasThirdWaveRan = true;
        }

        if (HasThirdWaveRan == true && HasSecondWaveRan == true)
        {
            SceneManager.LoadScene("Level_2_Completed"); 
        }
    }

    IEnumerator SecondWave()
    {
        if (HasSecondWaveRan == false)
        {
            
            yield return new WaitForSeconds(5.0f);

            for (int i = 0; i < 5; i++)
            {
                xPos = Random.Range(31, -14);
                Instantiate(runner, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            }

            for (int i = 0; i < 20; i++)
            {
                xPos = Random.Range(31, -14);
                Instantiate(zombie, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            }

            HasThirdWaveRan = false;
            HasSecondWaveRan = true;            
        }
    }

    IEnumerator ThirdWave()
    {
        if (HasThirdWaveRan == false)
        {
            yield return new WaitForSeconds(5.0f);

            for (int i = 0; i < 5; i++)
            {
                xPos = Random.Range(31, -14);
                Instantiate(runner, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            }

            for (int i = 0; i < 20; i++)
            {
                xPos = Random.Range(31, -14);
                Instantiate(zombie, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            }

            for (int i = 0; i < 3; i++)
            {
                xPos = Random.Range(31, -14);
                Instantiate(behemoth, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
            }

            HasThirdWaveRan = true;
            
        }
    }
    
}

标签: c#unity3d

解决方案


Update goes through all your if statements in just one frame. So when you set a Boolean to true, then executes the next if statement, thus changing all of them to true. You could try something like this:

   private bool HasSecondWaveRan = false;
   private bool HasThirdWaveRan = false;

   ...

   private void Update()
   {
       ZKleft = GameObject.FindGameObjectsWithTag("Zombie");

       if (ZKleft.Length == 0)
       {
           if (!HasSecondWaveRan && !HasSecondWaveRan)
           {
               StopCoroutine(FirstWave());
    //you don’t have a ‘FirstWave’, but I thought I
    //might include it. Remove it if you don’t want
    //a first wave.
               StartCoroutine(SecondWave());
               HasSecondWaveRan = true;
               return;
           }
           else if (HasSecondWaveRan && !HasThirdWaveRan)
           {
               StopCoroutine(SecondWave());
               StartCoroutine(ThirdWave());
               HasThirdWaveRan = true;
               return;
           }
           else if (HasSecondWaveRan && HasThirdWaveRan)
           {
               StopCoroutine(ThirdWave());
               SceneManager.LoadScene("Level_2_Completed"); 
           }
       }
   }

You can remove the if statements from the coroutine s that compare Has_WaveRan and false. I use ‘return’ to cancel the update function if the if statement ran. It should work if you just replace this code with your update function. If it doesn’t and/or you get errors, comment and describe the line the error it occurs and the error code. Change the coroutines to this:


    IEnumerator SecondWave()
    {
        for (int i = 0; i < 5; i++)
        {
            xPos = Random.Range(31, -14);
            Instantiate(runner, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
        }

        for (int i = 0; i < 20; i++)
        {
            xPos = Random.Range(31, -14);
            Instantiate(zombie, new Vector3(xPos, 0.4f, 6), Quaternion.identity);       
        }
        yield return new WaitForSeconds(5.0f);
    }

    IEnumerator ThirdWave()
    {
        for (int i = 0; i < 5; i++)
        {
            xPos = Random.Range(31, -14);
            Instantiate(runner, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
        }

        for (int i = 0; i < 20; i++)
        {
            xPos = Random.Range(31, -14);
            Instantiate(zombie, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
        }

        for (int i = 0; i < 3; i++)
        {
            xPos = Random.Range(31, -14);
            Instantiate(behemoth, new Vector3(xPos, 0.4f, 6), Quaternion.identity);
        }
        yield return new WaitForSeconds(5.0f);
    }


推荐阅读