﻿1
00:00:04,380 --> 00:00:04,920
‫Hey.

2
00:00:04,920 --> 00:00:05,810
‫Welcome back.

3
00:00:05,820 --> 00:00:11,610
‫We're ready to finish our game, which means there are just a few things left to do to polish up our

4
00:00:11,610 --> 00:00:15,150
‫game and get it in a state that we are happy with.

5
00:00:15,150 --> 00:00:17,730
‫So get ready to finish this game up.

6
00:00:17,730 --> 00:00:19,170
‫We're almost done.

7
00:00:19,170 --> 00:00:21,450
‫We're just going to add a couple of features.

8
00:00:21,450 --> 00:00:25,980
‫I'd like to make the camera movement a little smoother, so we're going to start with that.

9
00:00:26,010 --> 00:00:32,130
‫I've also noticed that the towers still fire projectiles after the tank has died, so we can make an

10
00:00:32,130 --> 00:00:35,250
‫easy fix to the code to prevent that from happening.

11
00:00:35,250 --> 00:00:40,410
‫And also, I'm going to visit a potential issue with the projectile spawn point.

12
00:00:40,410 --> 00:00:43,380
‫So let's jump in and polish up this game.

13
00:00:43,740 --> 00:00:46,920
‫Now, the first thing I'd like to look at is the camera movement.

14
00:00:46,920 --> 00:00:50,670
‫So if I go ahead and hit play, I'll just show you what I mean.

15
00:00:50,820 --> 00:00:58,380
‫As I move around, you'll see that the camera follows exactly with our movement as we turn and as we

16
00:00:58,380 --> 00:01:03,210
‫move forward and backward, the camera just sort of automatically follows along.

17
00:01:03,210 --> 00:01:08,850
‫Now, there's a nice trick we can add to this camera that can make it a little bit smoother.

18
00:01:08,850 --> 00:01:11,730
‫Let's go ahead and open up BP pond tank.

19
00:01:11,940 --> 00:01:16,830
‫Now here in BP Pond Tank, I'm going to select our spring arm component.

20
00:01:16,830 --> 00:01:23,580
‫And if I search for camera lag, I'll see here in the lag section, there's this checkbox enable camera

21
00:01:23,580 --> 00:01:24,360
‫lag.

22
00:01:24,390 --> 00:01:28,440
‫I'm going to check that and enable camera rotation lag.

23
00:01:28,470 --> 00:01:30,240
‫I'm going to check that as well.

24
00:01:30,240 --> 00:01:37,590
‫Now, this allows us to have the camera lag behind and smoothly catch up, which creates a nice sort

25
00:01:37,590 --> 00:01:39,780
‫of professional camera effect.

26
00:01:39,780 --> 00:01:42,810
‫Let's go ahead and hit play and test this out.

27
00:01:42,810 --> 00:01:50,490
‫So notice as I move, the camera takes a short amount of time to sort of catch up as we're moving.

28
00:01:50,490 --> 00:01:53,190
‫And the same goes for when we're rotating.

29
00:01:53,190 --> 00:01:59,970
‫So it's like there's a bit of inertia and the camera is on some sort of sliding track and it slows to

30
00:01:59,970 --> 00:02:00,840
‫a stop.

31
00:02:00,840 --> 00:02:07,710
‫Now we can select the spring arm and we can change the camera lag speed and rotation lag speed.

32
00:02:07,710 --> 00:02:15,300
‫So, for example, if I place this at a smaller value, say five and five rather than ten, now let's

33
00:02:15,300 --> 00:02:16,950
‫take a look at how it looks.

34
00:02:17,040 --> 00:02:21,450
‫So I'm moving and you'll see that the camera has a bit more lag.

35
00:02:21,450 --> 00:02:25,170
‫Now, we can increase or decrease this as we see fit.

36
00:02:25,170 --> 00:02:31,170
‫This is something that you can experiment with and sort of find the values that work for you.

