﻿1
00:00:04,470 --> 00:00:08,280
‫So we know that we need some components on our base -- class.

2
00:00:08,280 --> 00:00:12,570
‫We know that we need a base mesh for the bottom part of the tank and the turret.

3
00:00:12,600 --> 00:00:15,270
‫We also need a turret mesh for the top part.

4
00:00:15,300 --> 00:00:19,500
‫We need a capsule to handle collision and we need a projectile spawn point.

5
00:00:19,500 --> 00:00:21,270
‫That's going to be a scene component.

6
00:00:21,300 --> 00:00:26,460
‫Now, once we've added these things to the base pod class, then anything that we create based on this

7
00:00:26,460 --> 00:00:28,320
‫class will inherit those things.

8
00:00:28,320 --> 00:00:34,920
‫So we could create a tank based on base -- and then we could go and create a tower also based on base

9
00:00:34,920 --> 00:00:35,550
‫--.

10
00:00:35,700 --> 00:00:39,620
‫And because they're based on base pod, they inherit these components.

11
00:00:39,630 --> 00:00:46,380
‫The tank can have its own base mesh, its own turret mesh, its own capsule and its own projectile spawn

12
00:00:46,380 --> 00:00:46,800
‫point.

13
00:00:46,800 --> 00:00:52,500
‫And likewise, the tower will get its own base mesh turret mesh capsule component and projectile spawn

14
00:00:52,500 --> 00:00:53,370
‫point as well.

15
00:00:53,370 --> 00:00:58,560
‫And we'll see very soon how we can assign different meshes to each of these so they look different.

16
00:00:58,560 --> 00:01:00,750
‫So we know that we need some components.

17
00:01:00,750 --> 00:01:05,490
‫Now it's time to actually add some components to our base -- class.

18
00:01:05,910 --> 00:01:11,400
‫Now, by default, we already have a public section, a protected section, and the second public section

19
00:01:11,400 --> 00:01:12,240
‫down here.

20
00:01:12,570 --> 00:01:17,520
‫There are various reasons to have multiple public sections and we'll talk about those later.

21
00:01:17,520 --> 00:01:20,880
‫But for our components, we're going to create a private section.

22
00:01:22,070 --> 00:01:28,400
‫As you've learned previously, it's good to have member variables be private, so that way they're only

23
00:01:28,400 --> 00:01:31,790
‫accessible from within the class that owns them.

24
00:01:31,790 --> 00:01:33,410
‫So we need some components.

25
00:01:33,680 --> 00:01:36,190
‫The first one I'm going to add is the capsule.

26
00:01:36,200 --> 00:01:40,760
‫So let's create a variable of type you capsule component.

27
00:01:42,160 --> 00:01:44,030
‫Now this is going to be a pointer.

28
00:01:44,070 --> 00:01:48,880
‫We're going to use pointers for the majority of our variables as long as they're not base types like

29
00:01:48,880 --> 00:01:50,340
‫integer or float.

30
00:01:50,350 --> 00:01:55,600
‫And as you know, that's because pointers are lightweight, they're just addresses and they allow us

31
00:01:55,600 --> 00:01:56,860
‫to be more efficient.

32
00:01:56,950 --> 00:02:03,400
‫So we have this U capsule component pointer and we're going to call this capsule comp short for capsule

33
00:02:03,400 --> 00:02:04,030
‫component.

34
00:02:04,030 --> 00:02:11,140
‫Now just above capsule component, we're going to add an unreal engine specific macro and it's you property

35
00:02:11,470 --> 00:02:14,020
‫in all caps with its own parentheses.

36
00:02:14,020 --> 00:02:20,590
‫You property is a way to make unreal engine aware of this variable so that it can participate in unreal

37
00:02:20,590 --> 00:02:20,980
‫engines.

38
00:02:20,980 --> 00:02:22,240
‫Reflection System.

39
00:02:22,690 --> 00:02:28,750
‫The reflection system allows us to do things like expose this variable to blueprints and participate

