为什么此敌人生成方法导致Unity崩溃?

我已经在Unity 2D项目的主要Gameplay.cs脚本中研究了这段代码很长时间了,无论我以哪种方式进行更改和移动,它要么导致Unity锁定Play,要么进行一些调整后,将立即从Wave 0转到Wave9.这是我最初的尝试,它导致Unity在Play时冻结.我不明白为什么会这样,并且想了解我的逻辑哪里出了问题.

我正在努力实现以下目标:

>在游戏中,游戏等待startWait秒.
> startWait之后,游戏进入SpawnWaves()方法并等待
等待每波之间的秒数,并将波数增加
每波一次.
>每波产生zombieCount个敌人并等待spawn生成每个僵尸之间的等待秒数.


private float startWait = 3f;   //Amount of time to wait before first wave
private float waveWait = 2f;    //Amount of time to wait between spawning each wave
private float spawnWait = 0.5f; //Amount of time to wait between spawning each enemy

private float startTimer = 0f; //Keep track of time that has elapsed since game launch
private float waveTimer = 0f;  //Keep track of time that has elapsed since last wave
private float spawnTimer = 0f; //Keep track of time that has elapsed since last spawn

private List<GameObject> zombies = new List<GameObject>();

[Serializefield]
private Transform spawnPoints; //The parent object containing all of the spawn point objects


void Start()
{
    deathUI.SetActive(false);

    //Set the default number of zombies to spawn per wave
    zombieCount = 5;

    PopulateZombies();
}

void Update()
{
    startTimer += Time.deltaTime;
    if (startTimer >= startWait)
    {
        waveTimer += Time.deltaTime;
        spawnTimer += Time.deltaTime;

        SpawnWaves();
    }


    //When the player dies "pause" the game and bring up the Death screen
    if (Player.isDead == true)
    {
        Time.timeScale = 0;
        deathUI.SetActive(true);
    }

}

void SpawnWaves()
{
    while (!Player.isDead && scoreCntl.wave < 9)
    {
        if (waveTimer >= waveWait)
        {
            IncrementWave();
            for (int i = 0; i < zombieCount; i++)
            {
                if (spawnTimer >= spawnWait)
                {
                    Vector3 spawnPosition = spawnPoints.GetChild(Random.Range(0, spawnPoints.childCount)).position;
                    Quaternion spawnRotation = Quaternion.identity;
                    GameObject created = Instantiate(zombies[0], spawnPosition, spawnRotation);
                    TransformCreated(created);

                    spawnTimer = 0f;
                }
            }

            waveTimer = 0f;
        }
    }
}

我是一个初学者,并且了解我的代码可能不遵循最佳实践.我也有一个使用协同程序并产生收益的有效敌方生成器,但我希望此版本的敌方生成器能够正常工作.

解决方法:

我对Unity没有任何经验,但对于XNA,我认为使用Update()和Draw()函数时,它们的主要游戏处理是相似的.

一个Update()函数通常每秒调用几次,在代码中,一旦startTimer> = startWait,则每次更新调用后都要执行SpawnWaves().

因此,让我们看一下SpawnWaves()

void SpawnWaves()
{
    while (!Player.isDead && scoreCntl.wave < 9)
    {
        if (waveTimer >= waveWait)
        {
            IncrementWave();
            for (int i = 0; i < zombieCount; i++)
            {
                if (spawnTimer >= spawnWait)
                {
                    [..]
                    spawnTimer = 0f;
                }
            }
            waveTimer = 0f;
        }
    }
}

while循环是一个问题,因为它是游戏循环中的一种游戏循环.只有在玩家死亡或您的挥杆计数超过9时,它才会退出.

调用SpawnWaves()之后,有两种可能性,这取决于Time.deltaTime(在程序启动后或多或少是随机的),waveTimer可以大于waveWait.

>案例:waveTimer> = waveWait

内部所有代码将立即执行.
因此,如果有可能使用IncrementWave(),它将在毫秒内完成9次.然后,虽然为false,并且内部代码不再执行.
>案例:waveTimer< WaveWait 在这种情况下,IncrementWave()将永远不会被调用,并且您的游戏可能会在while循环中不断旋转.
因此,您要做的基本上是用if语句替换while循环,以使程序继续运行.

If(!Player.isDead && scoreCntl.wave < 9)

从那时起,您的计数器增量将多次在Update()上被调用.

waveTimer += Time.deltaTime;
spawnTimer += Time.deltaTime;

随着时间的流逝,波变化和产卵的条件会变为现实.

if (waveTimer >= waveWait),
if (spawnTimer >= spawnWait)

我希望这可以指导您解决问题.

更新:

对于此行为,最好将IncrementWave和生成条件分开.为此,您需要一个额外的bool变量,在此示例中,该变量称为havetoSpawn.

    if (waveTimer >= waveWait)
    {
      IncrementWave();
      waveTimer = 0f;
      havetoSpawn = true; //new variable
    }

    if (havetoSpawn && spawnTimer >= spawnWait)
    {
        for (int i = 0; i < zombieCount; i++)
        {
            [..] //spawn each zonbie
        }
        spawnTimer = 0f; //reset spawn delay
        havetoSpawn = false; //disallow spawing
    }

相关文章

前言 本文记录unity3D开发环境的搭建 unity安装 unity有中文...
前言 有时候我们希望公告牌跟随镜头旋转永远平行面向屏幕,同...
前言 经过一段时间的学习与实际开发,unity3D也勉强算是强行...
前言 在unity中我们常用的获取鼠标点击的方法有: 1、在3D场...
前言 在之前的例子中,我们都没有用到unity的精髓,例如地形...
这篇文章将为大家详细讲解有关Unity3D中如何通过Animator动画...