37
00:02:31,200 --> 00:02:36,930
‫Here we have a value of two and for me that's a little bit too much lag.

38
00:02:36,930 --> 00:02:41,100
‫So I think something between five and two would work for me.

39
00:02:41,100 --> 00:02:46,290
‫If you like this sort of value, then maybe you'll keep it at two or maybe even lower.

40
00:02:46,290 --> 00:02:54,360
‫But I'm going to put this at a value of, say, four for the camera lag speed and four for camera rotation

41
00:02:54,360 --> 00:02:55,320
‫lag speed.

42
00:02:55,350 --> 00:02:57,270
‫Let's take a look at how that looks.

43
00:02:57,270 --> 00:02:59,850
‫So as I move, the camera lags.

44
00:02:59,850 --> 00:03:03,660
‫There's clearly some camera lag, but it's not too much.

45
00:03:03,660 --> 00:03:09,660
‫I think this actually looks pretty good, so I'm pretty satisfied with that.

46
00:03:10,320 --> 00:03:15,960
‫Our next item is the tower firing after the tank has already died.

47
00:03:15,960 --> 00:03:18,930
‫Let me just go ahead and show you what I mean.

48
00:03:19,020 --> 00:03:19,740
‫There we go.

49
00:03:19,740 --> 00:03:23,880
‫The tank has died and the towers are still firing.

50
00:03:23,970 --> 00:03:26,970
‫Now, this is because the tank still exists.

51
00:03:26,970 --> 00:03:31,290
‫And as long as it's in fire range, the towers will continue to fire.

52
00:03:31,290 --> 00:03:38,130
‫This is easily handled by having a sort of variable that we can check to see if the tank has died.

53
00:03:38,520 --> 00:03:45,690
‫So I'm going to go into the tank class here and tank, and I'm going to add a Boolean variable that

54
00:03:45,690 --> 00:03:48,690
‫we can check to see if the tank is still alive.

55
00:03:48,690 --> 00:03:53,580
‫And I'm going to make this public since we plan on accessing it from outside the class.

56
00:03:53,580 --> 00:04:00,690
‫So I'm going to make this a bull variable called Be Alive, and I'm going to set it equal to true by

57
00:04:00,690 --> 00:04:01,500
‫default.

58
00:04:01,500 --> 00:04:09,270
‫So the tank will start off in the alive state and then as the tank dies, alive will be set to false.

59
00:04:09,270 --> 00:04:14,130
‫And that can happen in tank CP in handle destruction.

60
00:04:14,130 --> 00:04:16,530
‫So let's go to handle destruction here.

61
00:04:16,530 --> 00:04:23,070
‫And after we've set these other properties, I'm going to set B alive equal to false.

62
00:04:23,190 --> 00:04:29,730
‫So since we're setting B alive to false, we can know if the tank has died and then we can simply prevent

63
00:04:29,730 --> 00:04:33,120
‫firing the projectiles by checking this boolean.

64
00:04:33,120 --> 00:04:38,790
‫So let's go into Tower Dot, CP and here in check fire condition.

65
00:04:38,790 --> 00:04:42,990
‫We can make sure that the tank is still alive before we fire.

66
00:04:42,990 --> 00:04:46,290
‫So first I'm going to see if tank is valid.

67
00:04:46,290 --> 00:04:52,560
‫I'm going to say if tank is equal to null pointer, then I'll simply return early.

68
00:04:52,560 --> 00:04:59,010
‫That way we know Tank will be valid and then in our check to see if we're in fire range, I'm going

69
00:04:59,010 --> 00:05:03,420
‫to add an and and see if Tank be alive.

70
00:05:03,450 --> 00:05:03,870
‫If tank.

71
00:05:03,980 --> 00:05:05,830
‫Is alive, then we can fire.

72
00:05:05,840 --> 00:05:08,840
‫If Tank is not alive, we will not fire.

