1 00:00:24.725 --> 00:00:27.325 Hello, my name is Lee Young hoon 2 00:00:27.325 --> 00:00:29.525 The process of making a TPS game 3 00:00:29.525 --> 00:00:34.075 Typically progresses in the order of prototype, alpha, and beta stages 4 00:00:34.375 --> 00:00:38.580 In C based TPS game development 5 00:00:38.580 --> 00:00:40.880 Understanding design techniques 6 00:00:40.880 --> 00:00:43.919 Using finite state machines is essential for controlling AI 7 00:00:43.919 --> 00:00:47.025 While exploring systems like the skeletal mesh animation system 8 00:00:47.325 --> 00:00:51.425 And navigation system 9 00:00:51.425 --> 00:00:54.425 Which are key components of the Unreal Engine 10 00:00:54.425 --> 00:00:56.725 Therefore, in this chapter/section 11 00:00:56.725 --> 00:01:03.119 In this chapter, we will learn how to create a C based project 12 00:01:03.119 --> 00:01:08.175 Generate a TPS player, and apply a third-person camera and appearance 13 00:01:08.175 --> 00:01:11.325 Furthermore, we will also gain understanding of the character class 14 00:01:11.325 --> 00:01:14.825 And learn about rotation and movement 15 00:01:14.825 --> 00:01:17.125 Using the Character Movement Component 16 00:01:17.125 --> 00:01:20.475 First, let's create a TPS project 17 00:01:20.475 --> 00:01:23.275 And apply the player's appearance 18 00:01:23.275 --> 00:01:27.275 Creating a C based project and generate a TPS player 19 00:01:27.879 --> 00:01:31.080 Let's look at a C based TPS example 20 00:01:31.080 --> 00:01:34.300 First, let me explain what TPS is 21 00:01:34.300 --> 00:01:38.850 There is FPS and TPS 22 00:01:40.199 --> 00:01:48.925 FPS stands for First Person Shooter. 23 00:01:48.925 --> 00:01:54.025 And TPS stands for Third Person Shooter. 24 00:01:54.575 --> 00:01:56.675 So, FPS games are in first person perspective 25 00:01:56.675 --> 00:01:58.975 This one is in third person perspective 26 00:01:58.975 --> 00:02:01.575 Usually, if the screen shows like this 27 00:02:01.575 --> 00:02:06.075 (If the character's hands are only shown, it's first person perspective) With just hands appearing here then this would be called FPS 28 00:02:06.075 --> 00:02:10.525 Next, you can slightly see the full body 29 00:02:10.525 --> 00:02:14.000 If you can see the character's back, then this would be considered third person perspective 30 00:02:14.000 --> 00:02:16.700 This one is third person 31 00:02:16.700 --> 00:02:18.125 So, this example 32 00:02:18.125 --> 00:02:21.675 Let's go ahead and try a Third Person Shooter example like this 33 00:02:23.399 --> 00:02:26.080 Then, first, we need to create the project 34 00:02:26.080 --> 00:02:28.880 Open the Unreal Project Browser 35 00:02:28.880 --> 00:02:32.660 Next, select the Blank template for the game 36 00:02:32.660 --> 00:02:36.270 And here, let's proceed with C for the project 37 00:02:36.724 --> 00:02:41.839 Since the name is Cpp, let's use Cpp as a prefix 38 00:02:41.839 --> 00:02:43.839 Let's name it TPS then 39 00:02:59.279 --> 00:03:01.229 Once the project is created, we can start 40 00:03:01.229 --> 00:03:03.160 By doing the first tasks we need to do 41 00:03:03.160 --> 00:03:08.600 First, I'll change the layout to the form I prefer 42 00:03:08.600 --> 00:03:13.974 And then, I'll create a new level first 43 00:03:13.974 --> 00:03:17.080 Click New Level from this File category 44 00:03:17.080 --> 00:03:21.080 Since this is a TPS, we'll need a ground or floor 45 00:03:21.080 --> 00:03:25.630 So, let's start with Basic this time and click create 46 00:03:29.770 --> 00:03:34.170 And now we need to create the game mode and the protagonist here 47 00:03:35.240 --> 00:03:39.374 Let's proceed with creating these in C 48 00:03:39.374 --> 00:03:42.520 First, let's create the game mode 49 00:03:42.520 --> 00:03:46.070 Click like this 50 00:03:47.199 --> 00:03:52.880 Since this is a TPS, let's prefix it with TPS for the game mode name 51 00:03:52.880 --> 00:03:56.230 Click on Public and then click Create 52 00:04:02.224 --> 00:04:06.720 Then you should see it created like this 53 00:04:06.720 --> 00:04:08.870 Here, if you load it 54 00:04:17.399 --> 00:04:20.559 You can confirm that the files have been created successfully 55 00:04:20.559 --> 00:04:24.000 And now, let's create the main character as well 56 00:04:24.000 --> 00:04:29.224 Find Add C Class from tools 57 00:04:29.224 --> 00:04:32.359 Now, we'll create the character. 58 00:04:32.359 --> 00:04:35.959 You can choose from Actor, Pawn and Character 59 00:04:35.959 --> 00:04:37.600 Actor inherits from Pawn 60 00:04:37.600 --> 00:04:40.720 And Pawn is inherited by Character 61 00:04:40.720 --> 00:04:44.160 Choose character and press Next 62 00:04:44.160 --> 00:04:49.600 This one is the protagonist, so I'll put Player 63 00:04:49.600 --> 00:04:52.450 This is too lengthy, let's just say player 64 00:04:54.880 --> 00:04:58.219 Turns out you cannot use the name player 65 00:04:59.674 --> 00:05:05.774 I will name it TPS player and then press create 66 00:05:13.920 --> 00:05:16.000 Now that we have a new character 67 00:05:16.000 --> 00:05:20.079 I'll proceed to create a blueprint that inherits from this structure 68 00:05:20.079 --> 00:05:23.799 Like so, create a group for blue print class 69 00:05:23.799 --> 00:05:29.720 Then we need a folder, I will make one up here 70 00:05:29.720 --> 00:05:32.024 Right now, it's not working 71 00:05:32.024 --> 00:05:35.839 Hold on, let's create the folder before proceeding 72 00:05:35.839 --> 00:05:39.440 Go to contents and click New Folder 73 00:05:40.440 --> 00:05:43.490 I will name it, Blueprint 74 00:05:45.160 --> 00:05:48.480 And also, we have to save the current level 75 00:05:48.480 --> 00:05:53.624 I will also create Maps folder 76 00:05:53.624 --> 00:05:55.874 Save everything 77 00:05:55.874 --> 00:06:04.074 Come back again, create the main character with prefix BP, under bar 78 00:06:07.519 --> 00:06:10.079 And then create a game mode also 79 00:06:10.079 --> 00:06:12.559 We have been through this process once 80 00:06:12.559 --> 00:06:15.224 We will keep going 81 00:06:16.824 --> 00:06:20.874 Make the game mode as blue print as well 82 00:06:21.399 --> 00:06:24.119 And then save the current level as well 83 00:06:24.119 --> 00:06:29.619 Press Ctrl and S, save it in maps folder and name it game map 84 00:06:32.789 --> 00:06:36.039 We've created everything so, save everything 85 00:06:37.079 --> 00:06:42.119 And then we have to select these in Project Settings 86 00:06:42.119 --> 00:06:46.399 Go to Maps and Modes find Default Maps 87 00:06:46.399 --> 00:06:50.119 Add in the game map for everything 88 00:06:50.119 --> 00:06:53.569 Also, I will not change anything for Default Modes 89 00:06:59.924 --> 00:07:04.640 Let's distribute on World setting of the level 90 00:07:04.640 --> 00:07:06.490 You can also drag it and drop 91 00:07:09.399 --> 00:07:14.159 Here, switch the default Pawn with this one 92 00:07:14.959 --> 00:07:18.040 If you revise it here, also needs to save again 93 00:07:18.040 --> 00:07:21.679 Compile this and save again 94 00:07:21.679 --> 00:07:24.224 We will be keep using this 95 00:07:24.224 --> 00:07:28.920 Go to Save on compile set it to Always 96 00:07:28.920 --> 00:07:32.519 Do another saving entire file 97 00:07:32.519 --> 00:07:37.459 Now then, our main character will spawn here 98 00:07:38.224 --> 00:07:42.720 In this level, we initially have the Player Start 99 00:07:42.720 --> 00:07:44.760 I think the character will spawn here 100 00:07:44.760 --> 00:07:49.960 Now, we double click and change the appearance 101 00:07:50.760 --> 00:07:53.673 However, since we created it as Blank in the first place 102 00:07:53.673 --> 00:07:58.073 We have nothing that's why we go here 103 00:07:58.073 --> 00:08:05.920 I brought data from basic template for the appearance 104 00:08:05.920 --> 00:08:09.523 Go click the add button and go to the upper part 105 00:08:09.523 --> 00:08:13.373 There is Add Feature if you click this 106 00:08:13.373 --> 00:08:15.600 You can bring in existing content if needed 107 00:08:15.600 --> 00:08:19.399 Here, since we're going to use Third Person perspective 108 00:08:19.399 --> 00:08:22.640 Select and click Add to Project 109 00:08:22.640 --> 00:08:27.073 I will bring blueprint and we can use it 110 00:08:27.073 --> 00:08:30.160 To set C , everything comes together 111 00:08:30.160 --> 00:08:32.119 I will use this to import 112 00:08:35.919 --> 00:08:38.119 Now we can see that it's been copied 113 00:08:38.119 --> 00:08:40.629 Now you can close this window 114 00:08:41.873 --> 00:08:46.723 Now this BP Third Person 115 00:08:46.723 --> 00:08:49.280 It's been automatically added 116 00:08:49.280 --> 00:08:51.679 We will not use this 117 00:08:51.679 --> 00:08:53.359 Since we will use what we made 118 00:08:53.359 --> 00:08:55.719 Let's go back to Blueprint Folder 119 00:08:55.719 --> 00:08:59.373 Here, double click on BP_TPS Player 120 00:08:59.373 --> 00:09:01.719 We will set it here 121 00:09:01.719 --> 00:09:06.159 Here, if you inherit the Character 122 00:09:06.159 --> 00:09:09.960 Here, if you inherit from Character 123 00:09:09.960 --> 00:09:13.000 By default, this character has these four components attached 124 00:09:13.000 --> 00:09:16.280 So, this capsule shape serves as the collision component 125 00:09:16.280 --> 00:09:19.323 And there's an Arrow component 126 00:09:19.323 --> 00:09:22.223 That indicates the front direction 127 00:09:22.223 --> 00:09:24.520 Followed by the Skeletal Mesh Component 128 00:09:24.520 --> 00:09:27.840 So, here you would place a mesh 129 00:09:27.840 --> 00:09:31.673 That has a skeleton, and finally 130 00:09:31.673 --> 00:09:35.123 The component is called Character Movement 131 00:09:35.123 --> 00:09:42.359 It's a component used to control the movement of the character during gameplay 132 00:09:42.359 --> 00:09:47.073 So, if you look at it, we see walking, falling and jumping 133 00:09:47.073 --> 00:09:49.440 These functionalities are already implemented 134 00:09:49.440 --> 00:09:51.880 So, let's use these components 135 00:09:51.880 --> 00:09:56.359 We will first, jumping, actions like such 136 00:09:56.359 --> 00:09:59.840 First, let's set up the appearance 137 00:09:59.840 --> 00:10:02.240 Select the Mesh, and then 138 00:10:03.320 --> 00:10:08.039 If you go to Detail, There is a category called mesh 139 00:10:08.039 --> 00:10:11.423 Here, the Skeletal Mesh Asset is currently set to None 140 00:10:11.423 --> 00:10:18.960 If you expand this, you'll see a human-shaped mesh here 141 00:10:18.960 --> 00:10:21.560 Here, what we will use 142 00:10:23.673 --> 00:10:24.919 Is Quinn 143 00:10:24.919 --> 00:10:29.273 Let's use SKM Quinn 144 00:10:29.273 --> 00:10:35.599 Then by inserting this, you establish the pivot point of this character 145 00:10:35.599 --> 00:10:39.159 The origin or pivot point of this character would be at the center bottom 146 00:10:39.159 --> 00:10:40.520 Just like so 147 00:10:40.520 --> 00:10:43.640 We need to lower this a bit and rotate it as well 148 00:10:43.640 --> 00:10:47.090 Since it's currently facing right, therefore 149 00:10:48.039 --> 00:10:52.573 In the Mesh section, at the top, there's a Transform option where 150 00:10:52.573 --> 00:10:56.400 Z-axis down to -90 degrees. The reason for 90 degrees 151 00:10:56.400 --> 00:10:59.440 Typically, models like this are 152 00:10:59.440 --> 00:11:01.520 Standardized with a height of 180 cm 153 00:11:01.520 --> 00:11:05.880 So, if you move it down by 90 cm from the center 154 00:11:05.880 --> 00:11:07.599 It will fit perfectly here 155 00:11:07.599 --> 00:11:12.359 And then we'll rotate it like this along the Z axis 156 00:11:12.873 --> 00:11:15.719 Since clockwise direction increases 157 00:11:15.719 --> 00:11:17.479 Since we'll rotate it in the opposite direction 158 00:11:17.479 --> 00:11:19.479 We'll rotate it counterclockwise by 90 degrees 159 00:11:19.479 --> 00:11:23.573 Here, you can rotate it by -90 degrees like this 160 00:11:23.960 --> 00:11:28.460 This way, you can set it up to face forward 161 00:11:33.573 --> 00:11:39.209 So, if you set it up like this, the camera will 162 00:11:40.523 --> 00:11:43.719 Actually go behind the protagonist character 163 00:11:43.719 --> 00:11:46.923 In 2D shooting games, we typically place the camera 164 00:11:46.923 --> 00:11:49.923 Like this in the level for use 165 00:11:49.923 --> 00:11:54.599 In the case of TPS, the camera needs to follow the protagonist 166 00:11:54.599 --> 00:11:57.159 So, we place the camera here 167 00:11:57.159 --> 00:12:01.799 Click on the Add button here, and let's name it Camera 168 00:12:01.799 --> 00:12:03.440 Now we have the camera here 169 00:12:03.440 --> 00:12:06.190 Place the camera like this for positioning 170 00:12:08.973 --> 00:12:13.440 First, set it up in Blueprint, then you can work on it in C 171 00:12:13.440 --> 00:12:16.320 Placing the camera at eye level like this 172 00:12:16.320 --> 00:12:20.599 Would make it a first-person perspective 173 00:12:20.599 --> 00:12:23.919 Let's save it here and try running it once 174 00:12:23.919 --> 00:12:25.719 Then this happens 175 00:12:27.919 --> 00:12:31.673 If you press F8, it changes the camera perspective to view the surroundings 176 00:12:31.673 --> 00:12:34.200 You can see the player standing like this 177 00:12:34.200 --> 00:12:37.323 And since the camera is positioned at eye level 178 00:12:37.323 --> 00:12:39.520 Pressing F8 again will return to the previous view 179 00:12:39.520 --> 00:12:41.920 That's how it's set up 180 00:12:45.173 --> 00:12:49.173 Setting up the third-person camera and applying the character model 181 00:12:49.173 --> 00:12:52.973 Next, let's configure the third person camera 182 00:12:54.080 --> 00:12:57.239 But you can just add the camera by itself 183 00:12:57.239 --> 00:13:00.622 However, there might be an issue if you only add the camera because currently 184 00:13:00.622 --> 00:13:04.822 It's set up for FPS, so I'll move it back like this 185 00:13:04.822 --> 00:13:08.622 If you set it up like this, you should be able to see the back of the character 186 00:13:09.679 --> 00:13:12.559 So, in this setup, you wouldn't see the front view properly 187 00:13:12.559 --> 00:13:18.359 In TPS games, some have the camera positioned directly behind the character 188 00:13:18.359 --> 00:13:21.400 While others adopt a slightly angled side view perspective 189 00:13:21.400 --> 00:13:24.200 Handling those variations can be 190 00:13:24.200 --> 00:13:27.840 A bit challenging with just one camera setup 191 00:13:27.840 --> 00:13:34.022 So, I'm going to add something 192 00:13:34.022 --> 00:13:36.239 Called a Spring Arm as the parent of this camera 193 00:13:36.239 --> 00:13:40.080 So, I'll use that to adjust the position 194 00:13:40.080 --> 00:13:43.679 And one interesting feature of the Spring Arm is that 195 00:13:43.679 --> 00:13:47.479 Sure, would you like to see an illustration? 196 00:13:52.072 --> 00:13:55.000 In this case, there's a player positioned like this 197 00:13:55.000 --> 00:13:57.159 And the camera is looking like this. 198 00:13:57.159 --> 00:14:01.522 So, there could be a wall positioned like this in between 199 00:14:01.522 --> 00:14:03.640 Then if you look like this, you'd see the wall 200 00:14:03.640 --> 00:14:06.722 Which could be problematic in situations like this 201 00:14:06.722 --> 00:14:08.872 When we add a Spring Arm, which is a component 202 00:14:12.440 --> 00:14:16.822 Designed to envelop the camera 203 00:14:16.822 --> 00:14:20.022 Using the Spring Arm, the camera's position can automatically adjust to move away from the wall and stay positioned correctly on this side 204 00:14:20.022 --> 00:14:23.000 It adjusts to face in this direction 205 00:14:23.000 --> 00:14:25.479 So, that's why we use such features 206 00:14:26.522 --> 00:14:29.719 Let's go ahead and attach the component here and see how it works 207 00:14:29.719 --> 00:14:32.822 Select the Capsule component, click on the Add button 208 00:14:32.822 --> 00:14:36.479 And then I'll name it Spring here 209 00:14:36.479 --> 00:14:40.320 Then the Spring Arm option will appear like this; click on it 210 00:14:40.320 --> 00:14:43.159 Next, I'll place the camera here like this 211 00:14:43.159 --> 00:14:45.559 We'll maintain this hierarchy structure, and with this setup 212 00:14:45.559 --> 00:14:48.080 the camera will be pushed back 213 00:14:48.080 --> 00:14:51.400 Let's reset the camera back to its original position first 214 00:14:51.400 --> 00:14:56.520 And as you can see, the Spring Arm is set up like this 215 00:14:56.520 --> 00:15:00.222 So, I'll raise it up a bit like this 216 00:15:00.222 --> 00:15:02.599 I'm not adjusting the camera directly 217 00:15:02.599 --> 00:15:04.599 I'm moving the Spring Arm instead 218 00:15:04.599 --> 00:15:08.199 I'll push the Spring Arm slightly to the right 219 00:15:08.872 --> 00:15:19.922 Push the Spring Arm to the right When viewed from behind 220 00:15:20.200 --> 00:15:22.119 Let's go around like 40 or 70 221 00:15:22.119 --> 00:15:26.419 If we do this, it should look like this 222 00:15:28.622 --> 00:15:30.340 We can push it a bit further if needed 223 00:15:34.322 --> 00:15:36.871 And if you look at the Spring Arm 224 00:15:36.871 --> 00:15:39.280 Even though we didn't push the camera back separately 225 00:15:39.280 --> 00:15:40.479 The camera is positioned backward 226 00:15:40.479 --> 00:15:43.840 In the properties of the Spring Arm 227 00:15:43.840 --> 00:15:47.000 You'll find something called "Target Arm Length" under the camera section 228 00:15:47.000 --> 00:15:48.599 That's because it's set to 300 229 00:15:48.599 --> 00:15:51.080 If you reduce this to 200 or something like that 230 00:15:51.080 --> 00:15:52.721 You'll see it get closer 231 00:15:52.721 --> 00:15:56.371 And if you set it to 0, it will be right in front 232 00:15:56.371 --> 00:15:59.021 So, I'll set this to 200 233 00:16:00.119 --> 00:16:05.119 And now, let's run it once to see how it looks 234 00:16:05.119 --> 00:16:10.320 Let's proceed to implement this part in C 235 00:16:10.320 --> 00:16:19.350 Let's navigate to the player's header file in this direction 236 00:16:23.640 --> 00:16:26.000 Then we'll find the content we just added there 237 00:16:26.000 --> 00:16:30.159 Here, we've added the Spring Arm and Camera components 238 00:16:30.159 --> 00:16:34.872 And we've specified the Mesh asset for this mesh 239 00:16:34.872 --> 00:16:38.479 I'll write the code for this task 240 00:16:38.479 --> 00:16:49.039 First, let's go to the header file and add the Camera and Spring Arm components 241 00:16:49.039 --> 00:16:52.960 And then I attached the camera to the Spring Arm 242 00:16:52.960 --> 00:16:55.000 Then let's create this first 243 00:16:55.000 --> 00:17:05.472 Write the code for a camera and a spring arm UPROPERTY(EditAnywhere) 244 00:17:05.472 --> 00:17:19.680 Write class USpringArmComponent 245 00:17:20.359 --> 00:17:26.520 I will write springArm for this 246 00:17:26.520 --> 00:17:29.072 And copy the whole thing 247 00:17:29.072 --> 00:17:40.572 Writing the camera cod We need to make a camera too, UCameraComponent 248 00:17:40.572 --> 00:17:43.669 I will call this Cam 249 00:17:48.522 --> 00:17:50.640 I will add this since it's a component 250 00:17:50.640 --> 00:17:57.589 CamComp, SpringArmComp like so 251 00:18:02.199 --> 00:18:04.239 I will create this now 252 00:18:04.239 --> 00:18:12.439 Come to the creator, let's first create the spring arm component 253 00:18:12.439 --> 00:18:14.989 CreateDefaultSubobject 254 00:18:27.800 --> 00:18:29.079 Like so 255 00:18:29.079 --> 00:18:32.800 Put USpringArmComponent for this 256 00:18:32.800 --> 00:18:37.319 I will name it TEXT, always make sure to name your code 257 00:18:37.319 --> 00:18:39.419 Let's just use the same name 258 00:18:42.071 --> 00:18:44.680 This should be attached to the root, right? 259 00:18:44.680 --> 00:18:48.329 For this one, I will use attach 260 00:18:52.271 --> 00:18:59.920 I will add it to SetupAttachment(RootComponent) 261 00:18:59.920 --> 00:19:08.119 And we need to add a header to this, like this 262 00:19:08.119 --> 00:19:11.371 Let's proceed to add the header like this 263 00:19:11.371 --> 00:19:13.971 This has GameFramework 264 00:19:17.880 --> 00:19:19.439 We will need to create a camera as well, right? 265 00:19:19.439 --> 00:19:22.439 Write CamComp = CreateDefaultSubobject 266 00:19:22.439 --> 00:19:26.989 And then UCameraComponent and TEXT here too 267 00:19:31.221 --> 00:19:33.221 I will name this CamComp 268 00:19:37.199 --> 00:19:40.520 I will attach this one to the springArm 269 00:19:40.520 --> 00:19:45.239 Now write SetupAttachment 270 00:19:45.239 --> 00:19:48.489 I will attach this to SpringArmComp 271 00:19:49.560 --> 00:19:54.599 Include the header to this as well 272 00:19:54.599 --> 00:19:59.549 This seems like it should be a Camera/CameraComponent as well 273 00:20:01.880 --> 00:20:04.880 Just like so, finish coding 274 00:20:06.571 --> 00:20:14.071 The third step is to incorporate the input for the Mesh into the actual code 275 00:20:14.071 --> 00:20:17.000 We will use the assets we've put in here 276 00:20:17.000 --> 00:20:20.119 There are two buttons you can see 277 00:20:20.119 --> 00:20:23.199 This means I will put in what I have chosen 278 00:20:23.199 --> 00:20:26.640 This means going to the folder of this asset 279 00:20:26.640 --> 00:20:30.171 If you click on this folder, it will navigate like this 280 00:20:30.171 --> 00:20:33.571 You can see that we are currently using the Skeletal Mesh you are viewing 281 00:20:33.571 --> 00:20:37.680 Right click here and select Copy Reference 282 00:20:37.680 --> 00:20:42.271 Next, when you paste this content into Notepad 283 00:20:42.271 --> 00:20:45.959 It appears as a string like this 284 00:20:45.959 --> 00:20:49.280 You can use this string to perform loading 285 00:20:49.280 --> 00:20:52.479 This is actually the path to the asset 286 00:20:52.479 --> 00:20:56.160 The actual relative path to the asset 287 00:20:56.160 --> 00:20:59.410 So, let's use this to fill 288 00:21:01.599 --> 00:21:03.319 In the values for the Mesh 289 00:21:03.319 --> 00:21:07.571 There is a class called ConstructorHelpers 290 00:21:07.571 --> 00:21:14.119 Here, you'll find template structs named FClassFinder and FObjectFinder 291 00:21:14.521 --> 00:21:16.439 So, with these 292 00:21:18.671 --> 00:21:22.760 The classes are used to load Blueprint classes 293 00:21:22.760 --> 00:21:26.560 Since we're going to load assets, we'll use ObjectFinder 294 00:21:28.071 --> 00:21:31.621 After writing it like this, we'll add angle brackets here 295 00:21:31.621 --> 00:21:34.371 Because it's a template 296 00:21:34.371 --> 00:21:37.560 We use angle brackets to specify the data type 297 00:21:37.560 --> 00:21:39.680 You're not sure yet about the exact data type you'll use right? 298 00:21:39.680 --> 00:21:41.719 For now, let's write it like this 299 00:21:41.719 --> 00:21:47.640 Then, shall we call it TempMesh for now? 300 00:21:47.640 --> 00:21:51.359 Since we're loading a Mesh, let's proceed like this 301 00:21:51.359 --> 00:21:53.000 And enclose it in parentheses to create it 302 00:21:53.000 --> 00:21:56.369 Here, where the string goes, you use TEXT 303 00:21:58.640 --> 00:22:02.000 This one here is data type, then the variable name 304 00:22:02.000 --> 00:22:04.071 This part becomes where you pass arguments 305 00:22:04.071 --> 00:22:08.371 When you call the constructor function 306 00:22:08.371 --> 00:22:13.771 So, here we paste what we mentioned earlier 307 00:22:13.771 --> 00:22:16.160 Into this spot 308 00:22:16.160 --> 00:22:18.280 You need to be careful because 309 00:22:18.280 --> 00:22:22.071 Sometimes when you paste it directly 310 00:22:22.071 --> 00:22:25.521 There might be spacing issues 311 00:22:25.521 --> 00:22:26.571 You shouldn't do it like this 312 00:22:26.571 --> 00:22:29.921 Don't insert it like that, it should be directly attached without any spaces in between 313 00:22:29.921 --> 00:22:35.839 You should use the copied string exactly as it was copied 314 00:22:35.839 --> 00:22:39.880 If you look here, you can see what data type needs to be inserted 315 00:22:39.880 --> 00:22:41.920 SkeletalMesh is written 316 00:22:41.920 --> 00:22:47.870 So, you write that down, and this starts with U 317 00:22:48.839 --> 00:22:50.359 Now, that will work 318 00:22:50.359 --> 00:22:54.959 you'll need to include it to use this 319 00:22:57.670 --> 00:23:00.670 SkeletalMesh comes after Engine 320 00:23:04.571 --> 00:23:10.371 TempMesh is actually attempting to load internally 321 00:23:10.371 --> 00:23:13.640 It will try to read the file, and if successful 322 00:23:13.640 --> 00:23:17.959 Then you can receive feedback regarding that 323 00:23:17.959 --> 00:23:21.800 Use if and then TempMesh was successful 324 00:23:21.800 --> 00:23:26.170 there is a function named Succeeded, by using this function 325 00:23:28.070 --> 00:23:29.800 You can handle it after checking the feedback 326 00:23:29.800 --> 00:23:32.319 Actually, upon inspecting this function 327 00:23:32.319 --> 00:23:35.640 If the object TempMesh exists 328 00:23:35.640 --> 00:23:39.770 It returns true indicating success 329 00:23:39.770 --> 00:23:42.040 If it's null, it returns false 330 00:23:42.040 --> 00:23:43.839 Just like so 331 00:23:43.839 --> 00:23:48.370 So, since we haven't actually created the Mesh yet 332 00:23:48.370 --> 00:23:50.839 We need to handle that part where we assign it to the Mesh 333 00:23:50.839 --> 00:23:53.959 However, when inheriting from Character 334 00:23:53.959 --> 00:23:57.040 Mesh is typically present by default 335 00:23:57.040 --> 00:23:59.160 So, we can just retrieve it from there 336 00:23:59.970 --> 00:24:05.220 You can use the function GetMesh to retrieve it 337 00:24:05.220 --> 00:24:10.870 We can retrieve the Mesh that exists within the Character 338 00:24:13.040 --> 00:24:14.520 Then, after retrieving the Mesh 339 00:24:14.520 --> 00:24:21.470 We can simply call SetSkeletalMesh here 340 00:24:22.400 --> 00:24:25.319 Here, it instructs to insert a new Mesh 341 00:24:25.319 --> 00:24:33.970 This is precisely the Object that was in TempMesh earlier 342 00:24:33.970 --> 00:24:36.760 Right now, after loading 343 00:24:36.760 --> 00:24:40.370 This variable Object contains 344 00:24:40.370 --> 00:24:44.420 An object of type USkeletalMesh 345 00:24:46.520 --> 00:24:50.020 This way, we can proceed with loading 346 00:24:51.199 --> 00:24:56.040 And once we complete this, it means the loading has been done 347 00:24:56.040 --> 00:24:59.359 Now we need to include the Transform information as well 348 00:24:59.359 --> 00:25:03.599 So, let's go ahead and set these values 349 00:25:03.599 --> 00:25:08.149 Here, you can see that 350 00:25:12.420 --> 00:25:20.439 There is a SetRelativeLocationAndRotation function in GetMesh 351 00:25:20.439 --> 00:25:23.920 Using this, you can pass in a FVector 352 00:25:23.920 --> 00:25:27.420 Next, you can pass in a FRotator like this 353 00:25:28.719 --> 00:25:33.839 So, here, it was set as 0, 0, -90 earlier 354 00:25:33.839 --> 00:25:37.470 Let me copy this first 355 00:25:37.970 --> 00:25:40.079 Write these as such here 356 00:25:40.079 --> 00:25:43.520 Then, I'll also copy the Rotator below 357 00:25:43.520 --> 00:25:48.120 If we do it like this, it looks like this 358 00:25:48.970 --> 00:25:52.000 But now we have one more thing to learn here 359 00:25:52.000 --> 00:25:56.079 If you look closely, isn't the Rotator X, Y, Z? 360 00:25:56.079 --> 00:25:58.719 In terms of Pitch, Yaw, and Roll? 361 00:25:58.719 --> 00:26:02.560 Have you learned about concepts 362 00:26:02.560 --> 00:26:05.599 Like DirectX or drones in your studies? 363 00:26:05.599 --> 00:26:08.719 In that context, especially in aviation related topics 364 00:26:08.719 --> 00:26:11.319 You often encounter terms like Pitch, Yaw, and Roll 365 00:26:11.319 --> 00:26:14.560 Pitch, Yaw, and Roll are related to axes information 366 00:26:14.560 --> 00:26:16.640 So let's go ahead and add them here 367 00:26:16.640 --> 00:26:20.090 Since this is 0, 0, -90, let's just fill it in as is 368 00:26:24.079 --> 00:26:27.960 Next, let's put it into Rotator. When you look at Rotator 369 00:26:29.000 --> 00:26:34.650 Here as well, it's set up to input in the order of Pitch, Yaw, Roll, Like this 370 00:26:39.429 --> 00:26:42.479 So, since we need to input Pitch, Yaw, and Roll 371 00:26:42.479 --> 00:26:45.560 If you notice, even though we set Z to -90 372 00:26:45.560 --> 00:26:47.119 Yaw is in the middle position 373 00:26:47.119 --> 00:26:55.270 Warning You should input it as 0, -90, 0 like this 374 00:26:55.270 --> 00:26:57.959 So, paying attention to this point 375 00:26:57.959 --> 00:27:00.760 When it comes to Pitch, Yaw, and Roll 376 00:27:00.760 --> 00:27:04.079 They follow the order of axes 377 00:27:04.079 --> 00:27:11.719 If we visualize axes as x, y, z, 378 00:27:27.359 --> 00:27:31.420 Then it should be y, z, x in terms of order 379 00:27:31.420 --> 00:27:34.420 Remember this for correct usage 380 00:27:36.220 --> 00:27:40.479 When inserting values into a Rotator, it's important to note that the order is not x, y, z 381 00:27:40.479 --> 00:27:44.220 It's the order of y, z, x 382 00:27:44.220 --> 00:27:46.000 Remember the order Pitch, Yaw, Roll 383 00:27:46.000 --> 00:27:55.280 Pitch represents nodding up and down, Yaw represents swiveling side to side, and Roll represents tilting from side to side 384 00:27:55.280 --> 00:27:56.020 When rotating 385 00:27:59.160 --> 00:28:04.160 Then, after setting these, since everything is arranged 386 00:28:04.160 --> 00:28:08.070 Let's briefly shut down the Unreal Engine 387 00:28:08.070 --> 00:28:10.170 and then compile again from here 388 00:28:11.319 --> 00:28:14.970 Also, now that I think about it, for something like the spring arm 389 00:28:14.970 --> 00:28:17.719 We need to specify some more settings 390 00:28:17.719 --> 00:28:21.769 How did we set it up earlier? 391 00:28:23.319 --> 00:28:26.839 Here, for the spring arm, we mentioned TargetArmLength as 200 392 00:28:26.839 --> 00:28:29.969 We set it to 200 like this 393 00:28:29.969 --> 00:28:33.789 We set it to 200 like this, and then we also changed the position of the Spring Length 394 00:28:33.789 --> 00:28:37.400 For this, you would use SetRelativeLocation 395 00:28:37.400 --> 00:28:41.950 Was this set to 0 earlier? Did we set it as 40, 70? 396 00:28:43.439 --> 00:28:45.479 We wrote it like this earlier 397 00:28:45.479 --> 00:28:46.879 FVector is missing 398 00:28:51.599 --> 00:28:53.560 We specified it like this earlier 399 00:28:53.560 --> 00:28:56.649 Let's finish this together. Compile it 400 00:29:00.160 --> 00:29:01.610 And proceed 401 00:29:06.669 --> 00:29:09.880 Then let's take a quick look at the protagonist here 402 00:29:09.880 --> 00:29:15.569 If you open the TPS player and look at the viewport, it should look like this 403 00:29:21.669 --> 00:29:23.359 So, apart from what we've created 404 00:29:23.359 --> 00:29:26.359 The one we previously added in the blueprint is still there 405 00:29:26.359 --> 00:29:27.800 Let's delete that 406 00:29:27.800 --> 00:29:31.710 Let's delete the spring arm and camera components 407 00:29:32.769 --> 00:29:35.880 Keep only the components created in C 408 00:29:35.880 --> 00:29:39.880 You'll see that everything we wrote 409 00:29:39.880 --> 00:29:44.040 Has been correctly reflected 410 00:29:44.040 --> 00:29:48.440 After compiling and running it again, it should look like this 411 00:29:54.000 --> 00:29:57.719 Then let's proceed to handle the input 412 00:29:57.719 --> 00:30:00.619 There's something called Enhanced Input 413 00:30:02.049 --> 00:30:06.269 If you look at the Input here, it's set up like this 414 00:30:06.269 --> 00:30:09.760 There's already existing input handling for this 415 00:30:09.760 --> 00:30:11.569 But since we've done it before 416 00:30:11.569 --> 00:30:14.880 This time, let's try handling it using Enhanced Input 417 00:30:14.880 --> 00:30:18.119 In Unreal Engine, if you look at the Third Person example 418 00:30:18.119 --> 00:30:20.519 There's something called Enhanced Input like this 419 00:30:20.519 --> 00:30:25.000 The basic structure involves creating input actions 420 00:30:25.000 --> 00:30:28.599 And then mapping and handling them accordingly 421 00:30:28.599 --> 00:30:32.040 So, we will create a structure like this ourselves 422 00:30:32.040 --> 00:30:37.309 First, let's create a folder. I'll name it Input 423 00:30:39.969 --> 00:30:42.469 And we need to register two actions as well 424 00:30:42.469 --> 00:30:44.769 In Input, you'll find these actions listed under Input Actions 425 00:30:46.019 --> 00:30:49.359 Since these are Input Actions, we'll use the prefix IA 426 00:30:49.359 --> 00:30:54.000 Let's create one called "IA TPSMove 427 00:30:54.000 --> 00:30:57.439 Duplicate it by pressing Ctrl and D to create another one 428 00:30:57.439 --> 00:31:02.589 Let's create this as IA_Jump I'll save it for now 429 00:31:04.919 --> 00:31:08.719 For Jump, it's set to digital, and it's labeled as a bool 430 00:31:08.719 --> 00:31:12.319 It can handle true/false processing 431 00:31:12.319 --> 00:31:14.768 And when you look at Move, it's set like this 432 00:31:14.768 --> 00:31:16.920 I will open this and select Axis 2D 433 00:31:16.920 --> 00:31:20.400 Because Move involves using two axes 434 00:31:20.400 --> 00:31:24.000 So I will specify it as 2D 435 00:31:25.800 --> 00:31:28.418 And right click with the mouse 436 00:31:28.418 --> 00:31:31.719 Then in Input, this time we're going to create a Mapping Context 437 00:31:31.719 --> 00:31:35.669 Create it like this, and since this is for the IMC for player 438 00:31:35.669 --> 00:31:42.069 Set the name as TPS Player 439 00:31:43.680 --> 00:31:45.190 And double-click 440 00:31:46.040 --> 00:31:48.359 So, it's set up like this for mapping 441 00:31:48.359 --> 00:31:51.199 You can add them one by one by clicking the plus sign here 442 00:31:51.199 --> 00:31:54.199 Let's open this up and put in the two things we made 443 00:31:54.199 --> 00:31:59.430 We will put Jump and Move in there 444 00:32:00.680 --> 00:32:03.599 To activate the button corresponding to Jump 445 00:32:03.599 --> 00:32:09.519 We need to handle it by pressing the spacebar 446 00:32:09.519 --> 00:32:15.280 For movement, there should be four directions: W, A, S, D 447 00:32:15.280 --> 00:32:20.280 I'll assign forward and backward movement to X 448 00:32:20.280 --> 00:32:25.789 Because the front and back are along the X-axis, and left and right are along the Y-axis 449 00:32:25.789 --> 00:32:30.560 I will assign forward and backward to the X axis and left and right to the Y axis 450 00:32:30.560 --> 00:32:33.359 Normally, the order is x, y, z 451 00:32:33.359 --> 00:32:36.280 As you can see here in the value type 452 00:32:36.280 --> 00:32:39.040 It's labeled as Axis 2D and set to Vector. 453 00:32:39.040 --> 00:32:42.119 Of course, Vector follows the order of x, y 454 00:32:42.119 --> 00:32:44.319 So, I'll set it up like this 455 00:32:44.319 --> 00:32:46.640 First, let's assign the keys 456 00:32:46.640 --> 00:32:51.000 I'll use W and S for this, interpreting it as the Vertical concept 457 00:32:51.000 --> 00:32:56.639 I'll use A and D for this, interpreting it as the Horizontal concept 458 00:32:57.469 --> 00:33:00.119 Pressing W will simply result in 1 459 00:33:00.119 --> 00:33:03.719 Indicating it's pressed, and when it's not pressed, it'll be 0 460 00:33:03.719 --> 00:33:06.920 Then S should be -1 when pressed 461 00:33:06.920 --> 00:33:11.839 So, I'll add another one in the Modifier section here 462 00:33:11.839 --> 00:33:15.819 There's a 'Negate' option, which will make it negative 463 00:33:15.819 --> 00:33:21.640 So, for the W above, a value of 1 will go into x 464 00:33:21.640 --> 00:33:23.000 And when pressed, it will be 0 if it isn't pressed 465 00:33:23.000 --> 00:33:28.869 And S will go into x with a value of -1 conceptually 466 00:33:29.469 --> 00:33:31.079 So, I've set up these two basics 467 00:33:31.079 --> 00:33:33.160 Now, I'll need to set up A and D 468 00:33:33.160 --> 00:33:36.680 I want to assign A and D to y 469 00:33:36.680 --> 00:33:39.640 So, I'll add another modifier here 470 00:33:39.640 --> 00:33:43.168 here's an option called Swizzle 471 00:33:43.168 --> 00:33:49.368 If you expand it, there's an Order option 472 00:33:49.368 --> 00:33:51.760 Where you can reorder it to y, x, z 473 00:33:52.418 --> 00:33:57.839 Remember, it's about putting values into the leftmost axis 474 00:33:57.839 --> 00:34:00.920 So, it will go into y when swizzled 475 00:34:00.920 --> 00:34:05.199 Swizzling allows you to customize the values as you desire 476 00:34:05.199 --> 00:34:10.379 First, we're using Swizzle to put them into y 477 00:34:11.668 --> 00:34:15.668 Then, A will be negative and D will be positive 478 00:34:15.668 --> 00:34:18.690 We'll need to apply Swizzle to D as well 479 00:34:19.618 --> 00:34:22.679 This way, both A and D will be assigned to y 480 00:34:22.679 --> 00:34:25.879 But D is positive, so we can leave it as it is 481 00:34:25.879 --> 00:34:28.600 However, for A, since it's negative, we need to put in -1 482 00:34:28.600 --> 00:34:33.549 So, I'll add one more and apply 483 00:34:36.399 --> 00:34:37.800 Apply negate here 484 00:34:37.800 --> 00:34:39.468 If you set it up like this, it should work 485 00:34:39.468 --> 00:34:46.368 When you look at the whole setup W remains unchanged, S is negated 486 00:34:46.368 --> 00:34:48.760 And A and D are handled accordingly 487 00:34:49.760 --> 00:34:52.760 Also, we'll need to handle mouse rotation 488 00:34:52.760 --> 00:34:55.399 Let's add one more input 489 00:34:55.399 --> 00:34:58.000 Copy Move input 490 00:34:58.000 --> 00:35:00.560 And name it Look 491 00:35:01.918 --> 00:35:05.679 Then, I'll add a mapping here 492 00:35:05.679 --> 00:35:07.370 Set this one as Look 493 00:35:09.120 --> 00:35:13.199 Look will take mouse x and y inputs 494 00:35:13.199 --> 00:35:16.968 So, mouse x and mouse y 495 00:35:22.468 --> 00:35:23.679 Just like so 496 00:35:23.679 --> 00:35:29.329 Since it's x and y, we should Swizzle y to receive it 497 00:35:33.168 --> 00:35:37.618 And you'll see x is left and right, but y is up and down 498 00:35:37.618 --> 00:35:42.399 Usually, the mouse and actual coordinates are opposite 499 00:35:42.399 --> 00:35:45.040 So we'll include Negate here as well 500 00:35:45.040 --> 00:35:49.289 That's how I'll set it up 501 00:35:50.168 --> 00:35:53.580 We'll move to the TPS class 502 00:35:56.218 --> 00:36:00.140 Then to TPS Player and scroll down 503 00:36:01.268 --> 00:36:05.199 Here, we'll include IMC and IA inputs 504 00:36:05.199 --> 00:36:14.560 UPROPERTY(EditAnywhere) This way, you will be able to contain it 505 00:36:14.560 --> 00:36:16.300 Write class 506 00:36:18.418 --> 00:36:28.918 UInputMappingContext and name it IMC player 507 00:36:30.868 --> 00:36:32.718 Just like so 508 00:36:34.318 --> 00:36:36.768 And we also need to register actions 509 00:36:36.768 --> 00:36:40.070 Like this, it's UInputAction 510 00:36:41.120 --> 00:36:46.580 Here, instead of IMC, we'll name it IA_Move 511 00:36:48.080 --> 00:36:52.568 We'll copy it as is and add another one for Jump 512 00:36:52.568 --> 00:36:58.439 Besides Jump, we'll also add Look under Move like this 513 00:37:00.589 --> 00:37:07.310 Then, we'll need to create functions corresponding to these 514 00:37:12.118 --> 00:37:18.339 Let's add void OnIAMove here 515 00:37:20.568 --> 00:37:25.559 Next, we'll connect three functions 516 00:37:26.768 --> 00:37:32.618 Move, Look, and Jump 517 00:37:32.618 --> 00:37:35.199 Each of these functions will have parameters 518 00:37:35.199 --> 00:37:41.040 write const and there is something called FInputActionValue 519 00:37:41.040 --> 00:37:45.280 Ampersand then write value 520 00:37:45.280 --> 00:37:49.018 In order to use this, you'll need to include the header like this 521 00:37:49.018 --> 00:37:52.129 Should we quickly search this? 522 00:37:53.618 --> 00:37:56.339 If you search it like this 523 00:37:58.639 --> 00:38:01.318 It's set up like this; just add this, and you'll see that 524 00:38:01.318 --> 00:38:05.418 The module is named EnhancedInput 525 00:38:06.268 --> 00:38:12.239 So, if you come over here, I've already written it down 526 00:38:12.239 --> 00:38:15.840 It should be written like this for you all, too 527 00:38:15.840 --> 00:38:20.170 Here, add a comma and then enclose it in double quotation marks as a string 528 00:38:20.768 --> 00:38:23.040 EnhancedInput that was mentioned here earlier 529 00:38:23.040 --> 00:38:26.380 Let's write EnhancedInput right here 530 00:38:28.560 --> 00:38:33.120 You need to register the module to use the class 531 00:38:33.120 --> 00:38:38.240 Once you register it like this, include it 532 00:38:42.968 --> 00:38:47.120 When you use it like this at the top 533 00:38:47.120 --> 00:38:52.767 When you do this, make sure to write it above 534 00:38:53.517 --> 00:38:55.767 Generated at the top 535 00:38:58.159 --> 00:39:01.759 I'll proceed to add them all in the same manner 536 00:39:03.217 --> 00:39:05.219 Let's create the implementation 537 00:39:06.719 --> 00:39:08.400 Shall we compile it first? 538 00:39:12.367 --> 00:39:13.439 There's an error compiling 539 00:39:13.439 --> 00:39:15.120 Unreal Engine is open, so there might be a compile error 540 00:39:15.120 --> 00:39:17.360 Let's close Unreal engine 541 00:39:17.360 --> 00:39:19.667 Try compiling again 542 00:39:21.767 --> 00:39:23.919 Then you should see it compile successfully 543 00:39:23.919 --> 00:39:25.520 Sometimes you might see red lines like this 544 00:39:25.520 --> 00:39:27.850 You can ignore these for now and continue 545 00:39:31.017 --> 00:39:34.479 And now, we register and use this 546 00:39:36.067 --> 00:39:43.517 Let's move to TPS's BeginPlay and write it there 547 00:39:45.120 --> 00:39:49.140 First, let's bring the player controller 548 00:39:49.760 --> 00:39:54.567 Let's call it auto pc and cast it 549 00:39:54.567 --> 00:39:57.600 Currently, we're controlling this player 550 00:39:57.600 --> 00:39:59.760 We can get the player controller 551 00:39:59.760 --> 00:40:03.059 Cast it to the player controller. 552 00:40:06.717 --> 00:40:09.517 Write APlayerController like this 553 00:40:09.517 --> 00:40:16.917 Once casting is successful, verify that we're controlling the actual player character 554 00:40:16.917 --> 00:40:19.967 So, write GetController 555 00:40:22.167 --> 00:40:26.639 After retrieving it, if the casting was successful and pc is not null 556 00:40:26.639 --> 00:40:29.120 if it's not nullptr, you can proceed to write it like this 557 00:40:29.120 --> 00:40:30.470 You also can write just like this 558 00:40:32.167 --> 00:40:37.167 Then there's ULocalPlayer take a look here 559 00:40:37.167 --> 00:40:40.767 You can retrieve ULocalPlayer with Getsubsystem like this 560 00:40:40.767 --> 00:40:42.879 This is in a template form 561 00:40:42.879 --> 00:40:49.217 Write UEnhancedInputLocalPlayerSubsystem here 562 00:40:49.217 --> 00:40:50.639 Just like so 563 00:40:50.639 --> 00:40:53.239 You can fetch the Local Player 564 00:40:56.567 --> 00:41:02.000 From the player controller and assign it 565 00:41:02.000 --> 00:41:04.399 Obviously, we need to add the header for this 566 00:41:04.399 --> 00:41:07.299 Let's search for this as well 567 00:41:11.919 --> 00:41:16.717 Let's try using the include that's here 568 00:41:19.199 --> 00:41:21.499 You can just add it like so 569 00:41:24.639 --> 00:41:25.766 We should receive this first 570 00:41:25.766 --> 00:41:29.919 This one returns the subsystem 571 00:41:29.919 --> 00:41:34.169 Let's retrieve it with auto subsystem 572 00:41:37.266 --> 00:41:40.639 After doing this, we should also perform a null check on it 573 00:41:40.639 --> 00:41:43.717 If it's not null, then for the subsystem 574 00:41:47.017 --> 00:41:51.160 Wait, let's compile it once and then proceed 575 00:41:57.317 --> 00:42:04.317 Compiling was successful, and now, clear from the subsystem 576 00:42:04.317 --> 00:42:07.280 Autocomplete isn't working, but I'll type it out 577 00:42:13.199 --> 00:42:16.320 we'll clear out all the existing mappings for now 578 00:42:16.320 --> 00:42:18.066 We will redo the mapping 579 00:42:18.066 --> 00:42:28.239 We call the function AddMappingContext 580 00:42:28.239 --> 00:42:32.959 And add IMC Player and 0 581 00:42:34.159 --> 00:42:36.080 This is similar to a priority concept 582 00:42:36.080 --> 00:42:37.760 We'll use this directly 583 00:42:37.760 --> 00:42:40.680 I'll add it like this and register it 584 00:42:47.280 --> 00:42:50.517 Implementing this and registering it here would make things easier 585 00:42:50.517 --> 00:42:51.729 Let's register it 586 00:42:55.067 --> 00:42:57.840 To register, we need to cast 587 00:42:57.840 --> 00:43:01.679 If you see, there's UEnhancedInputComponent 588 00:43:01.679 --> 00:43:04.320 It is UInputComponent 589 00:43:04.320 --> 00:43:06.639 We will use it by casting 590 00:43:06.639 --> 00:43:13.040 We'll cast it like this and use it 591 00:43:13.040 --> 00:43:15.679 There's also CastChecked 592 00:43:15.679 --> 00:43:20.080 CastChecked conceptually includes null checking as well 593 00:43:20.080 --> 00:43:26.480 I'll cast it like this and proceed to use it 594 00:43:31.517 --> 00:43:33.120 Just like so 595 00:43:33.120 --> 00:43:36.020 To use this, you'll also need to include the header 596 00:43:36.967 --> 00:43:41.767 Automatically add the header 597 00:43:41.767 --> 00:43:44.719 You'll see it reflects well when you do it this way 598 00:43:44.719 --> 00:43:46.719 I'll try adding this in a similar manner 599 00:43:46.719 --> 00:43:48.639 Errors keep occurring 600 00:43:48.639 --> 00:43:52.190 I'll add this one as well 601 00:43:53.040 --> 00:43:55.510 I have included these two like this 602 00:43:59.560 --> 00:44:04.466 Resolved error with includes If I build it then the error goes away 603 00:44:06.520 --> 00:44:08.750 Then we need to establish the connection here 604 00:44:09.566 --> 00:44:11.989 Let's proceed with binding 605 00:44:15.616 --> 00:44:18.816 In case of EnhancedInput 606 00:44:18.816 --> 00:44:21.320 EnhancedInput has both Actions and Axes 607 00:44:21.320 --> 00:44:24.919 All inputs are configured using BindAction 608 00:44:24.919 --> 00:44:27.816 Write BindAction 609 00:44:27.816 --> 00:44:30.416 Next, if we were to start with Move 610 00:44:30.416 --> 00:44:33.399 We should add IA Move 611 00:44:33.399 --> 00:44:39.719 And then in ETriggerEvent, it looks like so 612 00:44:39.719 --> 00:44:42.816 There's Triggered, and then Started, Ongoing, and Completed 613 00:44:42.816 --> 00:44:45.810 More various codes exist 614 00:44:46.760 --> 00:44:49.466 Typically, for handling Axis, you would use Triggered 615 00:44:49.466 --> 00:44:51.000 Then they can keep coming 616 00:44:51.000 --> 00:44:52.360 Then, for button handling 617 00:44:52.360 --> 00:44:55.679 You can use Started and Completed 618 00:44:55.679 --> 00:44:59.616 So, since this is for Move, Triggered should do the trick 619 00:44:59.616 --> 00:45:03.039 Write in this, then you put the function's address here 620 00:45:04.639 --> 00:45:07.840 It's not significantly different from the usual method 621 00:45:07.840 --> 00:45:10.016 Register it like this 622 00:45:10.016 --> 00:45:17.159 And similarly, I'll copy and paste this 623 00:45:17.159 --> 00:45:19.666 To handle Lookup as well 624 00:45:19.666 --> 00:45:21.129 This one will be Look 625 00:45:26.216 --> 00:45:31.560 Let's also handle Jump too, since it's button based 626 00:45:31.560 --> 00:45:35.199 Like this, we'll handle Jump 627 00:45:35.199 --> 00:45:36.760 And for this one 628 00:45:36.760 --> 00:45:41.216 Since it triggers only when pressed, we'll use Started 629 00:45:42.316 --> 00:45:44.070 Have this as Jump 630 00:45:45.066 --> 00:45:49.066 Handling player movement and rotation 631 00:45:49.320 --> 00:45:52.040 Next, let's implement handling 632 00:45:52.040 --> 00:45:54.616 Player movement and rotation 633 00:45:55.080 --> 00:45:57.666 Let's move somewhere else 634 00:45:57.666 --> 00:46:00.466 To do that, we need to save the direction first 635 00:46:00.466 --> 00:46:03.666 Since we can't directly use the values passed here 636 00:46:03.666 --> 00:46:07.379 Let's create a variable named Direction 637 00:46:12.966 --> 00:46:15.569 And store them in a Vector 638 00:46:16.716 --> 00:46:20.216 We'll store it and We can't use it right away 639 00:46:20.216 --> 00:46:23.439 So let's fetch it from value 640 00:46:23.439 --> 00:46:26.239 We can bring value using get 641 00:46:26.239 --> 00:46:30.816 For Move, as I turned off 642 00:46:30.816 --> 00:46:33.616 Move is implemented as FVector2D 643 00:46:33.616 --> 00:46:36.266 Bring it just like so 644 00:46:36.266 --> 00:46:40.600 In order to do that, do as I do 645 00:46:40.600 --> 00:46:43.560 Then simply assign the values from here to this variable 646 00:46:43.560 --> 00:46:45.700 Assign x to itself in the x variable 647 00:46:49.000 --> 00:46:50.959 Since we're using x and y 648 00:46:50.959 --> 00:46:56.080 Then we'll assign y to the y variable like this 649 00:46:59.080 --> 00:47:10.879 (Lookup rotation functions AddControllerPitchInput, AddControllerYawInput) And for Lookup, rotation uses these functions 650 00:47:10.879 --> 00:47:14.719 What this does is 651 00:47:14.719 --> 00:47:16.360 It takes input rotation values and stores them here 652 00:47:16.360 --> 00:47:20.040 Maintaining rotation information 653 00:47:20.040 --> 00:47:25.280 Next, where will this be applied in the character's code 654 00:47:25.280 --> 00:47:27.365 Needs to be decided 655 00:47:27.365 --> 00:47:30.399 For now, we'll handle Pitch and Yaw here 656 00:47:30.399 --> 00:47:32.916 Because Pitch and Yaw are 657 00:47:32.916 --> 00:47:36.560 Pitch is nodding up and down while Yaw is swiveling side to side 658 00:47:36.560 --> 00:47:42.116 So, we'll rotate like this, swivel like this, and turn like this 659 00:47:42.760 --> 00:47:45.800 So, we'll rotate like this, swivel like this, and turn like this 660 00:47:45.800 --> 00:47:55.916 So, we'll use AddControllerPitchInput and AddControllerYawInput 661 00:47:55.916 --> 00:47:58.199 Let's use both of them 662 00:48:02.366 --> 00:48:05.600 That should work and now, we'll need to fetch from here again 663 00:48:05.600 --> 00:48:07.599 In a similar manner, we'll fetch it like this 664 00:48:10.616 --> 00:48:14.166 Because on the mouse, x is left right and y is up down 665 00:48:14.166 --> 00:48:16.840 Nodding would correspond to y 666 00:48:16.840 --> 00:48:19.066 Let's assign vec's y value here 667 00:48:20.840 --> 00:48:25.000 When you assign vec's x value like this 668 00:48:25.000 --> 00:48:28.549 Characters can nod and swivel movements like this 669 00:48:29.766 --> 00:48:31.959 Next, for Jump, we do it like this 670 00:48:31.959 --> 00:48:33.669 Just label it as Jump 671 00:48:35.919 --> 00:48:38.959 By calling the Jump function like this, you can perform a jump 672 00:48:38.959 --> 00:48:40.719 That's how you implement it 673 00:48:40.719 --> 00:48:45.479 Then, you'll need to implement 674 00:48:45.479 --> 00:48:47.966 The actual movement in the T part 675 00:48:47.966 --> 00:48:51.315 In the case of a character, there's a component called Character Movement 676 00:48:51.315 --> 00:48:53.040 You'll use that to handle the movement 677 00:48:53.040 --> 00:48:57.360 There's a function called AddMovementInput there 678 00:48:57.360 --> 00:49:04.616 You just need to pass Direction here like this 679 00:49:04.616 --> 00:49:07.520 But here, you're continuously filling in the values for Direction 680 00:49:07.520 --> 00:49:09.439 Then it will remain here like this 681 00:49:09.439 --> 00:49:11.515 So it will move even without me pressing any buttons 682 00:49:11.515 --> 00:49:14.215 So after handling Direction once 683 00:49:14.215 --> 00:49:25.199 Make sure to always initialize it with ZeroVector 684 00:49:25.199 --> 00:49:29.065 So the value is only set when pressed, and becomes Zero when released 685 00:49:29.065 --> 00:49:31.400 Then it won't move, like so 686 00:49:33.965 --> 00:49:36.370 Let's take a look at the results 687 00:49:42.615 --> 00:49:50.479 It's necessary to implement all the input handling for the player 688 00:49:51.715 --> 00:49:54.800 Here is where the input will go 689 00:49:54.800 --> 00:49:59.120 Let's put our custom IMC here 690 00:49:59.120 --> 00:50:02.010 Next, for Move, select TPS related settings 691 00:50:03.265 --> 00:50:08.249 For TPSLook and TPSJump, you can assign them accordingly 692 00:50:10.415 --> 00:50:12.919 Compile it and let's run it to check 693 00:50:12.919 --> 00:50:15.015 I can rotate 694 00:50:15.015 --> 00:50:20.565 Rotating works fine and I can also move my character 695 00:50:20.565 --> 00:50:22.115 I've made some settings for the rotation 696 00:50:22.115 --> 00:50:25.399 You'll find the basic rotation with these three selfs 697 00:50:27.949 --> 00:50:34.065 And then there's the spring arm here 698 00:50:34.065 --> 00:50:36.959 Also, there's the character movement 699 00:50:36.959 --> 00:50:38.515 Take a look at rotation, 700 00:50:38.515 --> 00:50:44.239 And if you search for it, you'll see it's checked here 701 00:50:44.239 --> 00:50:46.315 It says Use Controller Rotation Yaw in Pawn 702 00:50:46.315 --> 00:50:49.600 But originally, it wasn't checked here 703 00:50:49.600 --> 00:50:52.080 So, when you run it 704 00:50:52.080 --> 00:50:54.600 Rotation will likely only happen this way 705 00:50:54.600 --> 00:50:58.465 While movement will work fine 706 00:50:58.465 --> 00:51:02.040 The movement feels strange too, When I look behind, I end up moving backward 707 00:51:02.040 --> 00:51:04.965 Pressing w results in an unnatural feeling of movement 708 00:51:04.965 --> 00:51:09.365 I can see that it only moves forward like this 709 00:51:09.365 --> 00:51:12.665 These issues must be dealt with 710 00:51:13.199 --> 00:51:18.929 let's start with rotation, rotation typically looks like this 711 00:51:20.479 --> 00:51:24.315 If you input rotation values into AddControllerPitchInput/YawInput 712 00:51:24.315 --> 00:51:26.120 You're effectively holding 713 00:51:26.120 --> 00:51:29.919 Rotational information in those inputs 714 00:51:29.919 --> 00:51:32.815 Reflecting this involves 715 00:51:32.815 --> 00:51:35.239 Applying rotation through the options here 716 00:51:35.239 --> 00:51:40.639 So self essentially refers to the TPSPlayer itself 717 00:51:40.639 --> 00:51:44.600 I'll use the controller's values 718 00:51:44.600 --> 00:51:47.639 For the rotation axis of TPSPlayer's Yaw 719 00:51:47.639 --> 00:51:50.915 So if we check Pitch, it would look like this 720 00:51:50.915 --> 00:51:53.809 Where rotating causes it to lie down like this 721 00:51:55.415 --> 00:51:58.760 Pressing F8 like this allows you to escape 722 00:51:58.760 --> 00:52:00.399 This is what happens 723 00:52:00.399 --> 00:52:03.690 So, what we want is not this 724 00:52:03.690 --> 00:52:05.879 We want Pitch to rotate the camera only 725 00:52:05.879 --> 00:52:07.879 Not affect the character's orientation 726 00:52:07.879 --> 00:52:12.365 So, we'll leave this as it is 727 00:52:12.365 --> 00:52:17.765 Select Spring Arm and check Use Pawn Control Rotation 728 00:52:18.679 --> 00:52:24.470 When we run it, it will handle things like this 729 00:52:25.320 --> 00:52:28.615 Next, for jumping, you do it like this 730 00:52:28.615 --> 00:52:31.465 But finally, it seems like 731 00:52:31.465 --> 00:52:33.800 You need to move in the direction you're facing 732 00:52:33.800 --> 00:52:37.814 Right now, you're moving in an absolute direction 733 00:52:37.814 --> 00:52:42.740 Even if you're facing this way, you're moving forward like this 734 00:52:45.065 --> 00:52:47.869 Let me try to solve this for you 735 00:52:49.915 --> 00:52:52.619 Coming back to the player 736 00:52:54.719 --> 00:52:57.915 we move on to Tick and In Tick, we'll handle this 737 00:52:57.915 --> 00:53:04.965 This Direction is currently an absolute direction 738 00:53:04.965 --> 00:53:14.865 What we want is for this absolute direction to rotate relative to me 739 00:53:14.865 --> 00:53:16.719 So, what I mean is that currently, forward is absolute 740 00:53:16.719 --> 00:53:18.665 What we actually want is for these directions 741 00:53:18.665 --> 00:53:21.760 like east, west, north, south 742 00:53:21.760 --> 00:53:26.815 (Making it move relative to me) I want it to rotate relative to me 743 00:53:26.815 --> 00:53:32.315 We'll adjust the Direction value to reflect this relative positioning based on me 744 00:53:32.315 --> 00:53:34.159 Here's how you can do it 745 00:53:34.159 --> 00:53:39.919 Write Direction FTransform 746 00:53:39.919 --> 00:53:46.479 Then find GetControlRotation 747 00:53:48.015 --> 00:53:54.879 It takes the rotation values received from the controller input directly 748 00:53:54.879 --> 00:53:57.359 Right now, we're inserting it like this 749 00:53:58.115 --> 00:54:02.680 Then we fetch the rotation values stored there 750 00:54:03.515 --> 00:54:11.960 Then, using that as a basis, there's something called TransformVector 751 00:54:14.310 --> 00:54:17.764 In Blueprints, this is labeled as TransformDirection 752 00:54:17.764 --> 00:54:20.560 But in here, it's named TransformVector 753 00:54:20.560 --> 00:54:25.439 You just need to input Direction here and then perform the transformation 754 00:54:25.439 --> 00:54:32.214 This will return the orientation with the axis swapped 755 00:54:32.214 --> 00:54:37.399 Based on the current state stored in the controls 756 00:54:38.364 --> 00:54:46.114 Then I'll compile this and see the results afterwards 757 00:54:46.114 --> 00:54:49.064 When I run it and if I look this way and press W 758 00:54:49.064 --> 00:54:53.514 I start moving in this direction 759 00:54:53.514 --> 00:54:57.500 That's how it works, enabling this kind of control 760 00:54:58.614 --> 00:55:03.399 As for the player, the way we've set it up now 761 00:55:03.399 --> 00:55:05.679 We can't see the face 762 00:55:05.679 --> 00:55:07.314 If I try rotating like this 763 00:55:07.314 --> 00:55:08.959 You never get to see the face 764 00:55:08.959 --> 00:55:10.520 You can only see the back of the head 765 00:55:10.520 --> 00:55:13.479 Typically, in role-playing games, RPGs 766 00:55:13.479 --> 00:55:15.864 You can see the face in such games 767 00:55:15.864 --> 00:55:18.800 Even if you can see the face when you press w 768 00:55:18.800 --> 00:55:20.700 The character turns its back and moves forward 769 00:55:21.664 --> 00:55:24.669 We can also handle this as well 770 00:55:25.664 --> 00:55:31.560 Turn off these controller rotate 771 00:55:31.560 --> 00:55:35.114 Then, go to character movement 772 00:55:35.114 --> 00:55:37.600 And search Rotation 773 00:55:37.600 --> 00:55:40.364 Then, you will find Orient Rotation to Movement 774 00:55:40.364 --> 00:55:45.280 Check that and try it on after compiling 775 00:55:45.280 --> 00:55:48.969 Now I can rotate freely, able to see the face 776 00:55:49.919 --> 00:55:52.199 And if I press w here 777 00:55:52.199 --> 00:55:56.314 The body rotates relatively to the direction I am facing 778 00:55:56.314 --> 00:55:59.964 With w button pressed, character would rotate like this 779 00:56:02.959 --> 00:56:05.479 Not pressing w looks like this 780 00:56:05.479 --> 00:56:07.364 If you use this function 781 00:56:07.364 --> 00:56:10.364 Whenever you are creating desired contents 782 00:56:10.364 --> 00:56:14.179 Depending on the concept establish could lead to different settings 783 00:56:15.029 --> 00:56:19.840 But, since we are making TPS, we don't really need to see the face 784 00:56:19.840 --> 00:56:21.964 Will be satisfied just with the back of the head 785 00:56:21.964 --> 00:56:25.120 So, I will check this 786 00:56:25.120 --> 00:56:27.399 And then there is an issue with jump too 787 00:56:27.399 --> 00:56:29.320 As you can see, the character jumps like this 788 00:56:29.320 --> 00:56:33.679 If I wanted to jump twice, I can easily set it up 789 00:56:33.679 --> 00:56:37.120 Go to character, turn this thing off 790 00:56:37.120 --> 00:56:38.864 If you press 'Self' here 791 00:56:38.864 --> 00:56:45.479 And search for Jump Max Count 792 00:56:45.479 --> 00:56:47.814 You'll find this, it says 1 793 00:56:47.814 --> 00:56:52.879 If you change this to 2, you can jump twice 794 00:56:52.879 --> 00:56:57.399 If you change this to 2, you can jump twice 795 00:56:57.399 --> 00:56:59.919 Depending on how you set this value like this 796 00:56:59.919 --> 00:57:02.719 You can change the number of jumps 797 00:57:02.719 --> 00:57:07.570 And if you look here in Character Movement 798 00:57:10.063 --> 00:57:13.479 You can configure settings for jumping here 799 00:57:13.479 --> 00:57:14.719 There are options for Jumping and Falling 800 00:57:14.719 --> 00:57:17.564 Here if you take a look, there is Air Control 801 00:57:17.564 --> 00:57:19.864 There are more stuff to this 802 00:57:19.864 --> 00:57:21.564 Here is Air Control 803 00:57:21.564 --> 00:57:24.264 It's set to 0.05 which means 804 00:57:24.264 --> 00:57:28.199 The force taken while in the air after jumping 805 00:57:28.199 --> 00:57:29.879 It's set to a very small value 806 00:57:29.879 --> 00:57:32.310 So when you jump and try to press in the opposite direction like this 807 00:57:33.560 --> 00:57:35.360 It doesn't seem to offer much resistance 808 00:57:35.360 --> 00:57:38.719 It feels like the character continues moving in the direction it jumped 809 00:57:38.719 --> 00:57:43.414 It feels like keep moving in the direction I jumped, without much resistance to change direction 810 00:57:44.564 --> 00:57:51.760 If you want to change direction in the air as well, you can increase Air Control value 811 00:57:51.760 --> 00:57:55.399 Let's increase to 5 812 00:57:55.399 --> 00:57:59.714 After you compile and run it 813 00:57:59.714 --> 00:58:03.979 When you press in the opposite direction, you should feel more resistance 814 00:58:05.479 --> 00:58:10.439 This way, you can control your movement in the air 815 00:58:10.439 --> 00:58:13.314 You can refer to these settings to proceed with your work 816 00:58:13.314 --> 00:58:17.664 Let me summarize what we learned in this chapter 817 00:58:17.664 --> 00:58:20.014 Creating a C -based project and generating a TPS player Understanding character class 818 00:58:20.014 --> 00:58:22.364 FPS First-Person Shooter TPS Third-Person Shooter 819 00:58:22.364 --> 00:58:24.714 Applying the appearance of a TPS character Game designer, artist, programmer 820 00:58:24.714 --> 00:58:26.714 Applying Third person camera and appearances 821 00:58:26.714 --> 00:58:28.664 The role of SpringArm Automatically handling situations where the camera view is obstructed 822 00:58:28.664 --> 00:58:30.664 When there is a wall between the camera and the player, using a spring arm To automatically move the camera's position beyond the wall 823 00:58:30.664 --> 00:58:32.614 If the camera automatically moves backward, decrease the Target Arm Length 824 00:58:32.614 --> 00:58:34.664 Handling player movement and rotation 825 00:58:34.664 --> 00:58:37.564 Role of CharacterMovementComponent Components used to control movement when manipulating the actual character 826 00:58:37.564 --> 00:58:40.514 Handling movement, Lookup rotate function AddcontrollerPitchInput, AddcontrollerYawInput