﻿1
00:00:04,710 --> 00:00:06,600
‫Hello and welcome back.

2
00:00:06,630 --> 00:00:09,660
‫Now we're ready to start handling user input.

3
00:00:09,780 --> 00:00:15,000
‫That means we'd like to press the keyboard keys and move the mouse and click the mouse and see our tank

4
00:00:15,000 --> 00:00:16,650
‫react to that input.

5
00:00:16,770 --> 00:00:22,260
‫Now, in order to do that, we first need to actually get that input and we're first going to start

6
00:00:22,260 --> 00:00:24,450
‫doing that using axis mappings.

7
00:00:24,450 --> 00:00:25,980
‫So let's talk about this.

8
00:00:26,100 --> 00:00:30,600
‫Now here in the project, let's go to edit and project settings.

9
00:00:30,780 --> 00:00:35,340
‫And if we scroll down and select input, then we see our bindings here.

10
00:00:35,340 --> 00:00:39,600
‫And under bindings there are action mappings and axis mappings.

11
00:00:39,630 --> 00:00:42,300
‫We're first going to get into axis mappings.

12
00:00:42,350 --> 00:00:47,370
‫Now you may have some experience with these, but we're going to take a little bit of a deeper dive

13
00:00:47,370 --> 00:00:49,700
‫into what these do and how they work.

14
00:00:49,710 --> 00:00:51,150
‫So we have three of them.

15
00:00:51,240 --> 00:00:58,800
‫And if I click on the dropdown arrow, I'll see here W and SW and these are talking about the W and

16
00:00:58,800 --> 00:01:00,780
‫SW keys on the keyboard.

17
00:01:00,810 --> 00:01:06,960
‫These are assigned to this particular axis mapping, which is called Move Forward.

18
00:01:06,960 --> 00:01:09,870
‫So let's discuss how this axis mapping works.

19
00:01:09,870 --> 00:01:17,280
‫So we saw in The Unreal Editor that we have this axis mapping called Move Forward and it's got the W

20
00:01:17,280 --> 00:01:20,820
‫and SCS assigned to this axis mapping.

21
00:01:20,820 --> 00:01:22,950
‫So what does this mean exactly?

22
00:01:23,730 --> 00:01:27,870
‫Well, in Unreal Engine, we have something called an axis mapping.

23
00:01:27,870 --> 00:01:32,970
‫And axis mapping is something that's processed every single frame of the game.

24
00:01:33,000 --> 00:01:35,700
‫You assign keys to an axis mapping.

25
00:01:35,700 --> 00:01:38,460
‫In our case, we've assigned W and S.

26
00:01:38,490 --> 00:01:41,370
‫Now take a look next to the W key here.

27
00:01:41,370 --> 00:01:45,060
‫In my little screenshot sample to the right, it says scale.

28
00:01:45,060 --> 00:01:48,180
‫And next to scale there's a number 1.0.

29
00:01:48,300 --> 00:01:53,160
‫And you may have noticed next to the SQ, the scale is -1.0.

30
00:01:53,160 --> 00:01:58,650
‫So these are values that will affect that input information.

31
00:01:58,650 --> 00:02:01,080
‫Here's how an axis mapping works.

32
00:02:01,320 --> 00:02:08,580
‫Our axis mapping move forward has the ability to be associated with a function in C++.

33
00:02:08,700 --> 00:02:15,060
‫Now, when it comes to Axis mappings, if we associate a function with an Axis mapping, it needs to

34
00:02:15,060 --> 00:02:21,810
‫take an input parameter of type float so we can create a function on our pond called MOVE that takes

35
00:02:21,810 --> 00:02:22,410
‫a float.

36
00:02:22,410 --> 00:02:24,870
‫We'll just call this input parameter value.

37
00:02:24,930 --> 00:02:30,570
‫Now there's a way to take this function and associate it with our move forward axis mapping.

38
00:02:30,570 --> 00:02:34,980
‫It said that we bind the move function to the axis mapping.

39
00:02:34,980 --> 00:02:41,430
‫So every frame of the game Unreal Engine's input system is going to check to see if we're pressing the