73
00:05:09,020 --> 00:05:14,900
‫Now, you may be wondering whether or not it's a good idea to put the return on a single line like you've

74
00:05:14,900 --> 00:05:16,610
‫seen me do in previous videos.

75
00:05:16,610 --> 00:05:23,960
‫And this is a good opportunity to discuss Unreal Engines, best programming practices, and recommendations.

76
00:05:23,990 --> 00:05:30,590
‫Unreal engine coding practices do recommend that you have curly braces with a body for all of your if

77
00:05:30,590 --> 00:05:33,080
‫statements, even those that have a single statement.

78
00:05:33,080 --> 00:05:39,200
‫And the reason is because if you plan on adding multiple lines of code to this, then you already have

79
00:05:39,200 --> 00:05:40,190
‫the body here.

80
00:05:40,190 --> 00:05:41,690
‫And it's also more clear.

81
00:05:41,690 --> 00:05:46,160
‫And that also brings me to another point, which is my use of auto.

82
00:05:46,190 --> 00:05:53,720
‫I used auto here in the projectile class a couple of times, and while this can be efficient, it's

83
00:05:53,720 --> 00:06:01,940
‫not as obvious what the types are at first glance, which is why the use of auto is also not recommended

84
00:06:01,940 --> 00:06:04,220
‫in unreal engine coding practices.

85
00:06:04,220 --> 00:06:09,770
‫If you want to stick to Unreal Engine recommended coding practices, you can replace these instances

86
00:06:09,770 --> 00:06:11,570
‫of auto with the actual type.

87
00:06:11,570 --> 00:06:19,460
‫For example, here, get instigator controller returns an A controller so we can change that to a controller

88
00:06:19,550 --> 00:06:20,990
‫and that's a pointer.

89
00:06:20,990 --> 00:06:29,210
‫This you damage type static class returns a U class so we could use you class here and of course get

90
00:06:29,210 --> 00:06:37,940
‫owner up here returns an a actor so we could use a actor instead of auto here and now if you look at

91
00:06:37,940 --> 00:06:44,840
‫this code, it's a lot more obvious what these types are, whereas auto just sort of masks everything

92
00:06:44,840 --> 00:06:48,740
‫and allows you to be lazy and get away with not typing the types.

93
00:06:48,740 --> 00:06:55,790
‫Now sometimes I'm not sure what a big expression returns, so I'll use auto just to see what that type

94
00:06:55,790 --> 00:07:00,410
‫is and then later I'll replace it with the actual type.

95
00:07:00,410 --> 00:07:07,880
‫So that's another way you can use auto to help you learn the types return by long, complicated expressions

96
00:07:07,880 --> 00:07:08,540
‫like this.

97
00:07:08,540 --> 00:07:14,120
‫So since we're in the polishing up stages, I'm going to replace auto with the actual type names here

98
00:07:14,120 --> 00:07:15,350
‫in projectile.

99
00:07:15,380 --> 00:07:23,390
‫I'm also going to go into base pawn in the fire function where we have this projectile and this is returned

100
00:07:23,390 --> 00:07:25,940
‫from this big long expression here.

101
00:07:25,940 --> 00:07:34,550
‫Spawn actor is going to return an a projectile in this case so I can replace this with a projectile.

102
00:07:35,640 --> 00:07:36,150
‫Okay.

103
00:07:36,150 --> 00:07:39,840
‫So that's going to polish up the code on the C++ side.

104
00:07:39,840 --> 00:07:41,850
‫Let's go ahead and compile this.

105
00:07:41,850 --> 00:07:47,910
‫And with a successful compile, let's hop back into the editor and we're going to hit play and let's

106
00:07:47,910 --> 00:07:52,890
‫just make sure that those towers stop shooting at us after we've died.

107
00:07:52,890 --> 00:07:54,180
‫So there's one hit.

108
00:07:55,050 --> 00:08:00,270
‫There's another one, and I'm waiting, and I don't see any more projectiles.

