我已经在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
}