40
00:02:41,430 --> 00:02:43,680
‫W key or the key.

41
00:02:43,680 --> 00:02:50,730
‫And it's going to compute an axis value depending on whether or not we're pressing those keys and every

42
00:02:50,730 --> 00:02:51,600
‫single frame.

43
00:02:51,600 --> 00:02:58,080
‫It's going to call this function that we've bound to move forward and pass that axis value in.

44
00:02:58,080 --> 00:03:03,810
‫Whatever happens inside of that function is up to us as the C++ developer.

45
00:03:03,840 --> 00:03:05,310
‫Now here's how it works.

46
00:03:05,310 --> 00:03:10,860
‫If we're not pressing the W or the Keys, this axis value has the value zero.

47
00:03:10,860 --> 00:03:16,890
‫So the move function that's bound to the move forward axis mapping is called every single frame and

48
00:03:16,890 --> 00:03:19,620
‫the float value passed in is zero.

49
00:03:19,620 --> 00:03:22,380
‫Now let's say we're pressing the W key.

50
00:03:22,620 --> 00:03:26,820
‫The W key has its scale set to 1.0.

51
00:03:26,850 --> 00:03:33,870
‫This means that our axis value is going to be 1.0 and that's what gets passed into the MOV function.

52
00:03:33,870 --> 00:03:39,090
‫So every single frame, the move function is called with a value of 1.0 passed in.

53
00:03:39,120 --> 00:03:44,910
‫Now let's say instead we're pressing the SRC which has a scale value of -1.0.

54
00:03:44,940 --> 00:03:51,720
‫This means that every single frame the move function will be called and -1.0 will be passed in.

55
00:03:51,720 --> 00:03:58,260
‫Now in the case where we're pressing both W and S, then both of these values are added together.

56
00:03:58,260 --> 00:04:05,040
‫So we get the 1.0 from pressing the W key and we get -1.0 from pressing the SRC.

57
00:04:05,070 --> 00:04:07,200
‫Now these both cancel each other out.

58
00:04:07,320 --> 00:04:13,350
‫So if we're pressing both at the same time, the move function will be called with zero passed in.

59
00:04:13,710 --> 00:04:19,020
‫So depending on which combination of keys we're pressing, we'll get a different value passed into our

60
00:04:19,020 --> 00:04:25,230
‫MOVE function and we can do whatever we like with that value, such as use it to move the pawn.

61
00:04:25,230 --> 00:04:28,500
‫We'll talk about actually moving the pawn soon enough.

62
00:04:28,500 --> 00:04:34,620
‫For now, let's just work on actually setting ourselves up so that we can handle this information from

63
00:04:34,620 --> 00:04:36,390
‫the Axis mapping system.

64
00:04:36,930 --> 00:04:43,260
‫Okay, so now that we know how the Axis mapping works, it's time to create a callback function that

65
00:04:43,260 --> 00:04:46,620
‫we can bind to the move forward axis mapping.

66
00:04:46,620 --> 00:04:50,370
‫So I'm going to close project settings and hop back into VS code.

67
00:04:50,370 --> 00:04:58,470
‫So here in VS code, we'd like to create a function that we can bind to the move forward axis mapping.

68
00:04:58,470 --> 00:05:02,640
‫So here in tank H we can create a private function.

69
00:05:02,640 --> 00:05:03,810
‫Now it's going to have.

70
00:05:03,880 --> 00:05:07,180
‫The void return type, and I'd like to call this move.

71
00:05:07,210 --> 00:05:11,950
‫Now it needs to have a float input parameter, and we're going to call this value.

72
00:05:12,010 --> 00:05:16,750
‫So let's take our move function and define it here in Tank.

73
00:05:16,970 --> 00:05:25,450
‫CP I'll stick it here just under the constructor and we need a tank with the scope resolution operator

74
00:05:25,450 --> 00:05:27,310
‫before the function name.

75
00:05:27,460 --> 00:05:33,550
‫So we have this move function and we're ready to bind it to our move forward axis mapping.

76
00:05:33,670 --> 00:05:39,340
‫And that is done inside of a function called setup player input component.