109
00:08:00,300 --> 00:08:01,230
‫Perfect.

110
00:08:01,260 --> 00:08:01,680
‫Okay.

111
00:08:01,680 --> 00:08:07,500
‫So the last point I'd like to cover before we wrap this up is the projectile spawn point.

112
00:08:07,530 --> 00:08:14,550
‫Now, let's select that here in BP Pond Tank and make sure that it's spaced far enough away from the

113
00:08:14,550 --> 00:08:15,120
‫barrel.

114
00:08:15,150 --> 00:08:19,890
‫Before we do that, I'm going to place it really, really close and show you some issues that could

115
00:08:19,890 --> 00:08:21,240
‫potentially arise.

116
00:08:21,270 --> 00:08:27,570
‫Now, as I'm moving forward and clicking the left mouse button, you'll see that I don't see the projectile.

117
00:08:27,570 --> 00:08:31,530
‫In fact, I don't see it at all because it's just too close.

118
00:08:31,530 --> 00:08:33,100
‫We're already getting a collision.

119
00:08:33,120 --> 00:08:35,970
‫It's being destroyed before it can do anything.

120
00:08:35,970 --> 00:08:39,810
‫So make sure that it's a good deal away from the barrel.

121
00:08:39,840 --> 00:08:45,960
‫We're spawning some smoke anyway, so it's going to look like a smoke trail is following behind it.

122
00:08:45,960 --> 00:08:48,450
‫So this will still look pretty realistic.

123
00:08:49,970 --> 00:08:51,250
‫So that looks pretty good.

124
00:08:51,260 --> 00:08:58,040
‫And while we're on projectile spawn points, it might be a good idea to go and look at the BP pond turret

125
00:08:58,040 --> 00:09:01,010
‫and select its projectile spawn point.

126
00:09:01,010 --> 00:09:05,270
‫And if you've had any issues spawning projectiles from the turret, you might want to make sure it's

127
00:09:05,270 --> 00:09:10,570
‫a good distance away from the barrel of the turret as well.

128
00:09:10,580 --> 00:09:11,810
‫So there we have it.

129
00:09:11,810 --> 00:09:15,980
‫We have a functional game and it looks fantastic.

130
00:09:15,980 --> 00:09:21,650
‫We have the ability to roll around in the world, we have the ability to shoot projectiles and they

131
00:09:21,650 --> 00:09:22,760
‫blow stuff up.

132
00:09:22,760 --> 00:09:25,190
‫If we hit a tower, we can destroy it.

133
00:09:25,190 --> 00:09:28,430
‫If the tower hits us, it can destroy us.

134
00:09:29,380 --> 00:09:30,700
‫Just like that.

135
00:09:30,700 --> 00:09:38,110
‫And we have winning and losing conditions with HUD widgets that display on the screen and tell us whether

136
00:09:38,110 --> 00:09:40,330
‫we've won or lost the game.

137
00:09:40,330 --> 00:09:42,610
‫So this is fantastic.

138
00:09:42,610 --> 00:09:48,670
‫And if you would like to package this game, you can easily do so by going up to the top and clicking

139
00:09:48,670 --> 00:09:56,710
‫on the platforms icon either for Windows, if you're on a Windows machine or for iOS, if you're using

140
00:09:56,710 --> 00:10:00,670
‫a mac machine, then of course you have these other options.

141
00:10:00,670 --> 00:10:06,640
‫If you'd like to package for other platforms, I recommend you do some research online to look up the

142
00:10:06,640 --> 00:10:08,980
‫different platforms and how to package for them.

143
00:10:08,980 --> 00:10:14,920
‫I'm on a Windows Machine so I can simply click package project for Windows here and it's going to ask

144
00:10:14,920 --> 00:10:17,410
‫me where I'd like to package my game.

145
00:10:17,410 --> 00:10:19,780
‫Now I have my project here in Tune Tanks.

