1
00:00:03,980 --> 00:00:08,109
In this lecture, we're going to get our enemies spawning over time in our waves.

2
00:00:08,119 --> 00:00:13,280
And because it's just a small step to get our waves working, we're also going to implement multiple

3
00:00:13,280 --> 00:00:13,940
waves.

4
00:00:14,330 --> 00:00:20,300
So let's start by heading over to our wave config script, because in here we're going to want to specify

5
00:00:20,300 --> 00:00:22,790
the spawn time for each enemy in the wave.

6
00:00:22,910 --> 00:00:29,600
So let's create a new serialized field of type float called Time Between Enemy Spawns.

7
00:00:30,710 --> 00:00:33,050
While we're here, we can give it a default value.

8
00:00:33,050 --> 00:00:36,120
So maybe around one per second for now.

9
00:00:36,140 --> 00:00:41,090
And rather than giving all of the enemies a fixed arrival time, let's add a little bit of variance

10
00:00:41,090 --> 00:00:41,590
in there.

11
00:00:41,600 --> 00:00:46,390
To do this, we're going to need two more variables to keep things working correctly.

12
00:00:46,400 --> 00:00:53,720
So we're going to have a float called spawn time variance, and we're going to add or subtract this

13
00:00:53,720 --> 00:00:58,070
value from our time between enemy spawns to add that element of randomness.

14
00:00:58,250 --> 00:01:03,410
But if you don't want any randomness, we can still use this approach and just set our spawn time variance

15
00:01:03,410 --> 00:01:04,319
to zero.

16
00:01:04,340 --> 00:01:10,250
And because this is going to be added or subtracted from our time between enemy spawns, if we happen

17
00:01:10,250 --> 00:01:16,190
to set a larger variance which is above the value for our time between spawns, we could end up in some

18
00:01:16,190 --> 00:01:17,210
negative numbers.

19
00:01:17,210 --> 00:01:22,850
So this is what the third variable is going to control and this is going to be a float called minimum

20
00:01:22,850 --> 00:01:23,720
spawn time.

21
00:01:25,260 --> 00:01:28,980
And we can set that to around 0.24 now.

22
00:01:29,370 --> 00:01:35,040
So with those set up, let's create the getter method that's going to return our random spawn time.

23
00:01:35,340 --> 00:01:39,600
We scroll all the way down to the bottom and create a public float.

24
00:01:40,380 --> 00:01:42,180
Get random spawn time.

25
00:01:45,200 --> 00:01:50,720
First of all, we're going to want to store a random range in a float so that we can return that after

26
00:01:50,720 --> 00:01:52,190
we've done some adjustments.

27
00:01:52,310 --> 00:01:58,820
So we'll create a temporary variable of type float called spawn time, and this is going to return a

28
00:01:58,820 --> 00:02:06,620
random range between our time, between enemy spawns minus our spawn time variance.

29
00:02:07,430 --> 00:02:12,920
And if we put the next part on a new line, the maximum value is going to be the time between enemy

30
00:02:12,920 --> 00:02:16,130
spawns plus the spawn time variance.

31
00:02:18,000 --> 00:02:24,360
Then to cap this lower bound just in case this goes below our minimum spawn time threshold.

32
00:02:25,310 --> 00:02:28,310
We're going to return math f dot clamp.

33
00:02:29,010 --> 00:02:32,370
The value we want to clamp is going to be our spawn time.

34
00:02:32,820 --> 00:02:36,420
Our minimum value is going to be the minimum spawn time.

35
00:02:36,960 --> 00:02:41,700
And for the maximum value we're going to hold the maximum number that a float can hold.

36
00:02:41,700 --> 00:02:45,630
And we can do that with float dot max value.

37
00:02:46,310 --> 00:02:51,800
So with that set up, let's head over to our enemy spawn and actually get our enemies arriving over

38
00:02:51,800 --> 00:02:52,490
time.

39
00:02:52,760 --> 00:02:58,340
If we head down into our spawn enemies method, we've already written the loop to create the enemies.

40
00:02:58,340 --> 00:03:01,670
So we just need a way of delaying this loop for every iteration.