77
00:05:39,370 --> 00:05:40,630
‫That should sound familiar.

78
00:05:40,630 --> 00:05:48,130
‫In fact, if we open our explorer and go back to Base Pont H, we can scroll down and see in the public

79
00:05:48,130 --> 00:05:51,910
‫section the function setup player input component.

80
00:05:51,910 --> 00:05:56,380
‫We'll see that this is an override of an inherited virtual function.

81
00:05:56,950 --> 00:06:03,430
‫Now the base spawn class does not really need to set up any inputs, and that's what this function is

82
00:06:03,430 --> 00:06:06,010
‫for handling input from a player.

83
00:06:06,040 --> 00:06:10,810
‫Now, our base bond class doesn't need to handle input, but our tank class does.

84
00:06:10,810 --> 00:06:18,160
‫So what we can do is take this function out of base pond h but I'm going to copy it because we need

85
00:06:18,160 --> 00:06:19,240
‫it in tank.

86
00:06:19,930 --> 00:06:26,380
‫So copying this function, I'm going to come over to Tank H and here in the public section I'm going

87
00:06:26,380 --> 00:06:27,190
‫to paste it.

88
00:06:27,190 --> 00:06:32,800
‫And since we don't need it in base pond, I'm just going to remove it from the base pond class.

89
00:06:32,800 --> 00:06:38,090
‫And in fact I'm going to go into base pond CP and remove it from here as well.

90
00:06:38,110 --> 00:06:42,250
‫So let's go ahead and delete setup player input component from Base Pond.

91
00:06:42,460 --> 00:06:46,540
‫CP And now it's no longer in the base pond class.

92
00:06:46,540 --> 00:06:52,120
‫So let's go ahead and save our changes and close base Pond H and CP.

93
00:06:52,150 --> 00:06:59,110
‫And now we have setup player input component declared in Tank H, but we also want to define it and

94
00:06:59,110 --> 00:06:59,410
‫tank.

95
00:06:59,620 --> 00:07:01,540
‫CP So here in Tank.

96
00:07:01,720 --> 00:07:06,340
‫CP I'm going to add the definition just above the move function.

97
00:07:06,430 --> 00:07:12,880
‫So this is void and it's a tank set up player input component.

98
00:07:13,510 --> 00:07:18,000
‫Now let's go back to Tank H and see what its input parameter type is.

99
00:07:18,010 --> 00:07:21,880
‫You'll see that it's forward declared here inside the parentheses.

100
00:07:21,880 --> 00:07:27,070
‫This is something you can do if you want to forward, declare a class type in a header file.

101
00:07:27,070 --> 00:07:33,370
‫So it's forward declared here and we need this you input component pointer type and the parameter is

102
00:07:33,370 --> 00:07:34,990
‫called player input component.

103
00:07:34,990 --> 00:07:37,450
‫So we need this input parameter in tank.

104
00:07:37,600 --> 00:07:44,980
‫CP So in the parentheses for setup player input component, we're going to have a U input component

105
00:07:45,040 --> 00:07:50,080
‫that's a pointer and it's called player input component.

106
00:07:50,320 --> 00:07:55,300
‫So now the function signature matches that in the function declaration.

107
00:07:55,450 --> 00:08:02,050
‫Now back in the CP file, let's give this function a function body and we're overwriting this function

108
00:08:02,050 --> 00:08:07,450
‫and it's a good idea to call super set up player input component.

109
00:08:07,480 --> 00:08:13,030
‫Now, since we're calling the parent version of setup player input component, we have to pass in an

110
00:08:13,030 --> 00:08:15,460
‫input of type you input component.

111
00:08:15,460 --> 00:08:19,900
‫We're going to pass in the input parameter to this function here.

112
00:08:19,900 --> 00:08:23,430
‫So this way the parent class will call its version.

113
00:08:23,440 --> 00:08:26,620
‫Now the base pond tank is not implementing this function.

114
00:08:26,620 --> 00:08:27,700
‫We just removed it.

115
00:08:27,700 --> 00:08:31,930
‫But the parent class to base -- will call its version.

116
00:08:31,930 --> 00:08:38,410
‫And whenever you override a virtual function like this, calling the super version is a good idea.