40
00:02:28,750 --> 00:02:31,060
‫in garbage collection and things like that.

41
00:02:31,060 --> 00:02:36,400
‫So adding the you property is going to be something that will add to our components as we create them.

42
00:02:36,400 --> 00:02:41,980
‫So we have this capsule component and because we're using the YOU capsule component type, we need to

43
00:02:41,980 --> 00:02:44,860
‫let the compiler know about this type.

44
00:02:44,860 --> 00:02:48,250
‫It doesn't know by default what a capsule component is.

45
00:02:48,250 --> 00:02:54,640
‫Now normally to tell the compiler what a capsule component is, we would include a header file up here

46
00:02:54,640 --> 00:02:59,680
‫at the top with our include directives if we go to the unreal engine documentation and search for you

47
00:02:59,710 --> 00:03:05,200
‫capsule component, we can see right here where it says include the header file that we would need to

48
00:03:05,200 --> 00:03:08,950
‫include to tell the compiler about the capsule component.

49
00:03:08,950 --> 00:03:13,000
‫Now we could include this right here at the top and then our U.

50
00:03:13,000 --> 00:03:18,160
‫Capsule component type would be recognized by the compiler and everything would be hunky dory.

51
00:03:18,220 --> 00:03:24,070
‫But general, good practice when it comes to coding these things is to try to keep this header file

52
00:03:24,070 --> 00:03:25,720
‫as small as possible.

53
00:03:25,720 --> 00:03:32,380
‫Whenever we include a header file in this file, a program called the preprocessor takes all of the

54
00:03:32,380 --> 00:03:37,720
‫contents of that header file, strips out some things like comments, and then literally pastes all

55
00:03:37,720 --> 00:03:40,780
‫of the contents of that header file into this file.

56
00:03:41,050 --> 00:03:46,810
‫The result is that this file gets bigger because it has the contents of that included file paste it

57
00:03:46,810 --> 00:03:47,530
‫in here.

58
00:03:47,530 --> 00:03:50,950
‫We only want to include things when we use them.

59
00:03:50,950 --> 00:03:56,740
‫So how do we get away with not including the header file here in the base -- header?

60
00:03:56,740 --> 00:04:02,380
‫Well, we can use something in C++ known as forward declaration.

61
00:04:02,380 --> 00:04:07,990
‫We forward declare this u capsule component type using the class keyword like this.

62
00:04:08,470 --> 00:04:15,310
‫Notice the compiler now shows this type as green whenever we forward declare a variable were then able

63
00:04:15,310 --> 00:04:18,010
‫to get away with not including its header file.

64
00:04:18,010 --> 00:04:23,830
‫It's telling the compiler that this is a type so it'll no longer give us IntelliSense errors, saying

65
00:04:23,830 --> 00:04:26,170
‫that it doesn't recognize this as a type.

66
00:04:26,170 --> 00:04:28,150
‫Now this is an incomplete type.

67
00:04:28,150 --> 00:04:34,150
‫If we actually try to use this type either by accessing members like functions and variables or trying

68
00:04:34,150 --> 00:04:38,560
‫to construct an object of this type, we would get an error because it's an incomplete type.

69
00:04:38,560 --> 00:04:44,950
‫We would need the header file included wherever we use this type to do those things so we could forward

70
00:04:44,950 --> 00:04:48,400
‫declare a pointer of a type to avoid needing the header file.

71
00:04:48,400 --> 00:04:53,230
‫But it's important to note that we do need header files to inherit from particular classes.

72
00:04:53,230 --> 00:05:00,130
‫Notice that this class inherits from a pond and the pond header file is included here at the top.

73
00:05:00,130 --> 00:05:05,470
‫So inheritance does require the header file for the type we're inheriting from.

74
00:05:05,470 --> 00:05:09,100
‫So let's discuss forward declaration and why we want to do it.

75
00:05:09,130 --> 00:05:16,120
‫Let's say we have a class called Base Pon which needs to have a pointer variable of type you capsule

76
00:05:16,120 --> 00:05:17,020
‫component.