41
00:03:01,760 --> 00:03:05,330
And we can do this using something called a CO routine.

42
00:03:05,370 --> 00:03:10,790
Now, routines are kind of like methods, but they're written and executed slightly differently.

43
00:03:11,030 --> 00:03:16,010
The first step to setting up a routine is to give our method a new return type.

44
00:03:16,010 --> 00:03:20,480
So we're going to change this from void to be an AI enumerator.

45
00:03:20,660 --> 00:03:24,050
Now, you don't have to worry too much about what an enumerator is.

46
00:03:24,050 --> 00:03:28,880
You can really just think of this as the method returning something countable that you can keep track

47
00:03:28,880 --> 00:03:29,300
of.

48
00:03:29,630 --> 00:03:34,700
This is giving us a red squiggly error message for our method name, and it's saying that not all code

49
00:03:34,700 --> 00:03:36,290
paths return a value.

50
00:03:36,320 --> 00:03:40,370
So like a method with a return type, we do need to return something.

51
00:03:40,370 --> 00:03:44,090
But unlike a method, we do this in a slightly different way.

52
00:03:44,270 --> 00:03:50,450
So inside of our for loop, once we've gone round once we're going to want to break out of this code

53
00:03:50,510 --> 00:03:53,210
routine and wait for a certain amount of time.

54
00:03:53,360 --> 00:03:58,600
And to do this, we're going to need to yield control from our code routine back to unity.

55
00:03:58,610 --> 00:04:05,730
So our return type for our code routine is going to be yield return, and then we need to return something.

56
00:04:05,750 --> 00:04:10,280
Now, if we wanted this to execute straight away, we could return null.

57
00:04:10,520 --> 00:04:14,030
But in our case, we want to wait for a set number of seconds.

58
00:04:14,030 --> 00:04:18,200
So we're going to return a new wait, 4 seconds.

59
00:04:18,260 --> 00:04:21,320
And we can see in this list here, we've got a few different options.

60
00:04:21,320 --> 00:04:23,210
We've got wait until the end of the frame.

61
00:04:23,210 --> 00:04:26,120
We've got wait until the end of the fixed update loop.

62
00:04:26,120 --> 00:04:28,640
But the one we want is wait 4 seconds.

63
00:04:29,030 --> 00:04:34,370
And the amount of time we want to wait is going to be coming from our wave config so we can say current

64
00:04:34,370 --> 00:04:37,520
wave dot get random spawn time.

65
00:04:38,030 --> 00:04:43,670
And this is essentially the routine saying that it's done what it needs to do for now and to come back

66
00:04:43,670 --> 00:04:46,480
and check on it in a number of seconds.

67
00:04:46,490 --> 00:04:52,310
Once that time has elapsed, unity will check back in on our routine and say that you asked me to come

68
00:04:52,310 --> 00:04:55,400
back in a number of seconds to see if you had anything else to do.

69
00:04:55,400 --> 00:05:00,770
And our code routine is going to enter the next loop of our for loop, at which point it's going to

70
00:05:00,770 --> 00:05:05,530
instantiate our second enemy and then yield control for another amount of seconds.

71
00:05:05,540 --> 00:05:11,090
This loop will continue until we've gone through all of the enemies in our list, at which point our

72
00:05:11,090 --> 00:05:14,840
code routine will break out of its for loop and come to a close.

73
00:05:14,930 --> 00:05:18,380
So hopefully that logic makes sense, but let's see it in action.

74
00:05:18,380 --> 00:05:23,930
And before we can do that, we do need to call a routine slightly differently to a method as well.

75
00:05:23,930 --> 00:05:29,390
So up in our start method where we're currently calling a method called spawn enemies, now we need

76
00:05:29,390 --> 00:05:35,900
to start a code routine and we can do that by writing start code routine and then placing the method

77
00:05:35,900 --> 00:05:38,600
that we want to start in parentheses.

78
00:05:38,780 --> 00:05:42,290
So let's save up our script and see this in action, in unity.

79
00:05:42,900 --> 00:05:47,310
Before we go ahead and play, though, let's check on our waves in our Waves and Paths folder.