146
00:10:19,780 --> 00:10:24,670
‫I'm going to right click, create a new folder and I'm simply going to call this build.

147
00:10:24,670 --> 00:10:29,110
‫That's typically where you would put a packaged project.

148
00:10:29,110 --> 00:10:34,720
‫So I'm going to select that folder and allow Unreal Engine to package up my game.

149
00:10:34,720 --> 00:10:40,300
‫It's probably going to take a few minutes and once it's done, I should have a packaged game.

150
00:10:41,080 --> 00:10:41,530
‫Okay.

151
00:10:41,530 --> 00:10:48,070
‫So once I've finished packaging we should see build successful in the output log and then we can look

152
00:10:48,070 --> 00:10:51,970
‫in the folder that we designated for our packaged project.

153
00:10:51,970 --> 00:10:54,670
‫For me, it's going to be this build folder.

154
00:10:54,700 --> 00:11:02,220
‫Now I packaged four windows, so I have a Windows folder and here is my tune tanks, dot xy.

155
00:11:02,230 --> 00:11:03,490
‫It's an executable.

156
00:11:03,520 --> 00:11:08,440
‫I can double click on it and here is my final project.

157
00:11:08,440 --> 00:11:09,490
‫I can shoot.

158
00:11:09,580 --> 00:11:11,260
‫I can dodge.

159
00:11:11,990 --> 00:11:18,110
‫Looks like my enemy towers can shoot at me and I can destroy them.

160
00:11:18,110 --> 00:11:19,550
‫Yes, I can destroy them.

161
00:11:19,550 --> 00:11:23,240
‫They can destroy me, it looks like, and I can lose the game.

162
00:11:23,360 --> 00:11:26,990
‫And of course, if I was a bit more skilled, I could win the game.

163
00:11:27,170 --> 00:11:33,230
‫And for your final challenge, I'm going to task you with adding your own flavor to the game.

164
00:11:33,230 --> 00:11:35,420
‫Make this game your own.

165
00:11:35,420 --> 00:11:42,200
‫Find some new sounds or effects or meshes and create some funky looking towers and tanks.

166
00:11:42,200 --> 00:11:48,410
‫Add more towers, maybe add different skill levels, make the towers harder and harder as you progress

167
00:11:48,410 --> 00:11:49,580
‫throughout your level.

168
00:11:49,580 --> 00:11:56,480
‫Maybe level up the tank, give it a level that you can increase as you destroy more and more towers.

169
00:11:56,480 --> 00:12:03,980
‫Maybe you can add new level geometry and make the tank climb up ramps and try to destroy tanks in hard

170
00:12:03,980 --> 00:12:05,330
‫to reach areas.

171
00:12:05,360 --> 00:12:09,050
‫The possibilities are endless, but most importantly, have fun.

172
00:12:09,050 --> 00:12:10,700
‫While you're developing your games.

173
00:12:10,700 --> 00:12:13,160
‫You're not going to pause the video for this challenge.

174
00:12:13,160 --> 00:12:19,070
‫This is going to be something that you can do from this point forward with your game projects.

175
00:12:19,070 --> 00:12:20,630
‫So congratulations.

176
00:12:20,630 --> 00:12:21,980
‫We finished our game.

177
00:12:21,980 --> 00:12:23,750
‫I hope you enjoyed this section.

178
00:12:23,750 --> 00:12:25,460
‫I had a ton of fun.

179
00:12:25,460 --> 00:12:28,790
‫This is a great game project and you've come a long way.

180
00:12:28,790 --> 00:12:34,070
‫You've learned a ton of skills throughout this section of the course, so I hope you're ready to move

181
00:12:34,070 --> 00:12:35,930
‫on to more exciting things.

182
00:12:35,930 --> 00:12:36,890
‫Thank you very much.

183
00:12:36,890 --> 00:12:39,770
‫I'm Steven and I'll see you soon.