117
00:08:38,410 --> 00:08:43,090
‫So we don't miss any functionality implemented in the parent version.

118
00:08:43,090 --> 00:08:44,440
‫So why are we doing this?

119
00:08:44,470 --> 00:08:47,150
‫What is setup player input component good for?

120
00:08:47,170 --> 00:08:51,730
‫Well, one of the things it's good for is binding functions to access mappings.

121
00:08:51,730 --> 00:08:56,140
‫We'd like to bind our move function to the move forward axis mapping.

122
00:08:56,140 --> 00:08:57,250
‫And we do that here.

123
00:08:57,250 --> 00:09:01,180
‫We do that using this input parameter player input component.

124
00:09:01,180 --> 00:09:04,360
‫That's what this object is designed for.

125
00:09:04,390 --> 00:09:12,160
‫We take the player input component and on this pointer we use the arrow operator to access a function

126
00:09:12,160 --> 00:09:14,110
‫called bind axis.

127
00:09:14,590 --> 00:09:17,890
‫Now Bind Axis takes a few input parameters.

128
00:09:17,890 --> 00:09:22,450
‫The first is a string literal, which means we're going to use the text macro.

129
00:09:22,600 --> 00:09:24,430
‫Now what do we put in the quotes?

130
00:09:24,520 --> 00:09:27,160
‫We put the name of the axis mapping.

131
00:09:27,160 --> 00:09:31,690
‫We saw in the editor that this axis mapping is called move forward.

132
00:09:32,020 --> 00:09:36,970
‫So we're choosing that axis mapping to bind to the second input parameter.

133
00:09:36,970 --> 00:09:43,690
‫This is going to be a pointer to the object where binding the function for this is a pointer to the

134
00:09:43,690 --> 00:09:50,590
‫instance of the particular class where n and since we're in the tank class, this will point to the

135
00:09:50,590 --> 00:09:53,280
‫instance of the tank pawn in the game.

136
00:09:53,290 --> 00:09:58,120
‫Now the third parameter is the address of the function we're binding.

137
00:09:58,120 --> 00:10:01,720
‫So we have a tank move.

138
00:10:01,750 --> 00:10:03,550
‫Very important that we need to fully.

139
00:10:03,660 --> 00:10:06,900
‫Qualify the function name with the name of the class.

140
00:10:06,900 --> 00:10:13,200
‫And right here in front of the function name, we need the address of operator.

141
00:10:13,230 --> 00:10:18,450
‫Now, if you're not familiar with doing something like this, this is simply taking the address of a

142
00:10:18,450 --> 00:10:19,220
‫function.

143
00:10:19,230 --> 00:10:23,040
‫Functions can have addresses just like variables can.

144
00:10:23,040 --> 00:10:28,320
‫So using the address of operator is a way to pass functions into other functions.

145
00:10:28,320 --> 00:10:31,380
‫So that's why we need that address of operator.

146
00:10:31,380 --> 00:10:34,050
‫So we have our function call to bind access.

147
00:10:34,200 --> 00:10:40,650
‫Now you're probably noticing the IntelliSense error pointer to incomplete class type you input component

148
00:10:40,650 --> 00:10:41,700
‫is not allowed.

149
00:10:41,850 --> 00:10:43,710
‫Now we know what can cause this.

150
00:10:43,710 --> 00:10:46,950
‫For one, it could mean that we need to include a header file.

151
00:10:47,220 --> 00:10:50,430
‫Another possibility is that it's a false error.

152
00:10:50,430 --> 00:10:55,110
‫You can easily find out by compiling, so let's attempt to compile.

153
00:10:55,440 --> 00:10:57,600
‫We'll see that we have a successful compile.

154
00:10:57,600 --> 00:10:59,640
‫So we know this is a false error.

155
00:10:59,640 --> 00:11:04,290
‫But again, if you want, you can add the include just to remove that.

156
00:11:04,290 --> 00:11:05,790
‫So it's not bothering you.

157
00:11:05,820 --> 00:11:10,890
‫Now we know that the class type that it's complaining about is you input component.