80
00:05:47,400 --> 00:05:52,650
And if we click on Wave Zero, which is one we're currently playing within the scene, we can see that

81
00:05:52,650 --> 00:05:54,690
we've got these three new variables.

82
00:05:54,690 --> 00:06:00,240
So we've got our time between enemy spawns, which is around a second and a spawn time variance of zero.

83
00:06:00,270 --> 00:06:03,960
To add some randomness, I'm going to set this to around 0.5.

84
00:06:03,960 --> 00:06:09,390
So our enemies will now appear between half a second and one and one half seconds between each other.

85
00:06:09,720 --> 00:06:14,600
Now, if we go ahead and hit play, we'll find that our enemies are now nicely spaced out.

86
00:06:14,610 --> 00:06:20,370
So adding this time is allowing us to space out the execution of our for loop.

87
00:06:20,790 --> 00:06:24,440
The next step of our game is going to be to execute multiple waves.

88
00:06:24,450 --> 00:06:28,830
So let's head back over to our enemy spawn script and see how we're going to do this.

89
00:06:29,070 --> 00:06:34,200
Well, we're again going to need a couple of new variables and the first is going to be a list of wave

90
00:06:34,200 --> 00:06:34,950
configs.

91
00:06:34,950 --> 00:06:40,980
So let's create a serialized field and have a list of wave config essos.

92
00:06:42,010 --> 00:06:42,280
AMA.

93
00:06:42,280 --> 00:06:44,260
Call this the wave configs.

94
00:06:45,550 --> 00:06:51,610
And because we now have all of our WAV configs in this list, we don't need to have this current wave

95
00:06:51,610 --> 00:06:52,720
serialized anymore.

96
00:06:52,750 --> 00:06:57,880
What we're going to do is we're going to populate that based on the current wave from our list.

97
00:06:58,210 --> 00:07:03,790
Finally, just like how we have space between our enemies appearing, we may want to have space between

98
00:07:03,790 --> 00:07:05,050
our waves appearing.

99
00:07:05,140 --> 00:07:08,060
So let's add another serialized filled for that.

100
00:07:08,080 --> 00:07:12,430
It's going to be a float and it's going to be the time between waves.

101
00:07:13,240 --> 00:07:16,280
And by default, we're not going to have any space at all.

102
00:07:16,300 --> 00:07:22,000
So once one wave has generated all of its enemies, we're going to jump straight into the next one.

103
00:07:22,180 --> 00:07:25,450
But if you do want to slow that down, then you have some control.

104
00:07:25,450 --> 00:07:30,950
If you want even more control, then we can take a similar approach to our enemies from our wave config.

105
00:07:30,970 --> 00:07:32,820
But I'm not going to worry about that too much.

106
00:07:32,830 --> 00:07:37,900
I'm just going to have a fixed amount of time between each wave and to loop through all of the waves

107
00:07:37,900 --> 00:07:38,510
in our list.

108
00:07:38,530 --> 00:07:41,820
We're also going to do that in spawn enemies.

109
00:07:41,830 --> 00:07:46,240
But rather than walk you through it step by step, I think it's time for your challenge.

110
00:07:46,540 --> 00:07:50,640
I want you to loop through our new list of wave configs.

111
00:07:50,650 --> 00:07:55,360
And when you're looping through this list, have a think about whether you can use A for each loop for

112
00:07:55,360 --> 00:07:57,760
this or whether you need a for loop.

113
00:07:58,030 --> 00:08:03,880
And to clarify the logic for what we need to do in each loop, we need to set the value for our current

114
00:08:03,880 --> 00:08:07,540
wave because this is going to be very important for our path finder.

115
00:08:07,780 --> 00:08:10,840
We then want to loop through all of the enemies in that wave.

116
00:08:10,840 --> 00:08:13,320
So that's the code we've already got in place.

117
00:08:13,330 --> 00:08:18,520
And then after all of the enemies have been spawned for that wave, we want to wait for the time between

118
00:08:18,520 --> 00:08:20,690
waves before generating the next one.

119
00:08:20,710 --> 00:08:23,590
So pause the video now and give that a go.

120
00:08:28,710 --> 00:08:29,190
Okay.

121
00:08:29,190 --> 00:08:30,020
Welcome back.

122
00:08:30,030 --> 00:08:33,210
So let's get our waves working in our sworn enemies.

123
00:08:33,210 --> 00:08:37,860
We need a new loop to go through all of our wave config script through objects.

124
00:08:37,860 --> 00:08:43,440
And for this you could use a for loop, but I'm going to use a for each loop because we need to loop

125
00:08:43,440 --> 00:08:49,380
through all of them and we don't need to keep track of an iterator like we did for our enemies so we

126
00:08:49,380 --> 00:08:57,240
can say for each wave config S0 and we'll call this the wave in our wave configs list.

127
00:08:57,600 --> 00:09:02,430
Then we want to set our current wave equal to the wave that we're currently on.

128
00:09:02,430 --> 00:09:08,490
For this loop, we then want to take our existing for loop and place that inside of our for each loop.

129
00:09:08,490 --> 00:09:16,740
And then after that four loop has completed, we need to yield return new wait 4 seconds and this time

130
00:09:16,740 --> 00:09:20,010
we're going to wait for the time between our waves.

131
00:09:20,430 --> 00:09:26,340
Now, before we go ahead and test, rather than calling this spawn enemies, it's now spawning all of

132
00:09:26,340 --> 00:09:27,870
our waves and enemies.

133
00:09:28,020 --> 00:09:35,910
So to keep our method names descriptive, let's rename it to spawn enemy waves, save our script and

134
00:09:35,910 --> 00:09:37,890
jump back over into unity.

135
00:09:38,610 --> 00:09:42,990
And then on our enemy spawn, we now need to set up our wave configs again.

136
00:09:43,200 --> 00:09:48,840
So if we look the inspector, we can now select multiple things in our project window and drag them

137
00:09:48,840 --> 00:09:50,250
over into our list.

138
00:09:50,760 --> 00:09:53,640
Let's unlock the inspector so we don't run into problems.

139
00:09:53,850 --> 00:09:55,930
We select our enemy spanner.

140
00:09:56,370 --> 00:10:00,270
And I'm going to set the time between waves to 2 seconds.

141
00:10:00,570 --> 00:10:05,940
Now, before we hit play, we've set up our wave zero, but we haven't set up wave one yet.

142
00:10:06,360 --> 00:10:10,230
So let's go into wave one and add some enemies to our list.

143
00:10:11,050 --> 00:10:14,490
Strike over an enemy into our list and duplicate that a few times.

144
00:10:14,490 --> 00:10:17,430
So I'm going to again go with three for this wave.

145
00:10:17,640 --> 00:10:22,650
And for this one, I don't think I'm going to go with any variants for our spawn time, so let's test

146
00:10:22,650 --> 00:10:24,060
this out by hitting play.

147
00:10:25,440 --> 00:10:30,630
And we can say our first wave is being generated with some random variance in the enemy arrival.

148
00:10:30,810 --> 00:10:33,960
And then once that's finished, the second wave gets generated.

149
00:10:36,470 --> 00:10:43,370
If we set our time between waves to zero and play again, we'll see that the second wave arrives a lot

150
00:10:43,370 --> 00:10:44,060
sooner.

151
00:10:44,090 --> 00:10:48,140
So even before the first enemy wave has finished traversing the screen.

152
00:10:48,860 --> 00:10:54,320
And with that we have a nice functioning wave system and at this point we could go ahead and start creating

153
00:10:54,320 --> 00:10:56,590
more waves to add to our list.

154
00:10:56,600 --> 00:11:01,790
But regardless of how many we add, we are eventually going to get into a state where these waves come

155
00:11:01,790 --> 00:11:08,480
to an end, at which point we may want to transition to a game over or a wind screen, or in my case,

156
00:11:08,480 --> 00:11:10,400
I want these to infinitely loop.

157
00:11:10,400 --> 00:11:14,150
So once we get to the end of the list, we want to jump back up to the top.

158
00:11:14,150 --> 00:11:16,460
That's what we're going to be doing in the next lecture.

159
00:11:16,460 --> 00:11:17,540
So I'll see you there.

