WEBVTT 1 00:00:06.050 --> 00:00:10.100 Game advanced level control of gun 2 00:00:23.700 --> 00:00:25.500 Hello My name is Lee Yong Woo 3 00:00:25.500 --> 00:00:29.240 We will learn about the control of gun in this chapter 4 00:00:29.240 --> 00:00:35.080 We will learn about how to pickup, drop and shoot guns as learning contents 5 00:00:35.080 --> 00:00:38.380 In each contents, we will deal with how to use 6 00:00:38.380 --> 00:00:41.279 Enhanced Input which is added to unreal engine 5 7 00:00:41.279 --> 00:00:46.279 First, in pickup guns, learn how to extract actors you want to find as per range search 8 00:00:46.279 --> 00:00:49.919 And add it to mesh component of the character 9 00:00:49.919 --> 00:00:53.619 Next, in drop guns, process logic to detach guns 10 00:00:53.619 --> 00:00:56.240 Which is attached to mesh component 11 00:00:56.240 --> 00:00:59.790 And last, in shooting guns, how to calculate 12 00:00:59.790 --> 00:01:03.290 The point of view the player views via camera 13 00:01:03.290 --> 00:01:05.589 And process collision using LineTrace 14 00:01:05.589 --> 00:01:09.650 Pickup and drop guns 15 00:01:09.650 --> 00:01:13.189 We have to get assets we need for picking up 16 00:01:13.189 --> 00:01:16.639 So among the assets distributed 17 00:01:16.639 --> 00:01:20.339 There would be this asset called PistolMesh 18 00:01:20.339 --> 00:01:25.039 Unzip it, then there is PistolMesh folder 19 00:01:25.039 --> 00:01:29.639 Bring this PistolMesh folder to NetTPS folder 20 00:01:29.639 --> 00:01:33.889 Under the content folder by drag and drop 21 00:01:33.889 --> 00:01:37.639 Drag it and drop like this 22 00:01:37.639 --> 00:01:41.839 Now then, on the unreal engine editor 23 00:01:41.839 --> 00:01:43.959 There is a popup window asking whether you would import it or not 24 00:01:43.959 --> 00:01:45.659 Press import 25 00:01:45.659 --> 00:01:47.559 And press import all 26 00:01:47.559 --> 00:01:50.509 Now close the Message Log window 27 00:01:50.509 --> 00:01:54.009 Then, under the NetTPS folder 28 00:01:54.009 --> 00:01:55.800 You can see there is PistolMesh folder 29 00:01:55.800 --> 00:02:00.239 Let's work this material into the form we need 30 00:02:00.239 --> 00:02:04.889 First, in the PistolMesh folder we just brought 31 00:02:04.889 --> 00:02:07.039 There is static mesh as well as material 32 00:02:07.039 --> 00:02:08.399 And textures 33 00:02:08.399 --> 00:02:10.849 There are textures we are going to use 34 00:02:10.849 --> 00:02:15.329 We will make material by using these textures 35 00:02:15.329 --> 00:02:19.079 Come to here and remove 36 00:02:19.079 --> 00:02:21.679 This one called Param 37 00:02:21.679 --> 00:02:23.720 Press delete to remove it 38 00:02:23.720 --> 00:02:28.020 And then press ctrl + space bar to open content drawe 39 00:02:28.020 --> 00:02:32.240 Under the NetTPS, under the PistolMesh, there is Textures folder 40 00:02:32.240 --> 00:02:34.090 Let's bring what we need from here 41 00:02:34.090 --> 00:02:37.360 First of all, take normal map 42 00:02:37.360 --> 00:02:40.460 and connect to Normal socket 43 00:02:42.720 --> 00:02:48.620 Next, there is one called T_Pistol_AORM 44 00:02:48.620 --> 00:02:52.970 Grab this and drag and drop like this 45 00:02:54.399 --> 00:02:56.499 It was AORM 46 00:02:56.499 --> 00:02:58.699 This R channel goes into AO 47 00:02:58.699 --> 00:03:01.160 It says Ambient Occlusion 48 00:03:01.160 --> 00:03:04.060 AO stands for Ambient Occlusion 49 00:03:04.060 --> 00:03:07.960 So put R channel into AO socket 50 00:03:07.960 --> 00:03:10.160 Into Ambient Occlusion 51 00:03:10.160 --> 00:03:16.010 Remain is RM, so connect G to Roughness 52 00:03:16.010 --> 00:03:20.060 And connect B channel to Metallic like this 53 00:03:20.060 --> 00:03:24.519 Then you can preview on the viewport window 54 00:03:25.479 --> 00:03:32.679 Next, you can see T_Pistol_D here 55 00:03:32.679 --> 00:03:36.629 Instead of just using it 56 00:03:36.629 --> 00:03:40.379 There is masks texture next to it 57 00:03:40.379 --> 00:03:43.199 We will blend it with this 58 00:03:43.199 --> 00:03:46.549 Before we put it in Base Color 59 00:03:46.549 --> 00:03:51.600 Therefore, take T_Pistol_Masks and add it 60 00:03:51.600 --> 00:03:54.250 Then while pressing M 61 00:03:54.250 --> 00:03:57.050 If you click empty space on graph 62 00:03:57.050 --> 00:03:59.720 Multiply node will be added 63 00:03:59.720 --> 00:04:02.220 Press M on keyboard to do it 64 00:04:02.220 --> 00:04:05.399 Click while pressing M to add it 65 00:04:05.399 --> 00:04:09.299 If you find it hard to do, then there is a palette on right side 66 00:04:09.299 --> 00:04:15.399 Search multiply on the palette 67 00:04:15.399 --> 00:04:18.699 There is Multiply node of Math 68 00:04:18.699 --> 00:04:21.359 You also can drag and drop this 69 00:04:21.359 --> 00:04:23.909 Now if you see this Texture Sample 70 00:04:23.909 --> 00:04:27.909 Here is diffuse map image 71 00:04:27.909 --> 00:04:31.490 Take this and put it in A socket of Multiply 72 00:04:31.540 --> 00:04:34.390 Then the output 73 00:04:34.390 --> 00:04:36.359 Goes into Base Color like this 74 00:04:36.359 --> 00:04:38.509 Then now, as you see, they are mixed 75 00:04:38.509 --> 00:04:40.859 Now let me blend this image 76 00:04:40.859 --> 00:04:43.399 With blue background from masks into it 77 00:04:43.399 --> 00:04:47.999 I'm going to add a Lerp node here 78 00:04:47.999 --> 00:04:50.279 Press L on keyboard to do it 79 00:04:50.279 --> 00:04:54.029 Click empty space of graph while pressing L 80 00:04:54.029 --> 00:04:57.480 Click while pressing L to add Lerp node 81 00:04:57.480 --> 00:05:01.030 Then put R channel into A 82 00:05:01.030 --> 00:05:02.930 And G channel into B 83 00:05:02.930 --> 00:05:08.279 B channel into Alpha socket 84 00:05:08.279 --> 00:05:11.079 The output of Lerp 85 00:05:11.079 --> 00:05:13.839 Goes into B of Multiply 86 00:05:13.839 --> 00:05:17.239 Then you can preview on the viewport window like this 87 00:05:17.239 --> 00:05:20.440 Now the whole graph is formed like this 88 00:05:20.440 --> 00:05:24.090 Save and close this material 89 00:05:24.090 --> 00:05:27.340 Next, to allow player to grab guns 90 00:05:27.340 --> 00:05:29.839 We will add a component here 91 00:05:29.839 --> 00:05:31.889 Come to Visual Studio Code 92 00:05:31.889 --> 00:05:34.089 And move to the header file 93 00:05:34.089 --> 00:05:36.359 With the name of NetTPSCharacter 94 00:05:36.359 --> 00:05:42.259 Since all the components are added here on top 95 00:05:42.259 --> 00:05:45.040 So I will paste here 96 00:05:45.040 --> 00:05:49.140 Copy and paste UPROPERTY 97 00:05:49.140 --> 00:05:53.240 Now the component we are trying to add here is 98 00:05:53.240 --> 00:05:58.209 The one where guns will be added as child 99 00:05:58.209 --> 00:06:02.609 Therefore make this component as SceneComponent 100 00:06:02.609 --> 00:06:08.959 Declare class USceneComponent 101 00:06:09.679 --> 00:06:12.479 With the name of gunComp 102 00:06:12.479 --> 00:06:17.129 Then move to the constructor on NetTPSCharacter.cpp 103 00:06:17.129 --> 00:06:20.559 And move down to the bottom of it 104 00:06:20.559 --> 00:06:26.320 Type gunComp = CreateDefaultSubobject 105 00:06:26.880 --> 00:06:30.280 Put USceneComponent into angle brackets 106 00:06:30.280 --> 00:06:36.359 and GunComp as text into parentheses 107 00:06:37.520 --> 00:06:46.770 Now execute SetupAttachment after gunComp 108 00:06:46.770 --> 00:06:50.920 and GetMesh as parent component 109 00:06:50.920 --> 00:06:55.720 Then mesh component will be the parent component of gunComp 110 00:06:55.720 --> 00:06:58.070 And put in the name of socket here 111 00:06:58.070 --> 00:07:04.679 Let's say GunPosition as text to be identified easily 112 00:07:04.679 --> 00:07:06.920 Like this 113 00:07:08.519 --> 00:07:12.919 Then this gunComp will be attached 114 00:07:12.919 --> 00:07:17.000 To the GunPosition socket of mesh 115 00:07:17.000 --> 00:07:19.719 Now build it once 116 00:07:20.279 --> 00:07:23.479 Once it's done, go to the unreal engine and take a look 117 00:07:23.479 --> 00:07:27.320 We can see Gun Comp under the Mesh component 118 00:07:27.320 --> 00:07:29.570 Usually, if you don't see it, then 119 00:07:29.570 --> 00:07:33.480 Please restart the unreal engine 120 00:07:33.480 --> 00:07:38.080 As you can see, Gun Comp is attached like this 121 00:07:38.080 --> 00:07:40.530 But in your case, when you started unreal engine 122 00:07:40.530 --> 00:07:42.760 This Gun Comp could be on the floor like this 123 00:07:42.760 --> 00:07:46.010 Since we didn't make a socket called Gun Position yet 124 00:07:46.010 --> 00:07:47.610 It can't be attached to hands 125 00:07:47.610 --> 00:07:50.200 It's normal to be attached to the floor 126 00:07:50.200 --> 00:07:54.100 So Gun Comp needs to be on the hands to make 127 00:07:54.100 --> 00:07:56.500 Guns are able to be attached to like this 128 00:07:56.500 --> 00:07:58.950 Let's add a socket 129 00:07:58.950 --> 00:08:02.679 So Gun Comp can be attached to that socket 130 00:08:02.679 --> 00:08:04.529 Then where should we bring this socket 131 00:08:04.529 --> 00:08:08.760 Select this Mesh component then on the right bottom of the editor 132 00:08:08.760 --> 00:08:14.060 There is a mesh that this skeletal mesh component is using 133 00:08:14.060 --> 00:08:16.239 You can see Skeletal Mesh Asset 134 00:08:16.239 --> 00:08:19.389 There is preview image of skeletal mesh that is used 135 00:08:19.389 --> 00:08:21.600 Double click this one 136 00:08:21.600 --> 00:08:22.950 Good, you see 137 00:08:22.950 --> 00:08:25.350 There is Skeleton Tree on the right 138 00:08:25.350 --> 00:08:28.500 What we want to use in this Skeleton Tree 139 00:08:28.500 --> 00:08:31.959 I will attach it to the right hand 140 00:08:31.959 --> 00:08:36.609 So there is hand_l and there would be hand_r 141 00:08:36.609 --> 00:08:39.259 If you keep goes down there is hand_r 142 00:08:39.259 --> 00:08:43.359 Right click on hand_r 143 00:08:43.359 --> 00:08:46.309 and click Add Socket 144 00:08:46.309 --> 00:08:50.109 Then you will see hand_rSocket 145 00:08:50.109 --> 00:08:51.459 Let's rename it 146 00:08:51.459 --> 00:08:55.489 Since we said Gun Position on the code 147 00:08:55.489 --> 00:08:57.640 So name this one as same 148 00:08:57.640 --> 00:08:58.990 Alright 149 00:08:58.990 --> 00:09:01.790 Then save it 150 00:09:01.790 --> 00:09:05.159 and close the window 151 00:09:05.159 --> 00:09:08.259 If you select Gun Comp 152 00:09:08.259 --> 00:09:12.120 You can see it is attached to hand 153 00:09:12.120 --> 00:09:15.220 Right? It is attached to hand like this 154 00:09:15.220 --> 00:09:19.870 Now since we made gunComp 155 00:09:19.870 --> 00:09:22.359 Attached to socket 156 00:09:22.359 --> 00:09:25.059 Called GunPosition on the code 157 00:09:25.059 --> 00:09:28.200 You can see it is well attached 158 00:09:28.200 --> 00:09:31.650 Then attach gun to Gun Comp 159 00:09:31.650 --> 00:09:33.600 to adjust the position 160 00:09:33.600 --> 00:09:36.350 To check if it is well attached 161 00:09:36.350 --> 00:09:39.119 There is SM_Pistol in PistolMesh 162 00:09:39.119 --> 00:09:43.269 Attach it to the Gun Comp as child like this 163 00:09:43.269 --> 00:09:45.479 Then it is attached to here 164 00:09:45.479 --> 00:09:50.229 We don't edit this SM_Pistol directly 165 00:09:50.229 --> 00:09:52.070 To adjust the position 166 00:09:52.070 --> 00:09:55.920 The parent component above it, the scene component 167 00:09:55.920 --> 00:09:59.520 We have to adjust it's position 168 00:09:59.520 --> 00:10:02.440 So the pistol below 169 00:10:02.440 --> 00:10:07.340 Needs to be set 0, 0, 0 under the Transform 170 00:10:07.340 --> 00:10:09.719 Just keep it as you attached 171 00:10:09.719 --> 00:10:14.569 So let's adjust the position of Gun Comp directly 172 00:10:14.569 --> 00:10:17.479 It is hard to work because of the animation 173 00:10:17.479 --> 00:10:20.279 Select Mesh component 174 00:10:20.279 --> 00:10:22.629 There is Animation tab on the right side 175 00:10:22.629 --> 00:10:26.960 If you open Advanced tab 176 00:10:26.960 --> 00:10:31.590 You can see there's Pause Anims 177 00:10:32.760 --> 00:10:35.160 Check this Pause Anims 178 00:10:35.160 --> 00:10:39.410 Then you can see the animation attached to 179 00:10:39.410 --> 00:10:42.520 Mesh component, the skeleton mesh, is paused 180 00:10:42.520 --> 00:10:45.770 Now it'd be easier for us to work 181 00:10:45.770 --> 00:10:49.479 Then let's adjust the position of Gun Comp 182 00:10:49.479 --> 00:10:53.129 Let me rotate it first 183 00:10:53.129 --> 00:10:56.150 Rotate a bit like this 184 00:10:57.180 --> 00:11:00.330 Right? Then move a bit forward 185 00:11:00.330 --> 00:11:02.730 I'm not adjusting SM_Pistol 186 00:11:02.730 --> 00:11:06.809 As you can see, select the Gun Comp 187 00:11:06.809 --> 00:11:10.599 Select it like this and adjust 188 00:11:11.080 --> 00:11:15.530 Now then adjust the position 189 00:11:15.530 --> 00:11:19.450 Adjust the position of hands 190 00:11:21.479 --> 00:11:26.460 Like this 191 00:11:27.559 --> 00:11:30.409 And it is tilted to one side a bit 192 00:11:30.409 --> 00:11:31.759 It looks okay but 193 00:11:31.759 --> 00:11:34.729 Let me tilt it little bit like this 194 00:11:36.519 --> 00:11:39.269 Tilted like this 195 00:11:39.269 --> 00:11:43.320 Then player is holding pistol like this 196 00:11:43.320 --> 00:11:46.770 Now let's code these values 197 00:11:46.770 --> 00:11:50.320 There is information of transform on the right 198 00:11:50.320 --> 00:11:52.870 Take both location and 199 00:11:52.870 --> 00:11:55.670 Rotation values from transform 200 00:11:55.670 --> 00:11:57.440 And paste it 201 00:11:57.440 --> 00:11:59.590 Right click here 202 00:11:59.590 --> 00:12:02.799 Right click on location and select copy 203 00:12:02.799 --> 00:12:04.749 and move to the code 204 00:12:04.749 --> 00:12:12.640 Execute SetRelativeLocation on gunComp 205 00:12:12.640 --> 00:12:16.540 and paste it as Fvector 206 00:12:16.540 --> 00:12:22.339 Remove X,Y,Z parts and keep values only 207 00:12:24.840 --> 00:12:28.340 Alright? Let's go get rotation values and set it 208 00:12:28.340 --> 00:12:33.239 Right click on rotation and copy it as well 209 00:12:34.619 --> 00:12:39.869 Then execute 210 00:12:39.869 --> 00:12:43.960 SetRelativeRotation on gunComp and put values as FRotator 211 00:12:43.960 --> 00:12:47.120 ctrl + v 212 00:12:47.120 --> 00:12:54.550 Then you can paste it from clipboard in order 213 00:12:56.550 --> 00:12:59.650 Set them like this 214 00:12:59.650 --> 00:13:02.950 Then build it to process 215 00:13:02.950 --> 00:13:07.679 So that this information can be applied on C++ class itself 216 00:13:07.679 --> 00:13:11.829 Now then do not attach pistol direct to here 217 00:13:11.829 --> 00:13:14.129 We are supposed to grab it by pressing key 218 00:13:14.129 --> 00:13:17.080 So press delete on pistol 219 00:13:17.130 --> 00:13:21.529 Press delete to remove SM_Pistol component 220 00:13:21.529 --> 00:13:24.029 Then select Mesh component 221 00:13:24.029 --> 00:13:26.979 Uncheck Pause Anims on the right 222 00:13:26.979 --> 00:13:29.840 To get animation back 223 00:13:29.840 --> 00:13:32.440 Compile it 224 00:13:34.080 --> 00:13:38.230 Now make pistol we just created 225 00:13:38.230 --> 00:13:40.380 Into blueprint 226 00:13:40.380 --> 00:13:43.719 and place it via viewport on the world 227 00:13:43.719 --> 00:13:44.919 By placing it on viewport 228 00:13:44.919 --> 00:13:47.649 Make it available for us to grab the pistol 229 00:13:48.799 --> 00:13:51.899 For making SM_Pistol into blueprint 230 00:13:51.899 --> 00:13:55.350 Right click on Blueprints folder 231 00:13:56.520 --> 00:13:59.570 Right click on space of Blueprints folder under NetTPS 232 00:13:59.570 --> 00:14:03.939 Select Blueprint Class and choose Actor for parent 233 00:14:03.939 --> 00:14:08.530 and name it BP_Pistol 234 00:14:10.930 --> 00:14:14.080 Double click to open BP_Pistol 235 00:14:14.080 --> 00:14:20.180 Add SM_Pistol as root component here 236 00:14:20.180 --> 00:14:25.280 Press ctrl + space bar to open content drawer 237 00:14:25.280 --> 00:14:28.230 Then SM_Pistol inside of PistolMesh 238 00:14:28.230 --> 00:14:31.359 Drag and drop it 239 00:14:31.359 --> 00:14:34.009 Added as component 240 00:14:34.009 --> 00:14:38.059 Then select it again drag onto DefaultSceneRoot 241 00:14:38.059 --> 00:14:41.280 To make it as root component 242 00:14:41.280 --> 00:14:44.030 Now on the right side, if you're not holding the pistol 243 00:14:44.030 --> 00:14:46.430 It supposed to be on the ground, right? 244 00:14:46.430 --> 00:14:50.200 Therefore in order to apply it, on the right side 245 00:14:50.200 --> 00:14:55.600 On Details window, there is Simulate Physics under the Physics tab 246 00:14:55.600 --> 00:14:59.119 Check it to enable it 247 00:14:59.119 --> 00:15:03.419 When player run into this pistol, it's not supposed to be 248 00:15:03.419 --> 00:15:04.569 flown off or so 249 00:15:04.569 --> 00:15:08.119 So we're going to make it not collide with player 250 00:15:08.119 --> 00:15:11.669 There is Collision Presets below Collision tab 251 00:15:11.669 --> 00:15:13.669 If you open this Collision Presets 252 00:15:13.669 --> 00:15:17.559 You would see Pawn and everything is set as block 253 00:15:17.559 --> 00:15:20.209 So let's change it to custom 254 00:15:20.209 --> 00:15:22.909 Open dropdown menu on Collision Presets 255 00:15:22.909 --> 00:15:25.320 and change it to custom 256 00:15:25.320 --> 00:15:30.770 Change Visibility and Camera options 257 00:15:30.770 --> 00:15:32.870 Under the Trace Responses to Ignore 258 00:15:32.870 --> 00:15:35.080 Also set Pawn ignore 259 00:15:35.080 --> 00:15:37.180 So both Pawn and player 260 00:15:37.180 --> 00:15:39.180 Flying away when they collide with each other is 261 00:15:39.180 --> 00:15:41.919 Not going to happen 262 00:15:41.919 --> 00:15:46.369 Compile it and close BP_Pistol 263 00:15:46.369 --> 00:15:50.400 And place it on world 264 00:15:50.400 --> 00:15:54.850 Grab BP_Pistol and place it 265 00:15:54.850 --> 00:15:57.750 Then it is stick to the ground 266 00:15:57.750 --> 00:16:01.280 I'll put it little bit above so that it could be dropped when the game starts 267 00:16:01.280 --> 00:16:06.430 Copy and place one more somewhat distance away 268 00:16:06.430 --> 00:16:09.280 I'll make the number of players to 2 later 269 00:16:09.280 --> 00:16:13.680 Let's place like this since it's multiplayer 270 00:16:13.680 --> 00:16:18.239 Now if you press play then it would work normally 271 00:16:18.239 --> 00:16:24.520 If it is not set correctly on World Settings 272 00:16:24.520 --> 00:16:26.970 If your GameMode Override is not set correctly 273 00:16:26.970 --> 00:16:31.799 Select BP_NetTPSGameMode here 274 00:16:31.799 --> 00:16:35.699 Select BP_NetTPSGameMode as GameMode Override 275 00:16:35.699 --> 00:16:38.299 On World Settings 276 00:16:38.299 --> 00:16:41.239 Play again after setting then it would work normally 277 00:16:41.239 --> 00:16:45.639 Let's create action to pickup pistol 278 00:16:45.639 --> 00:16:50.039 For pickup action, if you go into Input, there is Actions 279 00:16:50.039 --> 00:16:53.239 Pickup pistol is going to be just pressing and not pressing 280 00:16:53.239 --> 00:16:56.089 Pickup button so it is similar to this Jump 281 00:16:56.089 --> 00:17:00.639 If you double click it, as you can see, Value Type is set to Digital 282 00:17:00.639 --> 00:17:03.119 Since it's bool, it will be pressing or not pressing 283 00:17:03.119 --> 00:17:05.719 Therefore I will copy this Jump 284 00:17:05.719 --> 00:17:07.560 and use it as it is 285 00:17:07.560 --> 00:17:10.310 Press ctrl + D after select IA_Jump 286 00:17:10.310 --> 00:17:12.160 to duplicate input action 287 00:17:12.160 --> 00:17:18.920 And name it as IA_TakePistol 288 00:17:18.920 --> 00:17:23.670 Then there is Input Mapping Context called IMC_Default 289 00:17:23.670 --> 00:17:25.880 Under the Inputs folder 290 00:17:25.880 --> 00:17:29.430 Double click to open it 291 00:17:29.430 --> 00:17:33.319 After open it by double click it 292 00:17:33.599 --> 00:17:36.899 Press add icon on Mappings 293 00:17:36.899 --> 00:17:39.549 Then a dropdown will be added 294 00:17:39.549 --> 00:17:44.439 Open it and select IA_TakePistol 295 00:17:44.439 --> 00:17:48.789 Then for key binding, there is keyboard icon 296 00:17:48.789 --> 00:17:52.599 Click it and press F on keyboard 297 00:17:52.599 --> 00:17:55.799 Press F to set it 298 00:17:55.799 --> 00:17:57.599 Now save it 299 00:17:57.599 --> 00:17:59.599 Then let's add it on code 300 00:17:59.599 --> 00:18:01.479 to make this input available 301 00:18:01.479 --> 00:18:03.879 Go to Visual Studio 302 00:18:03.879 --> 00:18:09.160 Go to the bottom of NetTPSCharacter.h file 303 00:18:09.160 --> 00:18:12.160 If you scroll above, you will find that inputs already has been declared 304 00:18:12.160 --> 00:18:13.610 In order to make it usable 305 00:18:13.610 --> 00:18:18.479 So I'll just copy and use it 306 00:18:18.479 --> 00:18:21.479 Press ctrl + C 307 00:18:23.199 --> 00:18:26.349 Scroll down to the bottom, set as public 308 00:18:26.349 --> 00:18:29.719 and paste what we just copied 309 00:18:29.719 --> 00:18:33.640 Then the name of variable is not LookAction 310 00:18:34.800 --> 00:18:39.000 But TakePistolAction 311 00:18:40.719 --> 00:18:46.640 Then let's add function to process this input below 312 00:18:46.640 --> 00:18:53.359 Choose either Move or Look and press ctrl + C 313 00:18:53.520 --> 00:18:55.870 Move down and paste it 314 00:18:55.870 --> 00:19:01.569 Name it as TakePistol 315 00:19:01.599 --> 00:19:05.749 This value will be what we want: pressed, not pressed 316 00:19:05.749 --> 00:19:11.199 Construct TakePistol 317 00:19:11.199 --> 00:19:14.099 on cpp file 318 00:19:14.099 --> 00:19:16.299 Added construction part like this 319 00:19:16.299 --> 00:19:20.600 Then we have to bind it in order to map this input 320 00:19:20.600 --> 00:19:22.550 onto input we actually set 321 00:19:22.550 --> 00:19:26.440 Add that part to SetupPlayerInputComponent function 322 00:19:27.920 --> 00:19:30.520 As you can see, we have jumping 323 00:19:30.520 --> 00:19:32.820 Also have looking 324 00:19:32.820 --> 00:19:36.800 Let me copy this looking 325 00:19:36.800 --> 00:19:41.750 And add TakePistolAction instead of LookAction 326 00:19:41.750 --> 00:19:45.319 Set it Started instead of Triggered 327 00:19:45.319 --> 00:19:48.119 So that the moment key is pressed, input occurs 328 00:19:48.119 --> 00:19:53.669 And add TakePistol function can be executed 329 00:19:53.669 --> 00:19:56.529 In accordance with this input, not LookAction 330 00:19:56.529 --> 00:19:57.279 Right? 331 00:19:57.279 --> 00:20:01.179 Now we made the part when the input comes in 332 00:20:01.179 --> 00:20:04.800 TakePistol function will be executed 333 00:20:04.800 --> 00:20:08.750 Now then let's work on few things in order to grab pistol 334 00:20:08.750 --> 00:20:11.479 How it would be processed 335 00:20:11.479 --> 00:20:15.879 If player doesn't possess pistol 336 00:20:15.879 --> 00:20:24.119 Then make it search and grab pistol within a certain range 337 00:20:24.599 --> 00:20:25.499 Right? 338 00:20:25.499 --> 00:20:27.649 Player does not supposed to grab another pistol while possess one 339 00:20:27.649 --> 00:20:30.049 So it's only when they don't possess pistol 340 00:20:30.049 --> 00:20:32.199 We placed two pistols in the world 341 00:20:32.199 --> 00:20:35.999 We will make them grab the nearest pistol 342 00:20:35.999 --> 00:20:41.439 According to this, we need some properties 343 00:20:41.439 --> 00:20:43.639 Some information 344 00:20:43.639 --> 00:20:47.570 Status whether possessing pistol or not 345 00:20:48.880 --> 00:20:50.080 Right? 346 00:20:50.080 --> 00:20:52.980 And they have to hold pistol 347 00:20:52.980 --> 00:20:56.130 So which pistol do they possess 348 00:20:56.130 --> 00:20:58.119 So that they can drop pistol later 349 00:20:58.119 --> 00:21:00.819 We need to process drop after grab 350 00:21:00.819 --> 00:21:05.079 Since we need to drop pistol, we need pistol they possess 351 00:21:05.079 --> 00:21:07.979 Move this above like this 352 00:21:07.979 --> 00:21:11.229 In order to make them grab pistol within certain range 353 00:21:11.229 --> 00:21:14.590 We need pistol search range as well 354 00:21:14.590 --> 00:21:19.590 So let's add these necessary properties first 355 00:21:19.590 --> 00:21:23.680 Move to NetTPSCharacter.h file 356 00:21:23.680 --> 00:21:28.160 Add properties right above the function 357 00:21:28.160 --> 00:21:34.640 Make bool bHasPistol for whether they possess pistol or not 358 00:21:34.640 --> 00:21:36.990 bHasPistol is false as initial state 359 00:21:36.990 --> 00:21:39.140 Make it like this 360 00:21:39.140 --> 00:21:43.760 Then we need pistol each player possess 361 00:21:43.760 --> 00:21:48.660 Since the possessed pistol by each player needs to be pointer 362 00:21:48.660 --> 00:21:49.920 Add UPROPERTY() 363 00:21:49.920 --> 00:21:57.760 Declare ownedPistol as Aactor pointer 364 00:21:57.760 --> 00:22:00.810 And set it as nullptr 365 00:22:00.810 --> 00:22:07.280 And we need pistol search range as property 366 00:22:08.079 --> 00:22:10.479 To make it available to be edited outside by planner 367 00:22:10.479 --> 00:22:15.199 Add UPROPERTY as EditAnywhere 368 00:22:15.199 --> 00:22:18.849 Set category as Gun 369 00:22:18.849 --> 00:22:26.719 Add float distanceToGun 370 00:22:26.719 --> 00:22:27.819 as 200 371 00:22:27.819 --> 00:22:29.819 as 2 meters 372 00:22:29.819 --> 00:22:34.079 Now we declared properties we need 373 00:22:35.365 --> 00:22:39.034 Come back to cpp and construct this 374 00:22:39.034 --> 00:22:42.184 Let's construct what needs to be done 375 00:22:42.184 --> 00:22:46.079 When players don't possess pistol 376 00:22:46.079 --> 00:22:49.979 Then will it work when they are holding pistol 377 00:22:49.979 --> 00:22:53.359 No, it won't 378 00:22:54.719 --> 00:23:00.619 Nothing works while possessing pistol 379 00:23:00.619 --> 00:23:02.400 They're not supposed to grab another 380 00:23:02.400 --> 00:23:07.950 So if bHasPistol is true then player is holding pistol 381 00:23:07.950 --> 00:23:12.079 So just return in order to process nothing 382 00:23:12.079 --> 00:23:15.379 This is what we implemented first 383 00:23:15.379 --> 00:23:19.920 Now write down below what we are going to process next 384 00:23:19.920 --> 00:23:22.220 What we want to process here is 385 00:23:22.220 --> 00:23:32.079 Examine all pistols in the world and grab the nearest one 386 00:23:32.079 --> 00:23:33.929 This is it, right? 387 00:23:33.929 --> 00:23:36.679 So we need to bring all pistols in the world 388 00:23:36.679 --> 00:23:39.839 Need to bring all of them to examine 389 00:23:39.839 --> 00:23:43.889 But keep searching and bring pistols 390 00:23:43.889 --> 00:23:45.280 Would not be good 391 00:23:45.280 --> 00:23:48.580 For performance, use cache method 392 00:23:48.580 --> 00:23:52.530 All pistols in the world needs to be examined 393 00:23:52.530 --> 00:23:56.490 To find pistols among the actors when spawn first 394 00:23:56.490 --> 00:24:00.920 Let's find pistols and assign them to variable 395 00:24:00.920 --> 00:24:07.400 Move to NetTPSCharacter.h file 396 00:24:07.400 --> 00:24:13.479 And remember pistols placed in the world 397 00:24:13.479 --> 00:24:20.280 Add UPROPERTY and assign pistols to TArray 398 00:24:20.280 --> 00:24:23.930 As the type of AActor pointer 399 00:24:23.930 --> 00:24:27.939 Name it pistolActors 400 00:24:27.940 --> 00:24:30.890 Then where they will be found 401 00:24:30.890 --> 00:24:34.160 Find them at BeginPlay 402 00:24:34.160 --> 00:24:38.260 Since this is the function which is called when starts 403 00:24:38.260 --> 00:24:42.280 So search pistols at the bottom of this 404 00:24:42.280 --> 00:24:44.780 Find pistols 405 00:24:44.780 --> 00:24:47.280 and assign them to pistolActors 406 00:24:47.280 --> 00:24:49.930 Assign all actors 407 00:24:49.930 --> 00:24:52.640 to here and bring first 408 00:24:52.640 --> 00:24:59.359 TArray for AActor, allActors 409 00:24:59.359 --> 00:25:01.409 Since we have to find pistol actors 410 00:25:01.409 --> 00:25:04.359 Among all actors in the world, so I made it like this 411 00:25:04.359 --> 00:25:14.239 There is GetAllActorsOfClass function in UGameplayStatics 412 00:25:14.239 --> 00:25:19.089 We are going to search actors at World 413 00:25:19.089 --> 00:25:21.719 Put StaticClass 414 00:25:21.719 --> 00:25:24.919 and put allActors where all found values 415 00:25:24.919 --> 00:25:28.199 will be assigned to 416 00:25:28.199 --> 00:25:32.499 Use for-statement and find Actors named pistol 417 00:25:32.499 --> 00:25:34.599 and assign it to PistolActors 418 00:25:34.599 --> 00:25:41.680 Put auto tempPistol : allActors into parentheses 419 00:25:41.680 --> 00:25:46.920 Then extract one by one from allActors through range search 420 00:25:46.920 --> 00:25:50.199 and put it into tempPistol one by one 421 00:25:50.199 --> 00:25:54.599 Then use if-statement and search name of tempPistol 422 00:25:54.599 --> 00:26:01.479 Use GetName and Contains function to check 423 00:26:01.479 --> 00:26:05.579 If it contains BP_Pistol 424 00:26:05.579 --> 00:26:10.509 Name of the pistol contains BP_Pistol 425 00:26:10.509 --> 00:26:16.159 If you check the names of BP_Pistol 426 00:26:16.159 --> 00:26:19.119 They are BP_Pistol and BP_Pistol2 427 00:26:19.119 --> 00:26:22.219 So the name changes everytime a pistol is added 428 00:26:22.219 --> 00:26:26.169 Therefore if the name contains the word BP_Pistol 429 00:26:26.169 --> 00:26:29.079 Then that is pistol 430 00:26:29.439 --> 00:26:32.739 Add tempPistol 431 00:26:32.739 --> 00:26:35.920 to pistolActors 432 00:26:35.920 --> 00:26:39.720 We don't have UGameplayStatics here so it's underlined with red 433 00:26:39.720 --> 00:26:43.399 So let me add a header above 434 00:26:44.719 --> 00:26:49.519 Include GameplayStatics.h which is under the Kismet 435 00:26:49.519 --> 00:26:52.959 at the top in order to add it 436 00:26:52.959 --> 00:26:53.759 Right? 437 00:26:53.759 --> 00:26:57.909 Then move back to TakePistol function 438 00:26:57.909 --> 00:27:00.209 Move back to TakePistol function 439 00:27:00.209 --> 00:27:02.159 Let's write a code to examine 440 00:27:02.159 --> 00:27:05.729 all pistols in the world and grab the nearest one 441 00:27:05.729 --> 00:27:10.029 Use for-statement, we have pistols that we memorized before 442 00:27:10.029 --> 00:27:12.729 Write auto pistolActor 443 00:27:12.729 --> 00:27:16.020 from pistolActors 444 00:27:16.820 --> 00:27:20.720 Extract on by one and assign them to pistolActor 445 00:27:20.720 --> 00:27:23.119 and process 446 00:27:24.000 --> 00:27:31.880 Before that, if the pistol has possessed by the other player 447 00:27:31.880 --> 00:27:33.530 The other player is already holding the pistol 448 00:27:33.530 --> 00:27:36.400 Then it cannot be taken away, right? 449 00:27:36.400 --> 00:27:39.900 If the pistol has an owner, don't examine 450 00:27:39.900 --> 00:27:41.760 Let's add this logic 451 00:27:41.760 --> 00:27:47.479 Use if-statement, pistolActor It's actor not actors 452 00:27:47.479 --> 00:27:50.829 Call GetOwner to examine 453 00:27:50.829 --> 00:27:53.359 Does it have an owner? 454 00:27:53.400 --> 00:27:55.900 which means it's not 'nullptr' 455 00:27:55.900 --> 00:27:58.650 Then it means it has an owner, so don't examine it 456 00:27:58.650 --> 00:28:02.359 Make it continue 457 00:28:02.359 --> 00:28:05.959 Alright, then if the pistol has passed this, 458 00:28:05.959 --> 00:28:12.520 Calculate the distance from the pistol and if it is within range, grab it 459 00:28:12.520 --> 00:28:15.170 Let's calculate the distance from the pistol first 460 00:28:15.170 --> 00:28:17.820 Declare float distance 461 00:28:17.820 --> 00:28:20.839 There is Dist function in FVector 462 00:28:20.839 --> 00:28:25.839 Put my current location, which is the actor's location 463 00:28:25.839 --> 00:28:30.439 and the location information of pistolActor 464 00:28:30.439 --> 00:28:36.000 Get both location to get the distance 465 00:28:36.000 --> 00:28:39.600 Use one more if-statement 466 00:28:39.600 --> 00:28:46.280 If the distance is within the range, we will take the pistol 467 00:28:46.280 --> 00:28:50.980 If the distance is out of the range, what should we do? 468 00:28:50.980 --> 00:28:53.199 Do we have to keep examining it? No 469 00:28:53.199 --> 00:28:56.399 So if it is out of the range, process not to examine it 470 00:28:56.399 --> 00:29:00.079 If the distance is out of the range, it has larger value 471 00:29:00.079 --> 00:29:05.879 If it is larger than distanceToGun, the range we can check 472 00:29:05.879 --> 00:29:09.379 No pistol is in the range, so continue 473 00:29:09.379 --> 00:29:12.599 Process not to examine the pistol 474 00:29:12.800 --> 00:29:14.900 Now the player grabbed the pistol 475 00:29:14.900 --> 00:29:21.119 Then we need to register the pistol as an owned one 476 00:29:21.119 --> 00:29:25.069 So write ownedPistol 477 00:29:25.069 --> 00:29:29.160 Assign pistolActor as the pistol owned by the player 478 00:29:29.160 --> 00:29:38.029 Then assign the player as the owner of the pistol 479 00:29:38.029 --> 00:29:39.429 It means that 480 00:29:39.429 --> 00:29:40.879 If you call SetOwner function 481 00:29:40.879 --> 00:29:45.479 from ownedPistol and write like this 482 00:29:45.479 --> 00:29:49.879 Then 'this' is assigned to owner 483 00:29:49.879 --> 00:29:53.560 The NetTPS character becomes the owner of the pistol 484 00:29:53.560 --> 00:29:55.660 Why is this so important? 485 00:29:55.660 --> 00:29:58.960 We examine whether the pistol has the owner or not up here 486 00:29:58.960 --> 00:30:01.400 So if the SetOwner function was called 487 00:30:01.400 --> 00:30:02.950 Then it has an owner already 488 00:30:02.950 --> 00:30:06.839 So the logic that does not examine will be activated 489 00:30:06.839 --> 00:30:10.239 So come back down, we set 'this' as the owner of the pistol 490 00:30:10.239 --> 00:30:13.479 Now the player is holding the pistol 491 00:30:13.479 --> 00:30:17.529 So we should change it to having pistol status 492 00:30:17.529 --> 00:30:20.920 Set bHasPistol to true 493 00:30:20.920 --> 00:30:25.119 Now that the player is holding the pistol, put break 494 00:30:25.119 --> 00:30:25.819 Alright? 495 00:30:25.819 --> 00:30:29.719 If the player finds a pistol within the range and if it doesn't have an owner 496 00:30:29.719 --> 00:30:34.079 Then the player grabs the pistol and registers him/herself as the owner 497 00:30:34.079 --> 00:30:37.829 We finished this part in TakePistol function 498 00:30:37.829 --> 00:30:42.880 Which means the owner has been registered 499 00:30:42.880 --> 00:30:47.430 Now we have to attach this pistol to the component 500 00:30:47.430 --> 00:30:50.439 So move to NetTPSCharacter.h file 501 00:30:50.439 --> 00:30:57.139 and add a function under TakePistol 502 00:30:57.139 --> 00:30:59.560 which attaches the pistol as component 503 00:30:59.560 --> 00:31:04.760 Put 'void', we will name it AttachPistol 504 00:31:04.760 --> 00:31:14.760 Put parameter as 'const AActor pointer pistolActor' and implement AttachPistol 505 00:31:14.839 --> 00:31:21.180 Then this implementation part is added at NetTPSCharacter.cpp 506 00:31:22.479 --> 00:31:29.779 Declare auto meshComp and call 507 00:31:29.779 --> 00:31:33.880 GetComponentByClass from pistolActor 508 00:31:33.880 --> 00:31:39.599 BP_Pistol is UStaticMesh 509 00:31:39.599 --> 00:31:46.030 So specify it as UStaticMeshComponent 510 00:31:46.030 --> 00:31:51.719 Then you can get static mesh component that contains SM_Pistol 511 00:31:51.719 --> 00:31:57.630 Now which one should we attach to this as parent component 512 00:31:57.630 --> 00:32:00.580 Use AttachToComponent 513 00:32:00.580 --> 00:32:04.959 Attach Gun Comp 514 00:32:04.959 --> 00:32:11.040 Write FAttachmentTransformRules as an attachment rule 515 00:32:11.040 --> 00:32:18.040 SnapToTargetNotIncludingScale 516 00:32:18.040 --> 00:32:22.479 to not include the size 517 00:32:22.599 --> 00:32:23.899 Right? 518 00:32:23.899 --> 00:32:28.439 The moment we grab the pistol, physics should not activate 519 00:32:28.439 --> 00:32:35.089 So put SetSimulatePhysics of meshComp 520 00:32:35.089 --> 00:32:38.839 to false so that the physics wouldn't work 521 00:32:38.839 --> 00:32:42.439 And this AttachPistol function's work is 522 00:32:42.439 --> 00:32:44.479 attaching this pistol to player's hands 523 00:32:44.479 --> 00:32:48.429 Now that we found it, when TakePistol was called 524 00:32:48.429 --> 00:32:50.199 We found even the owner 525 00:32:50.199 --> 00:32:53.719 So attaching it to hands should be done at the bottom 526 00:32:53.719 --> 00:32:57.419 So call AttachPistol with pistolActor that we have 527 00:32:57.419 --> 00:33:00.760 as parameter 528 00:33:00.760 --> 00:33:02.419 Now build it 529 00:33:06.109 --> 00:33:10.000 Play it and you can see this 'grabbing the pistol' animation 530 00:33:10.000 --> 00:33:15.760 So go to Animations folder and select ABP_Manny 531 00:33:15.760 --> 00:33:18.860 There would be Has Pistol on the right side of the Details window 532 00:33:18.860 --> 00:33:22.839 Uncheck Has Pistol at Anim Preview Editor 533 00:33:22.839 --> 00:33:28.839 Then click apply and compile Then go to BP_ThirdPersonCharacter 534 00:33:28.839 --> 00:33:31.839 There will be searching function on Details window 535 00:33:31.839 --> 00:33:34.489 Select Class Defaults 536 00:33:34.489 --> 00:33:39.359 and search input on Details window 537 00:33:39.359 --> 00:33:43.000 We didn't register anything on Take Pistol Action 538 00:33:43.000 --> 00:33:48.640 So open dropdown menu and select IA_TakePistol 539 00:33:48.640 --> 00:33:52.959 to apply input and the asset 540 00:33:52.959 --> 00:33:57.759 Compile, go back and play 541 00:33:57.759 --> 00:34:00.640 As you can see, the pistol is attached to the hand 542 00:34:00.640 --> 00:34:03.190 There is no animation working 543 00:34:03.190 --> 00:34:05.479 but you can see that the pistol is attached 544 00:34:05.479 --> 00:34:08.779 Then, we should apply animation 545 00:34:08.779 --> 00:34:14.159 There is NetPlayerAnimInstance.cpp at Visual Studio 546 00:34:14.159 --> 00:34:20.360 At the bottom of NativeUpdateAnimation, 547 00:34:20.360 --> 00:34:25.160 Update bHasPistol with the value of 548 00:34:25.160 --> 00:34:28.879 bHasPistol that we added to the player 549 00:34:28.879 --> 00:34:33.129 Build again and go back to unreal engine 550 00:34:33.129 --> 00:34:35.679 Play again and go grab the pistol 551 00:34:35.679 --> 00:34:40.879 If you press F, the character grabs the pistol 552 00:34:40.879 --> 00:34:44.719 That's it for the pistol grabbing animation 553 00:34:44.719 --> 00:34:47.760 Now, we will work on pistol releasing 554 00:34:47.760 --> 00:34:49.860 We need to assign input asset 555 00:34:49.860 --> 00:34:54.159 just like pistol grabbing 556 00:34:54.159 --> 00:35:00.409 So move to NetTPSCharacter.h file on Visual Studio 557 00:35:00.409 --> 00:35:04.000 and add input same as pistol grabbing 558 00:35:04.000 --> 00:35:07.400 There is TakePistolAction above 559 00:35:07.400 --> 00:35:13.400 Take it and paste it as public at the bottom 560 00:35:16.969 --> 00:35:22.159 and change the name to releaseAction 561 00:35:22.159 --> 00:35:28.609 For pistol releasing function, copy TakePistol above 562 00:35:28.609 --> 00:35:35.199 and paste it as processing pistol releasing function 563 00:35:35.199 --> 00:35:38.959 and the name is ReleasePistol instead of TakePistol 564 00:35:38.959 --> 00:35:42.239 ReleasePistol 565 00:35:42.239 --> 00:35:45.040 Then add implementation 566 00:35:45.040 --> 00:35:51.280 The implementation part is added to NetTPSCharacter.cpp 567 00:35:51.280 --> 00:35:55.439 Go to the bottom of SetupPlayerInputComponent 568 00:35:55.439 --> 00:35:57.089 You see this TakePistol part 569 00:35:57.089 --> 00:35:59.839 Press ctrl + D to copy 570 00:35:59.839 --> 00:36:05.840 Change from takePistolAction to releaseAction 571 00:36:05.919 --> 00:36:08.220 Put releaseAction 572 00:36:10.600 --> 00:36:17.199 and put ReleasePistol as a binding function 573 00:36:17.320 --> 00:36:22.239 We binded both input of releaseAction and ReleasePistol 574 00:36:22.239 --> 00:36:24.589 Then go to ReleasePistol 575 00:36:24.589 --> 00:36:27.600 and add the implementation part 576 00:36:27.600 --> 00:36:30.050 It's same as TakePistol 577 00:36:30.050 --> 00:36:33.679 We have to release the pistol that we are holding now 578 00:36:33.679 --> 00:36:39.040 So what if we are not holding a pistol? 579 00:36:39.040 --> 00:36:41.890 Should we process this ReleasePistol input? 580 00:36:41.890 --> 00:36:42.959 We shouldn't 581 00:36:42.959 --> 00:36:45.909 Should we process the input if we are holding the pistol? 582 00:36:45.909 --> 00:36:47.679 No, we shouldn't 583 00:36:47.679 --> 00:36:51.229 So if we are holding the pistol 584 00:36:51.229 --> 00:36:54.010 Then we process nothing 585 00:36:56.159 --> 00:36:59.059 So use if-statement 586 00:36:59.059 --> 00:37:00.479 If it's not bHasPistol 587 00:37:00.479 --> 00:37:02.779 that is if we are not holding the pistol, 588 00:37:02.779 --> 00:37:04.800 return and process nothing 589 00:37:04.800 --> 00:37:09.400 Then, if we are holding the pistol 590 00:37:09.400 --> 00:37:14.159 We should process about not holding the pistol 591 00:37:14.159 --> 00:37:18.559 So use if-statement and we made ownedPistol already 592 00:37:18.559 --> 00:37:20.800 If ownedPistol is not nullptr, 593 00:37:20.879 --> 00:37:23.229 there would be some value in it 594 00:37:23.229 --> 00:37:25.679 Let's put it like this 595 00:37:25.679 --> 00:37:30.560 Then, we have to set it as not owned 596 00:37:30.560 --> 00:37:36.639 bHasPistol let us know that it doesn't have a pistol anymore 597 00:37:39.439 --> 00:37:45.679 and for ownedPistol, SetOwner 598 00:37:45.679 --> 00:37:48.320 I'll put nullptr 599 00:37:48.320 --> 00:37:51.840 So it's saying that it doesn't possess anything 600 00:37:51.840 --> 00:37:55.140 And this part which has value in it 601 00:37:55.140 --> 00:37:59.120 Make it nullptr so that it doesn't have anything 602 00:37:59.120 --> 00:38:02.120 Then this pistol still is attached to my hand 603 00:38:02.120 --> 00:38:06.420 So let's make a function to implement 604 00:38:06.420 --> 00:38:08.719 releasing the pistol from my hands 605 00:38:08.719 --> 00:38:11.819 Move to NetTPSCharacter.h file 606 00:38:12.769 --> 00:38:19.199 and make a function to detach the pistol from the component 607 00:38:19.199 --> 00:38:25.840 Let's say void DetachPistol 608 00:38:25.840 --> 00:38:28.790 Put const AActor pointer 609 00:38:28.790 --> 00:38:32.399 pistolActor as parameter 610 00:38:32.399 --> 00:38:35.120 Now create the implementation part 611 00:38:35.120 --> 00:38:39.870 Move to NetTPSCharacter.cpp 612 00:38:39.870 --> 00:38:43.439 and write pistol detaching things here 613 00:38:43.439 --> 00:38:46.989 It's also same as AttachPistol 614 00:38:46.989 --> 00:38:49.520 A component is supposed to be detached 615 00:38:49.520 --> 00:38:52.720 Get auto meshComp 616 00:38:52.720 --> 00:38:56.320 This is a pistol and I will get 617 00:38:56.399 --> 00:38:58.249 StaticMeshComponent from BP_Pistol 618 00:38:58.249 --> 00:39:04.320 So call getComponentByClass from pistolActor 619 00:39:04.320 --> 00:39:09.539 to get UStaticMeshComponent 620 00:39:10.879 --> 00:39:14.479 and MeshComponent has Physics 621 00:39:14.479 --> 00:39:18.290 Call SetSimulatePhysics 622 00:39:19.199 --> 00:39:21.999 The pistol needs to be dropped to the ground 623 00:39:21.999 --> 00:39:23.840 So set it true 624 00:39:23.840 --> 00:39:29.240 Then to able to detach the gun component 625 00:39:29.240 --> 00:39:33.439 call DetachComponent 626 00:39:33.439 --> 00:39:36.599 No, DetachFromComponent 627 00:39:37.760 --> 00:39:39.560 Put this function 628 00:39:39.560 --> 00:39:44.479 There is FDetachmentRules 629 00:39:44.479 --> 00:39:51.600 And write KeepRelativeTransform 630 00:39:51.600 --> 00:39:54.250 Then DetachPistol, a function that detaches the pistol 631 00:39:54.250 --> 00:39:58.000 is being implemented, right above this 632 00:39:58.000 --> 00:39:59.350 There is ReleasePistol 633 00:39:59.350 --> 00:40:02.850 When we make it not owned, even before handling the nullptr 634 00:40:02.850 --> 00:40:06.239 We have to detach ownedPistol 635 00:40:06.239 --> 00:40:09.439 So we detach the pistol here 636 00:40:09.439 --> 00:40:11.760 Detaching the pistol 637 00:40:11.760 --> 00:40:16.399 Call DetachPistol and put ownedPistol 638 00:40:16.399 --> 00:40:18.699 Then the pistol will be detached from player's hands 639 00:40:18.699 --> 00:40:21.210 Now, build it 640 00:40:26.320 --> 00:40:31.020 Go to unreal engine, then go to Actions in the Input folder 641 00:40:31.020 --> 00:40:35.199 Press ctrl + D to duplicate IA_TakePistol 642 00:40:35.280 --> 00:40:41.360 Name it IA_ReleasePistol this time 643 00:40:41.679 --> 00:40:45.529 It's IA_ReleasePistol 644 00:40:45.529 --> 00:40:49.040 Then move to Input folder 645 00:40:49.040 --> 00:40:52.290 and open IMC_Default 646 00:40:52.290 --> 00:40:56.000 Click plus icon on Mappings 647 00:40:56.000 --> 00:40:59.840 to add IA_ReleasePistol 648 00:40:59.919 --> 00:41:04.019 Set Z with a key 649 00:41:04.019 --> 00:41:05.919 Save it 650 00:41:05.919 --> 00:41:09.319 and then move to BP_ThirdPersonCharacter 651 00:41:09.319 --> 00:41:11.919 There is Release Actions under the Input tab 652 00:41:11.919 --> 00:41:17.280 Assign IA_ReleasePistol like this 653 00:41:17.280 --> 00:41:23.480 Compile it and go back and grab the pistol 654 00:41:23.480 --> 00:41:25.360 Then press Z 655 00:41:25.360 --> 00:41:29.960 Then the pistol is dropped, grab again and press Z 656 00:41:29.960 --> 00:41:32.443 That's it for pistol releasing 657 00:41:32.443 --> 00:41:36.144 Pistol shooting 658 00:41:36.719 --> 00:41:38.919 Let's continue with the pistol shooting 659 00:41:38.919 --> 00:41:42.399 Since shooting needs input as well 660 00:41:42.399 --> 00:41:45.549 Move to NetTPSCharacter.h file 661 00:41:45.549 --> 00:41:47.280 and add relevant content 662 00:41:47.280 --> 00:41:50.730 Let's take the input from public 663 00:41:50.730 --> 00:41:55.760 to action and releasing input process function 664 00:41:55.760 --> 00:41:58.460 and paste it 665 00:41:58.460 --> 00:42:02.910 Change releaseAction to fireAction 666 00:42:05.919 --> 00:42:11.269 Also, change ReleasePistol to Fire 667 00:42:11.269 --> 00:42:17.699 Put this implementation to cpp like this 668 00:42:17.699 --> 00:42:22.560 Bind fire input with processing function as well 669 00:42:22.560 --> 00:42:25.510 So put fireAction 670 00:42:25.510 --> 00:42:30.479 In SetupPlayerInputComponent, 671 00:42:30.479 --> 00:42:34.179 Put Fire instead of ReleasePistol 672 00:42:34.179 --> 00:42:38.560 Add the implementation part to this function 673 00:42:38.560 --> 00:42:41.910 First, this has to be processed while holding the pistol 674 00:42:41.910 --> 00:42:48.280 So if we are not holding the pistol, don't process 675 00:42:48.280 --> 00:42:53.030 If bHasPistol is false 676 00:42:53.030 --> 00:42:56.479 Then we are not holding the pistol so return and don't process 677 00:42:56.479 --> 00:43:02.639 Let's implement pistol shooting below this 678 00:43:02.650 --> 00:43:06.639 with LineTrace that Unreal Engine provides 679 00:43:06.639 --> 00:43:13.789 FHitResult is the type to save the result of collision 680 00:43:13.789 --> 00:43:18.159 Make variable hitInfo, type of FHitResult 681 00:43:18.159 --> 00:43:22.459 LineTrace connects two dots to make a line, right? 682 00:43:22.459 --> 00:43:26.459 Because we are trying to get the result of collision of lines, 683 00:43:26.459 --> 00:43:27.919 We need two dots 684 00:43:27.919 --> 00:43:34.159 startPos, type of FVector 685 00:43:34.159 --> 00:43:38.109 This will be on camera, towards where camera is facing at 686 00:43:38.109 --> 00:43:44.140 So execute GetComponentLocation from FollowCamera, 687 00:43:47.040 --> 00:43:48.890 like this 688 00:43:48.890 --> 00:43:51.240 Now, the camera is attached 689 00:43:51.240 --> 00:43:54.520 The camera is attached to the player 690 00:43:54.520 --> 00:43:57.420 From the location of the camera towards where the camera is facing 691 00:43:57.420 --> 00:44:00.840 We'll shoot right in the center 692 00:44:00.840 --> 00:44:03.940 endPos, type of FVector 693 00:44:03.940 --> 00:44:07.290 The direction camera is facing from StartPos 694 00:44:07.290 --> 00:44:12.800 Execute GetForwardVector where FollowCamera is facing 695 00:44:12.800 --> 00:44:14.700 We'll shoot just 100 meters 696 00:44:14.700 --> 00:44:17.159 So write down 10000 like this 697 00:44:17.159 --> 00:44:20.759 Since the pistol mustn't shoot the shooter itself, 698 00:44:20.759 --> 00:44:26.639 there is FCollisionQueryParams in the condition of collision 699 00:44:26.639 --> 00:44:32.839 Let's use AddIgnoreActor to register itself through params 700 00:44:32.839 --> 00:44:37.320 so that I can't shoot myself 701 00:44:37.919 --> 00:44:42.080 Now let's add some part that we actually shoot, which is LineTrace 702 00:44:42.080 --> 00:44:46.280 To detect whether it is hit by LineTrace or not, 703 00:44:46.280 --> 00:44:50.120 add variable bHit, type of bool 704 00:44:50.120 --> 00:44:58.199 Execute GetWorld and LineTraceSingleByChannel 705 00:44:58.199 --> 00:45:01.549 Put hitInfo where collision information will be saved 706 00:45:01.549 --> 00:45:07.409 Put two dots, startPos and endPos 707 00:45:08.639 --> 00:45:12.589 Put this into trace channel input 708 00:45:12.589 --> 00:45:16.280 to process everything that can be seen into collision 709 00:45:16.280 --> 00:45:19.330 And finally params 710 00:45:19.330 --> 00:45:23.520 not to shoot myself 711 00:45:23.520 --> 00:45:29.820 And if bHit is true, then let's process 712 00:45:29.820 --> 00:45:33.600 so that we can mark particles where it is hit 713 00:45:33.600 --> 00:45:38.600 Then declare marking particles as member 714 00:45:38.600 --> 00:45:44.690 Let's write below Fire function on NetTPSCharacter.h 715 00:45:44.690 --> 00:45:48.239 Let's add shot particle 716 00:45:48.239 --> 00:45:52.760 Add UPROPERTY with EditDefaultOnly 717 00:45:52.760 --> 00:45:56.590 Put category as Gun 718 00:45:57.600 --> 00:46:05.120 Then UParticleSystem type class 719 00:46:05.120 --> 00:46:09.110 with the name of gunEffect 720 00:46:10.139 --> 00:46:14.189 Right? Then we just play this gunEffect 721 00:46:14.189 --> 00:46:16.320 Go back to cpp 722 00:46:16.320 --> 00:46:21.800 To mark shot particle, we can use SpawnEmitterAtLocation 723 00:46:21.800 --> 00:46:24.650 from UGameplayStatics 724 00:46:24.650 --> 00:46:29.000 Put GetWorld so that we can put the particle in the right place 725 00:46:29.000 --> 00:46:33.560 gunEffect and location from hitInfo 726 00:46:33.560 --> 00:46:35.760 We can see the spot shot by the bullet 727 00:46:35.760 --> 00:46:41.719 Put default value of FRotator function 728 00:46:41.719 --> 00:46:45.459 Write down true then build it 729 00:46:47.239 --> 00:46:53.120 Now, go back to unreal engine, BP_ThirdPersonCharacter 730 00:46:53.120 --> 00:46:55.170 It's already set to Class Defaults 731 00:46:55.170 --> 00:46:59.600 We have to assign input to Fire Action first 732 00:46:59.600 --> 00:47:02.500 But let me add Gun Effect first 733 00:47:02.500 --> 00:47:06.600 Type gun effect to get Gun Effect 734 00:47:06.600 --> 00:47:12.040 Click dropdown to assign P_Explosion 735 00:47:12.040 --> 00:47:15.340 Assign P_Explosion to make the hit spot stand out 736 00:47:15.340 --> 00:47:17.239 like an explosion effect 737 00:47:17.239 --> 00:47:21.270 Then let me add gun input here 738 00:47:22.719 --> 00:47:28.119 Go to Actions and select IA_TakePistol as well 739 00:47:28.119 --> 00:47:30.679 Press ctrl + D to duplicate 740 00:47:30.679 --> 00:47:35.760 Put IA_Fire 741 00:47:35.760 --> 00:47:38.510 IA_Fire 742 00:47:38.510 --> 00:47:42.159 Go to Inputs then IMC_Defaults 743 00:47:42.159 --> 00:47:44.009 Add another mapping 744 00:47:44.009 --> 00:47:47.869 which is IA_Fire this time 745 00:47:49.080 --> 00:47:53.480 Click keybord icon and register left click 746 00:47:53.480 --> 00:47:58.040 Click here to bind left mouse button 747 00:47:58.040 --> 00:48:02.740 Save it and go to BP_ThirdPersonCharacter 748 00:48:02.740 --> 00:48:05.439 Search input 749 00:48:05.439 --> 00:48:10.199 Assign IA_Fire to Fire Action 750 00:48:10.199 --> 00:48:11.349 Alright? 751 00:48:11.349 --> 00:48:15.439 I think there is something wrong with the codes 752 00:48:15.439 --> 00:48:20.339 In Fire function, it says startPos '=' 753 00:48:20.339 --> 00:48:23.920 We have to change it to '+' 754 00:48:23.920 --> 00:48:29.439 so that it can make arrow from this location to this direction 755 00:48:29.439 --> 00:48:32.339 Right? There was a typo 756 00:48:32.339 --> 00:48:35.719 Change it to '+' and build it again 757 00:48:37.040 --> 00:48:41.740 Alright, go back and play to execute 758 00:48:41.740 --> 00:48:45.159 You can see it's working well 759 00:48:45.159 --> 00:48:46.809 But the animation is not working 760 00:48:46.809 --> 00:48:50.359 So this time let's add an animation 761 00:48:50.359 --> 00:48:52.840 so that it works when you shoot 762 00:48:52.840 --> 00:48:56.890 Go to Animations folder and search fire 763 00:48:56.890 --> 00:48:59.869 We got three results, and among these 764 00:48:59.869 --> 00:49:04.069 There is MM_Pistol_Fire, right? 765 00:49:04.069 --> 00:49:07.439 Click right side of the mouse 766 00:49:07.439 --> 00:49:10.789 Hover cursor on Create 767 00:49:10.789 --> 00:49:13.489 Select Create AnimMontage 768 00:49:13.489 --> 00:49:15.760 Make it to montage and play it 769 00:49:15.760 --> 00:49:20.719 I'll just use the name created automatically 770 00:49:20.719 --> 00:49:25.270 Double click to open the montage file 771 00:49:26.320 --> 00:49:27.920 Let's add slots 772 00:49:27.920 --> 00:49:33.000 There will be an anim slot window on the Window menu 773 00:49:33.000 --> 00:49:35.400 Anim Slot Manager 774 00:49:35.400 --> 00:49:37.250 It sticks to the bottom right corner 775 00:49:37.250 --> 00:49:39.840 Then, there is an add slot button 776 00:49:39.840 --> 00:49:43.340 Click it and type FireSlot 777 00:49:43.340 --> 00:49:46.439 as the New Slot Name 778 00:49:46.439 --> 00:49:50.479 Then we get FireSlot 779 00:49:50.479 --> 00:49:55.129 And then on the left side, the default slot is selected 780 00:49:55.129 --> 00:49:58.839 Click slot button and go to Slot name then you can find FireSlot 781 00:49:58.839 --> 00:50:02.839 it's second one from bottom and select it 782 00:50:02.839 --> 00:50:07.479 Then this montage is processed to be able to play on Fire Slot 783 00:50:07.479 --> 00:50:12.279 it's now moving but close and reopen it 784 00:50:12.279 --> 00:50:16.139 Then you can see it working normally 785 00:50:17.159 --> 00:50:22.919 Let's edit the animation little bit 786 00:50:22.919 --> 00:50:24.869 You see, there is ABP_Manny 787 00:50:24.869 --> 00:50:26.869 Double click to open it 788 00:50:26.869 --> 00:50:30.919 I will edit this Main States part 789 00:50:30.919 --> 00:50:34.569 Bring Main States to this place 790 00:50:34.569 --> 00:50:37.239 Make cache from this and use it 791 00:50:37.239 --> 00:50:42.940 So if you type cache you can see New Save cached pose at the bottom 792 00:50:44.080 --> 00:50:50.290 Change its name to MainCache 793 00:50:50.290 --> 00:50:53.290 The top should be shooting and the bottom should be running 794 00:50:53.290 --> 00:50:55.439 These two needs to be mixed 795 00:50:55.439 --> 00:51:02.120 So add Layered blend per bone node here 796 00:51:02.120 --> 00:51:06.620 Add Layered blend per bone node like this 797 00:51:06.620 --> 00:51:10.520 Basically for MainCache to be able to be put into Base Pose 798 00:51:10.520 --> 00:51:12.199 Click on the right side of the mouse 799 00:51:12.199 --> 00:51:16.549 and search main cache then you'll see Use cached pose MainCache 800 00:51:16.549 --> 00:51:20.689 Select it and connect to Base Pose 801 00:51:22.760 --> 00:51:24.760 Then for Blend Poses 0 802 00:51:24.760 --> 00:51:27.360 Value from montage if it exists 803 00:51:27.360 --> 00:51:30.280 Otherwise, take the value of MainCache itself 804 00:51:30.280 --> 00:51:35.420 Select MainCache and press ctrl + C and paste it 805 00:51:36.760 --> 00:51:40.560 Here, we need our fire montage 806 00:51:40.560 --> 00:51:45.000 So if you search default slot, you'll find this 807 00:51:45.000 --> 00:51:49.479 Add this node in Montage 808 00:51:49.560 --> 00:51:53.810 So connect MainCache to Default Slot 809 00:51:53.810 --> 00:51:57.280 And the thing we want to use is Fire Slot 810 00:51:57.280 --> 00:52:00.880 Select Default Slot and open Slot Name on the right side 811 00:52:00.880 --> 00:52:04.479 Select Fire Slot, second one from the bottom 812 00:52:04.479 --> 00:52:06.979 and put it like this to look organized 813 00:52:06.979 --> 00:52:10.479 There is one more default slot from the beginning 814 00:52:10.479 --> 00:52:14.879 Press ctrl + X to cut 815 00:52:14.879 --> 00:52:19.520 and paste it here 816 00:52:19.520 --> 00:52:23.320 Connect them like this 817 00:52:23.320 --> 00:52:27.159 Save the output as cache again 818 00:52:27.159 --> 00:52:31.159 The output from here 819 00:52:31.159 --> 00:52:35.959 There is New Save cached pose, select it 820 00:52:35.959 --> 00:52:40.899 And just name it as PistolCache 821 00:52:41.679 --> 00:52:47.929 Right? Shooting for upper body and running for lower body 822 00:52:47.929 --> 00:52:49.929 These two has to be mixed 823 00:52:49.929 --> 00:52:55.940 Select Layered blend per bone node and go to the right side 824 00:52:55.959 --> 00:52:57.959 There is index under Layer Setup 825 00:52:57.959 --> 00:52:59.759 Click plus icon 826 00:52:59.759 --> 00:53:01.360 Then one more of it is added 827 00:53:01.360 --> 00:53:07.879 Then name it as spine_03 828 00:53:07.879 --> 00:53:11.919 If you go to the skeleton 829 00:53:12.199 --> 00:53:16.899 You can see that the middle one is called spine_03 830 00:53:16.899 --> 00:53:20.879 We took the name of bone and used it as it is 831 00:53:21.840 --> 00:53:26.190 So write down spine_03 like this 832 00:53:26.190 --> 00:53:27.490 Alright 833 00:53:27.490 --> 00:53:30.140 Now, move to the right, the value that goes into Control Rig 834 00:53:30.140 --> 00:53:31.439 will be changed like this 835 00:53:31.439 --> 00:53:35.839 Execute PistolCache while holding the pistol 836 00:53:35.839 --> 00:53:39.189 Otherwise, execute normal MainCache as it is 837 00:53:39.189 --> 00:53:41.000 Let me add it here 838 00:53:41.000 --> 00:53:43.309 Click right on here 839 00:53:43.309 --> 00:53:48.609 and search blend poses by bool 840 00:53:48.609 --> 00:53:51.080 and add this node 841 00:53:51.080 --> 00:53:54.080 Blend Poses by bool 842 00:53:54.080 --> 00:53:59.080 Connect this output to the source 843 00:53:59.080 --> 00:54:03.580 In order to put PistolCache into True Pose 844 00:54:03.580 --> 00:54:09.879 Select PistolCache and connect 845 00:54:09.879 --> 00:54:15.229 And for False Pose, connect MainCache 846 00:54:16.040 --> 00:54:19.140 to it 847 00:54:19.140 --> 00:54:23.590 and this switching value needs to be in here 848 00:54:23.590 --> 00:54:27.439 For this Active Value, My Anim Settings under the VARIABLES 849 00:54:27.439 --> 00:54:29.789 If you open it, there would be Has Pistol 850 00:54:29.789 --> 00:54:34.239 Drag and drop it to Active Value to connect 851 00:54:34.239 --> 00:54:37.789 Then these two will be swithed in accordance with this 852 00:54:37.789 --> 00:54:39.360 Compile it 853 00:54:39.360 --> 00:54:41.960 In order to execute the shooting animation 854 00:54:41.960 --> 00:54:47.800 Go to NetPlayerAnimInstance.h file on Visual Studio 855 00:54:47.800 --> 00:54:53.300 Add details about the shooting animation at the bottom 856 00:54:53.300 --> 00:54:58.560 Montage used for shooting 857 00:54:58.560 --> 00:55:00.260 add UPROPERTY 858 00:55:00.260 --> 00:55:06.239 Put EditDefaultOnly and the category as Anim 859 00:55:06.239 --> 00:55:11.159 Declare class type of UAnimMontage 860 00:55:11.639 --> 00:55:14.939 Write fireMontage 861 00:55:14.939 --> 00:55:17.989 Then shooting animation 862 00:55:17.989 --> 00:55:20.600 Animation play function 863 00:55:20.600 --> 00:55:25.350 Add shooting animation play function 864 00:55:25.350 --> 00:55:30.760 Add void PlayFireAnimation 865 00:55:30.760 --> 00:55:36.410 Then add PlayFireAnimation implementation 866 00:55:36.410 --> 00:55:38.520 on NetPlayerAnimInstance.cpp 867 00:55:38.520 --> 00:55:40.920 First, the player needs to have a pistol 868 00:55:40.920 --> 00:55:43.370 Pistol ownership, right? 869 00:55:43.370 --> 00:55:47.479 And we need montage 870 00:55:48.439 --> 00:55:52.539 If bHasPistol is true 871 00:55:52.539 --> 00:55:55.919 and have fireMontage 872 00:55:55.919 --> 00:56:01.119 Execute Montage_play 873 00:56:01.119 --> 00:56:05.000 Put fireMontage, which is what we want to play 874 00:56:05.000 --> 00:56:08.550 and make it twice faster 875 00:56:08.550 --> 00:56:11.760 Then we need to call this PlayFireAnimation 876 00:56:11.760 --> 00:56:14.310 from NetTpsCharacter 877 00:56:14.310 --> 00:56:18.120 So go to the bottom of Fire 878 00:56:18.120 --> 00:56:20.570 on NetTPSCharacter.cpp 879 00:56:20.570 --> 00:56:23.270 Right below the if-statement, 880 00:56:23.270 --> 00:56:27.520 We'll write the code for the animation play 881 00:56:27.520 --> 00:56:34.860 Declare auto anim 882 00:56:34.910 --> 00:56:38.239 Cast UNetPlayerAnimInstance 883 00:56:38.239 --> 00:56:45.479 Execute GetAnimInstance from GetMesh 884 00:56:45.479 --> 00:56:49.429 Then call PlayFireAnimation 885 00:56:49.429 --> 00:56:51.239 from this anim like this 886 00:56:51.239 --> 00:56:54.989 Add header for UNetPlayerAnimInstance 887 00:56:54.989 --> 00:56:58.890 Include NetPlayerAnimInstance.h to add it 888 00:57:00.040 --> 00:57:05.239 And then build it 889 00:57:05.919 --> 00:57:08.019 Select Class Defaults 890 00:57:08.019 --> 00:57:12.439 On the right side, we should assign Fire Montage 891 00:57:13.000 --> 00:57:16.300 Select MM_Pistol_Fire_Montage 892 00:57:16.300 --> 00:57:18.300 Click Compile 893 00:57:18.300 --> 00:57:21.159 Now let's go and play 894 00:57:21.159 --> 00:57:24.909 Grab the pistol and shoot 895 00:57:24.909 --> 00:57:26.679 There is a problem when shooting horizontally 896 00:57:26.679 --> 00:57:29.229 Let's edit this 897 00:57:29.229 --> 00:57:36.120 Go to ABP_Manny, you'll see Layered blend per bone 898 00:57:36.120 --> 00:57:37.820 On the right side, 899 00:57:37.820 --> 00:57:41.520 There is an option called Mesh Space Rotation Blend 900 00:57:41.520 --> 00:57:44.420 Check it and compile 901 00:57:44.420 --> 00:57:47.040 Go back and play again 902 00:57:47.040 --> 00:57:50.490 Let's shoot again, it works well 903 00:57:50.490 --> 00:57:54.600 But shooting while running looks weird 904 00:57:54.600 --> 00:57:58.050 This is because when the animations blend, 905 00:57:58.050 --> 00:58:00.400 The switching speed gets too slow 906 00:58:00.400 --> 00:58:03.479 So in order to edit this, 907 00:58:03.479 --> 00:58:06.829 there is Fire Montage that we are using now 908 00:58:06.829 --> 00:58:08.979 Go to Animations folder and search 909 00:58:08.979 --> 00:58:13.760 Double click MM_Pistol_Fire_Montage 910 00:58:13.760 --> 00:58:17.510 There is Blend Time option at Asset Details on the left side 911 00:58:17.510 --> 00:58:20.120 There are Blend In and Out 912 00:58:20.120 --> 00:58:22.320 Both of them are set to 0.25 913 00:58:22.320 --> 00:58:25.970 Change them to 0.05 914 00:58:25.970 --> 00:58:28.199 0.05 for Blend Out 915 00:58:28.199 --> 00:58:33.760 Now save it and go back to play 916 00:58:33.760 --> 00:58:36.260 Grab the pistol and shoot 917 00:58:36.260 --> 00:58:41.520 As you can see, shooting while running works well now 918 00:58:41.520 --> 00:58:45.170 But we can see that 919 00:58:45.170 --> 00:58:47.320 no matter where you are aiming, both upward and downward 920 00:58:47.320 --> 00:58:50.879 Rotation values are being reflected 921 00:58:50.879 --> 00:58:54.379 So let's apply these values 922 00:58:54.379 --> 00:58:58.329 Go to NetPlayerAnimInstance.h file on Visual Studio 923 00:58:58.329 --> 00:59:01.479 Make it able to save the pitch 924 00:59:01.479 --> 00:59:07.689 So add a variable that saves the value of rotation 925 00:59:07.689 --> 00:59:12.239 Add UPROPERTY and EditAnywhere 926 00:59:12.239 --> 00:59:14.959 and BlurprintReadWrite 927 00:59:14.959 --> 00:59:22.280 Then put Category as MyAnimSettings 928 00:59:22.280 --> 00:59:24.680 just as same as we did above 929 00:59:24.680 --> 00:59:29.679 Declare float pitchAngles 930 00:59:29.679 --> 00:59:31.529 No, just Angle 931 00:59:31.529 --> 00:59:36.879 We'll move the place where this pitchAngle should be saved 932 00:59:36.879 --> 00:59:40.429 to NetPlayerAnimInstance.cpp 933 00:59:40.429 --> 00:59:44.639 and add to NativeUpdateAnimation function 934 00:59:44.639 --> 00:59:50.360 Let's add it here 935 00:59:50.360 --> 00:59:57.079 Let's process in order to reflect the rotation value 936 00:59:57.079 --> 01:00:04.639 The value of pitchAngle, there is 937 01:00:04.639 --> 01:00:09.439 GetBaseAnimRotation from minus player 938 01:00:09.520 --> 01:00:11.370 Here 939 01:00:11.370 --> 01:00:15.080 It's not Anim, it's Aim 940 01:00:15.080 --> 01:00:19.480 GetBaseAimRotation, we can get the aiming rotation value 941 01:00:19.480 --> 01:00:22.600 If we use it as it is, then it would be between 0 and 360 degrees 942 01:00:22.600 --> 01:00:27.050 But we need it to be from minus to plus rotation value 943 01:00:27.050 --> 01:00:33.129 So we won't use this, let's add .GetNormalized 944 01:00:33.129 --> 01:00:36.800 Then it would give us values ranging from -180 to +180 945 01:00:36.800 --> 01:00:41.350 Apply rotation value pitch to this value here 946 01:00:41.350 --> 01:00:42.900 Pitch is a vertical value 947 01:00:42.900 --> 01:00:47.000 We added minus because the value of rotation is reversed 948 01:00:47.000 --> 01:00:57.080 There is Clamp from FMathf 949 01:00:57.080 --> 01:01:01.939 Use it to trim pitchAngle 950 01:01:01.939 --> 01:01:05.139 from -60 to +60 before using it 951 01:01:05.139 --> 01:01:07.479 Then build again 952 01:01:07.479 --> 01:01:09.329 in order to save this value, 953 01:01:09.329 --> 01:01:13.399 Go to ABP_Manny 954 01:01:13.399 --> 01:01:16.899 There is Blend Poses by bool 955 01:01:16.899 --> 01:01:21.159 Before that, when the player has a pistol 956 01:01:21.159 --> 01:01:24.209 make sure it could be rotated up and down 957 01:01:24.209 --> 01:01:25.909 while the player is holding it 958 01:01:25.909 --> 01:01:31.000 So move this part a bit to the side 959 01:01:31.000 --> 01:01:35.950 Before the node using PistolCache 960 01:01:35.950 --> 01:01:38.719 I'll make the value of pitch is applied 961 01:01:38.719 --> 01:01:40.619 Let me cut this first 962 01:01:40.619 --> 01:01:42.519 Disconnect the value to True Pose 963 01:01:42.519 --> 01:01:45.039 and move PistolCache a bit to the side 964 01:01:47.040 --> 01:01:49.240 Then click right on here 965 01:01:49.240 --> 01:01:56.080 There is a node called Transform (Modify) Bone 966 01:01:56.080 --> 01:01:58.280 There is a Transform (Modify) Bone 967 01:01:58.280 --> 01:02:00.429 Add this node 968 01:02:03.079 --> 01:02:07.679 In order to put the output into True Pose 969 01:02:07.679 --> 01:02:09.479 Take it and put it in 970 01:02:09.479 --> 01:02:15.330 Then a converting node called Component To Local is added automatically 971 01:02:16.399 --> 01:02:21.199 Let's put PistolCache 972 01:02:21.199 --> 01:02:22.349 into Component Pose 973 01:02:22.349 --> 01:02:27.040 Then a node called Local To Component is added here 974 01:02:27.040 --> 01:02:29.090 Since we are going to add the value of rotation 975 01:02:29.090 --> 01:02:31.040 Click right on Rotation socket 976 01:02:31.040 --> 01:02:34.280 and select Split Struct Pin 977 01:02:34.280 --> 01:02:35.730 Then it's all separated 978 01:02:35.730 --> 01:02:38.880 Now Roll to PitchAngle 979 01:02:38.880 --> 01:02:41.330 I mean connect the value of PitchAngle to Roll 980 01:02:41.330 --> 01:02:44.919 to the Rotation X like this 981 01:02:44.919 --> 01:02:49.219 Then select Transform (Modify) Bone 982 01:02:49.219 --> 01:02:53.669 On the right side, the bone we will apply is under the Skeletal Control 983 01:02:53.669 --> 01:02:57.719 Select spine_03 984 01:02:57.719 --> 01:03:00.369 Then we will use the value of rotation 985 01:03:00.369 --> 01:03:03.869 Under the Rotation tab, it's set to Ignore 986 01:03:03.869 --> 01:03:08.040 Change it to Add to Existing 987 01:03:08.040 --> 01:03:12.390 Compile and save it 988 01:03:12.390 --> 01:03:14.320 Come back to the main window 989 01:03:14.320 --> 01:03:16.970 Click play 990 01:03:16.970 --> 01:03:19.370 Everything is fine if we do nothing 991 01:03:19.370 --> 01:03:24.120 When the player gets the pistol, the camera is rotating up and down 992 01:03:24.120 --> 01:03:29.220 Press F8, we can see the upper body is rotated up 993 01:03:29.220 --> 01:03:32.320 and down in accordance with my mouse rotation 994 01:03:32.320 --> 01:03:35.920 That's it for pistol shooting 995 01:03:35.920 --> 01:03:39.039 Let's put together what we learned in this chapter 996 01:03:39.702 --> 01:03:41.402 Pistol grabbing and releasing Pistol grabbing Add gun assets to the project and create BP_Pistol blueprint Create input action for pistol grabbing and figure out the mapping factors 997 01:03:41.402 --> 01:03:43.052 Implement TakePistol function in order to process pistol grabbing on NetTPSCharacter class and write algorithm to examine nearest guns and grab it 998 01:03:43.052 --> 01:03:44.752 Use AttachToComponent function to attach the pistol to the player's hands 999 01:03:44.752 --> 01:03:46.402 Pistol releasing Create input action to release pistol and implement mapping factor Use DetachFromComponent to detach from the component of the player actor 1000 01:03:46.402 --> 01:03:48.852 Pistol shooting Create input action to shoot guns and implement mapping factor Learn about LineTrace which is the way to examine objects collide by throwing invisible line in the form of a half line in shooting 1001 01:03:48.852 --> 01:03:51.252 Create montage animation asset of unreal engine and learn the way of playing it to control shooting animation 1002 01:03:51.252 --> 01:03:53.902 Learn how to use Transform (Modify) Bone node on the animation blueprint in order to implement upper body rotation in accordance with the mouse control of the player