77
00:05:17,050 --> 00:05:22,060
‫Now you capsule component is in the capsule component header file.

78
00:05:22,060 --> 00:05:28,470
‫Now we're actually going to use this type in based upon when we construct an object of the U.

79
00:05:28,480 --> 00:05:30,010
‫Capsule component type.

80
00:05:30,010 --> 00:05:36,820
‫So in, based upon all we really need is to have a pointer of type U capsule component.

81
00:05:37,000 --> 00:05:44,440
‫Now the truth is based upon H doesn't actually need the implementation details of the capsule component

82
00:05:44,440 --> 00:05:45,160
‫class.

83
00:05:45,160 --> 00:05:50,680
‫In other words, it doesn't need to know how the functions are defined or even how big the capsule component

84
00:05:50,680 --> 00:05:51,820
‫class is.

85
00:05:51,850 --> 00:05:55,750
‫A capsule component pointer is the same size as any other pointer.

86
00:05:55,750 --> 00:05:57,250
‫It's just an address.

87
00:05:57,250 --> 00:05:58,810
‫Now in the base plan class.

88
00:05:58,810 --> 00:06:01,420
‫We want to construct the capsule component.

89
00:06:01,510 --> 00:06:08,260
‫For this reason, we need to know the size of a capsule component in order to lay out the memory necessary

90
00:06:08,260 --> 00:06:09,790
‫for creating this object.

91
00:06:09,790 --> 00:06:16,060
‫So while the capsule component header is not strictly needed in base Ponca It's absolutely needed in

92
00:06:16,060 --> 00:06:16,330
‫base.

93
00:06:16,350 --> 00:06:24,970
‫Porkpie So good programming practice is to only include headers where you actually need them so we can

94
00:06:24,970 --> 00:06:32,410
‫get away with declaring a pointer of type U capsule component pointer in base product H and then include

95
00:06:32,410 --> 00:06:39,310
‫capsule components where we need the implementation details because we're constructing a capsule component

96
00:06:39,310 --> 00:06:41,020
‫and we need to know the size of a.

97
00:06:41,310 --> 00:06:43,230
‫Capsule component in memory.

98
00:06:43,350 --> 00:06:49,920
‫Now let's discuss the consequences of including the header file in base pond FX instead.

99
00:06:50,010 --> 00:06:55,410
‫As we've seen, we can absolutely do this and you may be thinking, well, we're including it in base

100
00:06:55,410 --> 00:07:01,230
‫pont CP Anyway, so what difference does it make if we include it in one file versus another?

101
00:07:01,260 --> 00:07:03,180
‫Now here's where the problem comes in.

102
00:07:03,210 --> 00:07:07,390
‫Header files are designed to be included by other files.

103
00:07:07,410 --> 00:07:12,810
‫So let's say that we have Base Pond H and we've included capsule components in it.

104
00:07:12,810 --> 00:07:18,600
‫And then further down the road we have some other class and we're going to have a base pond pointer

105
00:07:18,600 --> 00:07:23,370
‫in some other class, just like we had a capsule component pointer in base pod.

106
00:07:23,400 --> 00:07:28,230
‫Now, rather than going through the trouble of forward declaring the base pond pointer and some other

107
00:07:28,230 --> 00:07:33,810
‫class, we're just going to declare it as normal and include base pawn in some other class.

108
00:07:34,680 --> 00:07:41,520
‫So now not only does Base Pond H include the capsule component header, which results in more code being

109
00:07:41,520 --> 00:07:43,190
‫copied into that header file.

110
00:07:43,200 --> 00:07:47,820
‫Now some other class has base upon, which includes capsule component.

111
00:07:47,820 --> 00:07:55,470
‫So all of the content and capsule components is also inside of some other class H and it's not even

112
00:07:55,470 --> 00:07:56,400
‫needed there.

113
00:07:56,400 --> 00:08:01,910
‫Some other class that H only needs to know about base upon it doesn't care about capsule component.

114
00:08:01,920 --> 00:08:07,920
‫Now say we continue this pattern and create some other class called yet another class and yet another

115
00:08:07,920 --> 00:08:13,680
‫class may need to have a pointer of type some other class now rather than forward declaring.

116
00:08:13,680 --> 00:08:21,180
‫We just include some other class H in yet another class H and now inside of yet another class H.

117
00:08:21,210 --> 00:08:27,840
‫Even though we don't even need the header for base pond or capsule component H, we got it in yet another

118
00:08:27,840 --> 00:08:32,730
‫class because some other class includes those header files inside of it.

119
00:08:32,730 --> 00:08:40,140
‫So we have copies of all of the contents of capsule components and based upon H just stuck here in yet

120
00:08:40,140 --> 00:08:46,620
‫another class, bloating up that file and increasing compile times all because we didn't forward declare.

121
00:08:46,620 --> 00:08:52,440
‫So instead the better thing to do is include header files where they're actually needed.

122
00:08:52,440 --> 00:08:59,610
‫So if we take capsule components and only include it in based upon CPP, then later down the road when

123
00:08:59,610 --> 00:09:05,340
‫we create some other class and actually need to use the base pod, we can include the header there and

124
00:09:05,340 --> 00:09:12,840
‫base upon does not include capsule components, so all that extra code is not included in some other

125
00:09:12,840 --> 00:09:13,440
‫class.

126
00:09:13,440 --> 00:09:18,810
‫And then when we go and create yet another class which needs some other class, we can include some

127
00:09:18,810 --> 00:09:24,990
‫other class that h in yet another class that CPP where it's actually needed and then yet another class

128
00:09:24,990 --> 00:09:30,270
‫that H does not get filled up with the contents of other header files that it doesn't need.

129
00:09:30,270 --> 00:09:36,990
‫So when classes have dependencies like this based upon depends on capsule component, it's best to keep

130
00:09:36,990 --> 00:09:38,670
‫those dependencies to a minimum.

131
00:09:38,880 --> 00:09:42,570
‫So I'm going to challenge you to create a compilation error.

132
00:09:42,570 --> 00:09:44,970
‫We shouldn't be afraid of compilation errors.

133
00:09:44,970 --> 00:09:47,550
‫They're just a normal part of the development process.

134
00:09:47,550 --> 00:09:54,210
‫So we're going to generate one intentionally go back and remove the class keyword and compile without

135
00:09:54,210 --> 00:09:56,160
‫forward declaring capsule comp.

136
00:09:56,160 --> 00:10:04,080
‫Now when I say compile, I mean you can compile from Visual Studio code, just a regular C++ compile.

137
00:10:04,110 --> 00:10:10,500
‫You've learned how to do that, or you can simply save your file and Visual Studio code and initiate

138
00:10:10,500 --> 00:10:11,670
‫live coding.

139
00:10:11,670 --> 00:10:16,800
‫Either one of those is fine and once we go through this together, I'll show you what happens with both

140
00:10:16,800 --> 00:10:17,280
‫methods.

141
00:10:17,280 --> 00:10:22,440
‫If you use live coding, of course you're going to be looking at the generated output in the live coding

142
00:10:22,440 --> 00:10:27,270
‫window as opposed to the output that you would see in Visual Studio code.

143
00:10:27,270 --> 00:10:33,060
‫Now spoiler, you're going to get a compilation error, look at the compilation error message, see

144
00:10:33,060 --> 00:10:34,260
‫what it's telling you.

145
00:10:34,470 --> 00:10:38,070
‫This is just a familiarize ourselves with the errors that we generate.

146
00:10:38,070 --> 00:10:43,500
‫Then after this, go back and forward, declare capsule comp using the class keyword.

147
00:10:43,620 --> 00:10:48,450
‫Once you've done that, compile again, you should get a successful compilation this time.

148
00:10:48,780 --> 00:10:51,060
‫Pause the video and give this a try.

149
00:10:53,520 --> 00:10:56,350
‫All right, so let's wreak some havoc on our code here.

150
00:10:56,370 --> 00:10:58,320
‫I'm going to remove the class keyword.

151
00:10:58,700 --> 00:11:03,540
‫Okay, so we've attempted to compile, and here is the output in the terminal.

152
00:11:03,570 --> 00:11:09,300
‫The first thing we see is error and it gives us an error code and it says capsule comp is not a member

153
00:11:09,300 --> 00:11:10,830
‫of a base pawn.

154
00:11:10,860 --> 00:11:17,040
‫We have a note that says C declaration of a base pawn and then we see that we get other errors as a

155
00:11:17,040 --> 00:11:17,940
‫result of this.

156
00:11:17,940 --> 00:11:23,390
‫So oftentimes students will get confused when they attempt to compile and seem multiple errors.

157
00:11:23,400 --> 00:11:28,560
‫So this goes to show that a single mistake can propagate a series of errors.

158
00:11:28,560 --> 00:11:31,670
‫And that doesn't mean you have to go and fix a whole bunch of files.

159
00:11:31,680 --> 00:11:34,410
‫The error could have a single origin here.

160
00:11:34,410 --> 00:11:36,420
‫We know what the origin of the error is.

161
00:11:36,420 --> 00:11:37,820
‫We need to forward declare.

162
00:11:37,830 --> 00:11:45,150
‫Now let's see what happens if we use live coding instead of regular compilation and Visual Studio code.

163
00:11:45,150 --> 00:11:51,450
‫So I'm going to go ahead and click the button to initiate live coding and right away in red I see build

164
00:11:51,450 --> 00:11:54,270
‫failed and we see the same thing here.

165
00:11:54,270 --> 00:11:55,050
‫Right here.

166
00:11:55,050 --> 00:11:59,310
‫Capsule comp is not a member of a base pawn note.

167
00:11:59,340 --> 00:12:01,860
‫See the declaration of a base pawn.

168
00:12:01,860 --> 00:12:03,750
‫So we see the same thing here.

169
00:12:03,750 --> 00:12:08,490
‫So either case we're going to see an error like this when we forget to forward declare.

170
00:12:08,490 --> 00:12:16,170
‫So now we know what it looks like and now we're more informed and less afraid of these mysterious compilation

171
00:12:16,170 --> 00:12:17,340
‫error messages.

172
00:12:17,460 --> 00:12:23,280
‫So what we're going to do is fix this error by forward declaring you capsule component, and then we

173
00:12:23,280 --> 00:12:24,990
‫can attempt to compile again.

174
00:12:24,990 --> 00:12:27,780
‫And now we've compiled without any errors.

175
00:12:27,870 --> 00:12:32,070
‫So now we see what it looks like when we forgot to forward declare a variable.

176
00:12:32,100 --> 00:12:35,250
‫Keep that in mind when you get compiler errors in the future.

177
00:12:35,760 --> 00:12:41,490
‫So in summary, we discussed forward declaration when creating a new pointer and we learned that you

178
00:12:41,490 --> 00:12:48,370
‫should only include what you use in the CP file and we should include as little as possible in the H

179
00:12:48,450 --> 00:12:49,020
‫file.

180
00:12:49,050 --> 00:12:55,020
‫We know that we don't need the header file to declare a new pointer as long as we forward declare and

181
00:12:55,020 --> 00:13:00,090
‫that we do need the header file if we're going to be constructing an object of a particular type.

182
00:13:00,090 --> 00:13:05,850
‫And we do need the header file to access members like functions and variables and we saw that we actually

183
00:13:05,850 --> 00:13:09,780
‫do need the header file for inheritance for inheriting from a class.

184
00:13:09,780 --> 00:13:11,460
‫We need that header file there.

185
00:13:11,580 --> 00:13:17,160
‫So now that we know how to forward declare a type and we have our pointer capsule comp, we're ready

186
00:13:17,160 --> 00:13:21,840
‫to actually construct a capsule component object and we'll do that in the next video.

187
00:13:22,200 --> 00:13:23,040
‫I'll see you soon.

