Contents:
For testing the base zombie, we shall be making a super basic zombie spawner. It will just take the amount of rows on the base Grid
, and spawn a zombie randomly between a set amount of seconds.
IEnumerator spawnZombo()
{
while (zombieCounter < maxZombieCount)
{
yield return new WaitForSeconds(delayBetweenSpawns);
Zombie newZombie = Instantiate(zombiePrefab, transform, false);
newZombie.transform.position = new Vector3(gridGenerator.gridWidth + 5, 0.5f, Random.Range(0, gridGenerator.gridHeight));
zombieCounter++;
}
}
Now we can test the system!
The test works but the colliders suck!
Much better collisions and a great demo test.
Now we are onto the big guns. Looking at the logic from the original game we can see that the Zombies spawned each Wave
are always the same, but the locations can be random. Therefore, the Wave System
we create must incorporate this into its logic.
Using Scriptable Objects
again, we can create Waves
that have the data of the Zombies stored as Segments
.
[Serializable]
[CreateAssetMenu(fileName = "Wave", menuName = "PvZRemake/Wave/New Wave", order = 1)]
public class Wave : ScriptableObject
{
public string waveNumber;
public float delayBetweenSegments; //Uses this OR if the wave is defeated to trigger the next.
[Header("Wave Data")]
public WaveSegment[] waveSegments;
}
[Serializable]
public class WaveSegment
{
public Zombie[] zombiesInSegment;
}
Now we have a Wave
Scriptable Object we can populate to create waves and Segments
of these waves, and place this into a future WaveController
. Each Segment
represents the Zombies that will spawn in that segment and are separated by the delayBetweenSegments
variable. Now, we need to use this to make the logic for the actual spawning system.
We will again be using Coroutines to control the spawning, and separate the elements utilising the time delay.
'While the Wave
is active, we must iterate through each Segment
and spawn the Zombies which have been designated within this. We can do this using a ‘foreach’ statement for the zombies inside of a ‘forloop’ for the Segments
.
IEnumerator GenerateWaves(WaveSegment[] segments)
{
while (waveIsActive)
{
for (int i = 0; i < segments.Length; ++i)
{
Zombie[] segmentZombies = segments[i].zombiesInSegment;
foreach (Zombie zombie in segmentZombies)
{
Zombie zombieSpawned = Instantiate(zombie, transform, true);
zombieSpawned.transform.parent = transform;
zombieSpawned.transform.position = new Vector3(gridGenerator.gridWidth + 3, 0.5f, Random.Range(0, gridGenerator.gridHeight));
}
if (i >= segments.Length - 1)
{
waveIsActive = false;
break;
}
yield return new WaitForSeconds(currentWave.delayBetweenSegments);
}
}
while (!waveIsActive)
{
yield return null;
}
}
Now let’s test, we should expect the following for Wave
1-1: