1
00:00:04,059 --> 00:00:08,410
In this lecture, we're going to get our enemies shooting back at our player, and we're going to do

2
00:00:08,410 --> 00:00:11,980
this using the exact same shooter script that we used for our player.

3
00:00:12,670 --> 00:00:17,950
Before we go ahead and edit our script though, let's clean up our assets folder by dragging our shooter

4
00:00:17,950 --> 00:00:25,330
script into our scripts folder and then let's head into our prefabs, go into our enemy, and then add

5
00:00:25,330 --> 00:00:26,650
our Shooter component.

6
00:00:28,550 --> 00:00:29,090
In here.

7
00:00:29,090 --> 00:00:31,390
We want to give it the projectile prefab.

8
00:00:31,400 --> 00:00:34,130
So this time we're going to use our enemy projectile.

9
00:00:34,160 --> 00:00:36,920
And for now, we'll just leave all of the other things as default.

10
00:00:36,950 --> 00:00:39,050
We can edit those when we start testing.

11
00:00:39,440 --> 00:00:44,300
With that set, let's open up our shooter script and see what we need to change to get it to work for

12
00:00:44,300 --> 00:00:45,170
our enemies.

13
00:00:45,500 --> 00:00:48,620
Well, we want our enemies to fire automatically.

14
00:00:48,620 --> 00:00:53,150
So it's really just a case of overriding our is firing boolean.

15
00:00:53,150 --> 00:00:56,710
So this is no longer going to be getting set from a different script.

16
00:00:56,720 --> 00:01:02,030
Instead, what we're going to do is we're going to set this to true in our start method, but so this

17
00:01:02,030 --> 00:01:03,880
doesn't affect our player as well.

18
00:01:03,890 --> 00:01:09,230
Let's create a new variable so we can tell the system whether we're using the A control or the player

19
00:01:09,230 --> 00:01:09,830
control.

20
00:01:10,160 --> 00:01:16,820
This is as simple as creating a serialized field of type ball that we're going to call use a I.

21
00:01:16,850 --> 00:01:22,940
So if use IE is true, we're going to automatically set up our is firing ball and if it's false, we're

22
00:01:22,940 --> 00:01:24,950
going to accept input from the player.

23
00:01:24,980 --> 00:01:32,870
So in start, let's say that if we are using the AI then is firing is always going to be true.

24
00:01:33,410 --> 00:01:40,880
So let's save up our script as it is and jump into unity to test this inside of our enemy prefab, let's

25
00:01:40,880 --> 00:01:45,020
go down to our shooter script and check the use option.

26
00:01:45,200 --> 00:01:50,120
Now if we go ahead and hit play, we can now see that our enemies are shooting.

27
00:01:50,210 --> 00:01:52,350
But we've got some very weird behavior here.

28
00:01:52,370 --> 00:01:54,920
First of all, the shooting is very fast.

29
00:01:54,920 --> 00:01:58,220
And secondly, they're shooting in the wrong direction.

30
00:01:58,220 --> 00:02:01,730
So let's come out of play mode and fix both these problems.

31
00:02:02,480 --> 00:02:09,110
So over on our enemy prefab, let's first of all change our firing rate from 0.2 and make that a bit

32
00:02:09,110 --> 00:02:12,110
larger so maybe around one and see how that feels.

33
00:02:12,320 --> 00:02:15,260
And together, projectiles moving in the correct direction.

34
00:02:15,260 --> 00:02:21,200
Remember that in our shooter script we were telling it to use the op vector multiplied by the projectile

35
00:02:21,200 --> 00:02:21,980
speed.

36
00:02:22,010 --> 00:02:27,470
So our enemy is going to be following our up vector, which is still up the screen, even though our

37
00:02:27,470 --> 00:02:29,990
sprite makes it look like we're facing down.

38
00:02:30,020 --> 00:02:32,390
So first of all, let's rotate our sprite.

39
00:02:32,390 --> 00:02:36,140
So it follows more closely what the up direction should be.

40
00:02:36,680 --> 00:02:42,410
So we'll just jump into our enemy Sprite and on the Z component of our rotation, we'll just change

41
00:02:42,410 --> 00:02:44,420
that to 180 degrees.

42
00:02:44,540 --> 00:02:47,180
We'll see that the Green Arrow now points down.

43
00:02:47,180 --> 00:02:49,580
But remember, this is only for our sprite.

44
00:02:49,580 --> 00:02:56,420
So if we click on our enemy, we can see that the up arrow for this is still facing up with that set.

45
00:02:56,420 --> 00:03:02,420
The projectiles will now come out of the front of the ship, but we now need a way of rotating the entire

46
00:03:02,420 --> 00:03:04,670
ship so it faces down the screen.

47
00:03:04,910 --> 00:03:09,470
So to do this, we're going to have to rotate our objects when we instantiate them.

48
00:03:09,770 --> 00:03:14,120
And if we head over to our script folder, this was the job of the enemy spawn.

49
00:03:14,450 --> 00:03:15,890
So let's open up our enemy.

50
00:03:15,890 --> 00:03:20,840
Spawn a script, head down to where we're instantiating our enemies.

51
00:03:20,840 --> 00:03:24,710
And in here we're setting the rotation to cotangent identity.

52
00:03:24,710 --> 00:03:28,880
So no rotation, but we can very easily change this condition.

53
00:03:28,880 --> 00:03:35,810
So instead of using cotangent identity, we want to rotate our enemy 180 degrees when it's created.

54
00:03:35,990 --> 00:03:40,790
There are a few ways to do this, but the easiest way of doing this is to say Quaternions.

55
00:03:41,240 --> 00:03:44,210
Euler So you are.

56
00:03:44,210 --> 00:03:48,560
And if you're wondering about the weird spelling versus the pronunciation, it's because it's named

57
00:03:48,560 --> 00:03:50,810
after the mathematician Leonard Euler.

58
00:03:51,200 --> 00:03:57,620
Then inside the parentheses we need to specify the X, Y and Z rotation and we don't want to rotate

59
00:03:57,620 --> 00:04:03,020
on the X or Y, but we do want to rotate 180 degrees on the Z component.

60
00:04:03,320 --> 00:04:10,490
So if we save this and jump back into unity and then we can go ahead and hit play, we should now find

61
00:04:10,490 --> 00:04:15,050
that our enemies are the right way round and are shooting in the correct direction.

62
00:04:15,050 --> 00:04:18,829
So we now have a way of the enemies shooting back at the player.

63
00:04:18,829 --> 00:04:24,170
But the projectiles are all on a fixed firing schedule, so it's very predictable gameplay and this

64
00:04:24,170 --> 00:04:26,900
is the next thing that I'm going to want to change.

65
00:04:26,900 --> 00:04:31,460
So let's come out of play and head back over into our shooter script one more time.

66
00:04:32,210 --> 00:04:35,440
And then let's just recap on our firing CO routine.

67
00:04:35,450 --> 00:04:41,570
So while true, we're instantiating our object, giving it some velocity, destroying it after a set

68
00:04:41,580 --> 00:04:42,440
amount of time.

69
00:04:42,440 --> 00:04:45,440
And then the piece we're interested in is the weighting.

70
00:04:45,440 --> 00:04:50,860
So to make this more random, we're going to want to pass a random value into this wait 4 seconds.

71
00:04:50,870 --> 00:04:54,950
And because I think you're up to the task, this is going to be your challenge.

72
00:04:55,190 --> 00:05:02,060
I want you to go ahead and modify our routine to wait for a random amount of time between our projectiles.

73
00:05:02,090 --> 00:05:08,390
And as a hint, why not have a look at I'll get random spawn time method from our wave config.

74
00:05:08,390 --> 00:05:11,870
So because the logic here is going to be very, very similar.

75
00:05:11,870 --> 00:05:16,520
So once you've had a look at that method that we've written previously, think about what new variables

76
00:05:16,520 --> 00:05:21,200
we're going to need to add to our shoot script to make this work and potentially what we're going to

77
00:05:21,200 --> 00:05:22,340
need to change.

78
00:05:22,340 --> 00:05:25,280
So pause the video now and give that one a go.

79
00:05:30,970 --> 00:05:31,480
Okay.

80
00:05:31,480 --> 00:05:32,390
Welcome back.

81
00:05:32,410 --> 00:05:34,590
So hopefully you got on well with that challenge.

82
00:05:34,600 --> 00:05:39,640
And here we are in our wave config so we can see how we did it last time.

83
00:05:39,760 --> 00:05:45,880
Well, for our variables, we had a time between enemy spawns, a spawn time variance and a minimum

84
00:05:45,880 --> 00:05:46,720
spawn time.

85
00:05:46,720 --> 00:05:52,780
And if we head down to our get random spawn time method in here, we were getting a random spawn time

86
00:05:52,780 --> 00:05:54,250
between two values.

87
00:05:54,250 --> 00:05:59,380
And then to make sure that we weren't going into negative numbers, we were clamping our result.

88
00:05:59,380 --> 00:06:03,850
So let's essentially replicate this same sort of thing in our shooter script.

89
00:06:04,030 --> 00:06:09,550
We're currently waiting for our fire rate in our routine, but I think this should probably be renamed

90
00:06:09,550 --> 00:06:11,590
and used in a slightly different way.

91
00:06:11,590 --> 00:06:18,130
So I'm going to rename my firing rate to the base firing rate and then I'm going to create two more

92
00:06:18,130 --> 00:06:19,420
serialized fields.

93
00:06:19,510 --> 00:06:25,750
These are both going to be Float, and the first one is going to be called the firing rate variance.

94
00:06:26,350 --> 00:06:29,650
And by default, we're going to set this to zero.

95
00:06:29,650 --> 00:06:35,080
And then for our second variable, we're going to call this one the minimum firing rate.

96
00:06:36,340 --> 00:06:39,190
And we can maybe set that to around point one.

97
00:06:39,700 --> 00:06:44,140
With those set, let's head down to our routine and implement our logic.

98
00:06:44,650 --> 00:06:50,800
So in here we want a temporary variable of type float, which I'm going to call Time to next projectile.

99
00:06:52,640 --> 00:07:01,850
And this is going to be equal to a random range between our base firing rate minus our firing rate variance

100
00:07:01,850 --> 00:07:06,200
and our base firing rate plus our firing rate variance.

101
00:07:06,320 --> 00:07:12,080
Then to make sure that this value doesn't go below zero, because if it does, we're going to be waiting

102
00:07:12,080 --> 00:07:15,530
for negative seconds, which is going to cause us a lot of problems.

103
00:07:15,530 --> 00:07:21,440
So we're going to clamp this value by saying time to next projectile is equal to math.

104
00:07:21,440 --> 00:07:26,330
F Clamp the value we want to clamp is our time to next projectile.

105
00:07:26,480 --> 00:07:33,320
We want our minimum value to be the minimum firing rate and our maximum value is going to be our float

106
00:07:33,650 --> 00:07:34,550
max value.

107
00:07:36,400 --> 00:07:42,220
And then, rather than yielding for the amount of our base firing rate, we want to wait for the time

108
00:07:42,220 --> 00:07:43,660
to next projectile.

109
00:07:43,960 --> 00:07:46,120
So let's save this up and test out.

110
00:07:46,630 --> 00:07:49,750
Let's head into our prefabs and look at our enemy.

111
00:07:49,870 --> 00:07:52,510
We've already set our use AI to be true.

112
00:07:52,540 --> 00:07:58,930
We want our base firing rate to be around one, and we're going to add a variance of maybe around 0.5.

113
00:07:58,930 --> 00:08:04,060
So our projectiles will spawn anywhere between half a second and one half seconds between each other.

114
00:08:04,360 --> 00:08:09,310
Now, before we actually test, there's one more thing I do want to do in my shooting script, because

115
00:08:09,310 --> 00:08:13,180
we're getting a lot of variables in here and it's starting to get very cluttered.

116
00:08:13,210 --> 00:08:19,060
We've got this is firing flag that's public, but we don't ever really need to set it in the inspector.

117
00:08:19,060 --> 00:08:21,120
So it would make sense to hide that away.

118
00:08:21,130 --> 00:08:26,950
And we've also got a bit of a split between generic shooter functionality and other things specifically

119
00:08:26,950 --> 00:08:28,860
related to our air shooting.

120
00:08:28,870 --> 00:08:32,740
So let's jump back into our shooter script for one final time.

121
00:08:32,740 --> 00:08:38,740
And if we head up to our variables at the top, we're going to separate this up with some headers so

122
00:08:38,740 --> 00:08:40,659
we can use the header attribute.

123
00:08:40,809 --> 00:08:47,050
And I'm going to call the first one general and this will include our projectile prefab, its speed

124
00:08:47,050 --> 00:08:50,470
lifetime and maybe our base firing rate as well.

125
00:08:50,710 --> 00:08:57,310
And then we're going to have a second header attribute called I and this will have our use I flag and

126
00:08:57,310 --> 00:09:00,430
the variables that we're using to modify our firing rate.

127
00:09:00,580 --> 00:09:06,970
Finally, we're going to hide away this public variable, and we can do that with another new attribute.

128
00:09:06,970 --> 00:09:09,580
And this is called Hide in Inspector.

129
00:09:09,850 --> 00:09:15,130
And just like a serialized filled, this doesn't really affect the access level of our variable encode.

130
00:09:15,130 --> 00:09:18,130
It only affects the access in the inspector.

131
00:09:18,400 --> 00:09:21,400
So let's save this up and jump back into unity.

132
00:09:21,940 --> 00:09:26,590
And now we can see our shooter component is a lot more manageable if we're just dealing with general

133
00:09:26,590 --> 00:09:31,360
stuff, we can set up our first four variables and if we're interested in AI, then we can set these

134
00:09:31,360 --> 00:09:37,270
up and finally notice that our IS shooting variable is no longer present because we've hidden it in

135
00:09:37,270 --> 00:09:38,170
the inspector.

136
00:09:38,200 --> 00:09:42,520
So with that little bit of clean up a side, let's finally go and test our gain.

137
00:09:43,210 --> 00:09:48,370
We now have our enemies shooting at random intervals, which is a lot nicer and they're shooting a little

138
00:09:48,370 --> 00:09:51,700
bit slower and we can shoot back at them and destroy them.

139
00:09:52,030 --> 00:09:55,180
And with that, our core gameplay is pretty much finished.

140
00:09:55,180 --> 00:10:00,460
It still requires a little bit of tuning and we can add some more enemy waves and enemy types, but

141
00:10:00,460 --> 00:10:02,470
the fundamentals are all there.

142
00:10:02,740 --> 00:10:07,510
However, it is still a little bit boring, so over the next few lectures we're going to start adding

143
00:10:07,510 --> 00:10:08,980
some juice to our game.

144
00:10:08,980 --> 00:10:13,780
And the first piece of juice that I want to add is some particle effects to start selling the impact

145
00:10:13,780 --> 00:10:15,910
of the projectiles on the enemies.

146
00:10:15,910 --> 00:10:19,000
Well, we're starting that in the next lecture, so I'll see you there.