158
00:11:11,280 --> 00:11:16,290
‫So here's you input component in the documentation and here's the include.

159
00:11:16,290 --> 00:11:23,100
‫And if we add this up here at the top of the tank CP file, we'll get rid of that pesky false error.

160
00:11:23,100 --> 00:11:29,280
‫And again, because these have the pragya wants include guards, we know that input components is not

161
00:11:29,280 --> 00:11:34,080
‫going to be included more than once and there go the squiggles they're gone.

162
00:11:34,350 --> 00:11:39,900
‫So now we know this move function will be called every frame and value will have a particular float

163
00:11:39,900 --> 00:11:44,280
‫value depending on whether we're pressing the W or asks.

164
00:11:44,670 --> 00:11:50,490
‫Now, simply knowing that the move function is bound to move forward is not quite enough.

165
00:11:50,490 --> 00:11:54,750
‫As developers, it's nice to have some sort of confirmation that things are working.

166
00:11:54,750 --> 00:12:01,110
‫So what I'd like you to do as your challenge is to use YUI log in the MOV function to print the value

167
00:12:01,110 --> 00:12:04,950
‫that's being passed into move that float called value.

168
00:12:04,980 --> 00:12:13,110
‫So use percent f in uiy log to log the value of the float value to the output log and then play test

169
00:12:13,110 --> 00:12:17,020
‫the game and press those keys and see what you get printed out to the log.

170
00:12:17,040 --> 00:12:20,370
‫Pause the video and add this to the move function now.

171
00:12:23,280 --> 00:12:23,590
‫Okay.

172
00:12:23,610 --> 00:12:27,960
‫So here in the mov function, i'm going to add a uii log.

173
00:12:30,200 --> 00:12:33,680
‫And this can be log temp warning.

174
00:12:33,770 --> 00:12:35,960
‫And for the text macro.

175
00:12:36,230 --> 00:12:42,440
‫I'm simply going to put value percent F and value.

176
00:12:42,710 --> 00:12:43,520
‫Now that's okay.

177
00:12:43,520 --> 00:12:48,500
‫If you used a different verbosity or warning type, if you know how to do those things.

178
00:12:48,950 --> 00:12:49,960
‫That's totally fine.

179
00:12:49,970 --> 00:12:56,090
‫I'm just going to use a warning here and I know you've used things like percent se and formatted your

180
00:12:56,090 --> 00:12:58,100
‫log with a string value.

181
00:12:58,130 --> 00:13:04,300
‫Percent F, if you're not aware, is how you can format your UI log with a float value.

182
00:13:04,310 --> 00:13:12,380
‫So let's compile this and back in the editor, I'm going to open up the output log and press play and

183
00:13:12,380 --> 00:13:16,190
‫check it out where spamming the output log with countless messages.

184
00:13:16,190 --> 00:13:19,000
‫Now I'm going to click in the viewport and press the W key.

185
00:13:19,010 --> 00:13:22,030
‫There's my value of one I'm going to release.

186
00:13:22,040 --> 00:13:23,180
‫It's back to zero.

187
00:13:23,210 --> 00:13:26,570
‫I'm going to press the key and it's negative one.

188
00:13:26,570 --> 00:13:30,500
‫And if we press both at the same time, we get zero.

189
00:13:30,500 --> 00:13:33,620
‫And so it's exactly as we expected.

190
00:13:33,800 --> 00:13:34,650
‫Perfect.

191
00:13:34,670 --> 00:13:35,390
‫All right.

192
00:13:35,390 --> 00:13:39,320
‫So in this video, we've set up our pond to handle some user input.

193
00:13:39,560 --> 00:13:46,180
‫We talked about access mappings and we bound our move function to the move forward access mapping.

194
00:13:46,190 --> 00:13:53,300
‫We then printed that access value using YUI log in our MOVE function, but we'd actually like to move

195
00:13:53,300 --> 00:13:57,130
‫our tank rather than just print some values to the output log.

196
00:13:57,140 --> 00:14:02,720
‫So in the lectures to come, we're going to set it up so that we can actually start moving our tank.

197
00:14:03,290 --> 00:14:04,310
‫I'll see you soon.

