WEBVTT 1 00:00:05.676 --> 00:00:09.992 Game Advanced Prototype Version 2 2 00:00:09.992 --> 00:00:11.982 GCC Academy 3 00:00:27.900 --> 00:00:29.719 Hello, everyone 4 00:00:29.719 --> 00:00:32.880 This is Kim Hyun-jin, in charge of FPS game building 5 00:00:32.880 --> 00:00:35.560 In this unit, we will implement 6 00:00:35.560 --> 00:00:39.119 the jump function for the character using user input 7 00:00:39.119 --> 00:00:41.919 Then, we will use Rigidbody 8 00:00:41.919 --> 00:00:43.599 to implement a throwable weapon 9 00:00:43.599 --> 00:00:45.040 and utilize the Raycast function 10 00:00:45.040 --> 00:00:47.080 to create a shooting weapon 11 00:00:47.859 --> 00:00:51.601 Character Jump 12 00:00:52.080 --> 00:00:56.240 First, let's implement the character's jump 13 00:00:56.240 --> 00:01:00.360 Pressing the spacebar will make the character jump 14 00:01:00.360 --> 00:01:01.929 Before implementing the jump, 15 00:01:01.929 --> 00:01:06.239 we need to apply gravity to the player 16 00:01:06.239 --> 00:01:10.120 In the PlayerMove script, 17 00:01:10.120 --> 00:01:15.080 we will create a global variable to handle gravity 18 00:01:15.080 --> 00:01:19.239 A gravity variable is necessary, 19 00:01:19.239 --> 00:01:22.879 and we will also create a variable 20 00:01:22.879 --> 00:01:27.639 to store the vertical velocity affected by gravity 21 00:01:27.639 --> 00:01:31.120 Float gravity 22 00:01:31.120 --> 00:01:37.400 The name is float gravity 23 00:01:37.400 --> 00:01:42.120 We will define float gravity = -20 24 00:01:42.120 --> 00:01:46.440 In reality, gravity has a value of -9.8, 25 00:01:46.440 --> 00:01:48.720 but we do not need 26 00:01:48.720 --> 00:01:51.400 to simulate, at least now, 27 00:01:51.400 --> 00:01:53.040 real-world physics exactly 28 00:01:53.040 --> 00:01:56.839 You can adjust this value 29 00:01:56.839 --> 00:02:02.400 to find what feels appropriate 30 00:02:02.400 --> 00:02:05.599 I will set it to -20 31 00:02:05.599 --> 00:02:08.000 Next, we create a variable for vertical velocity 32 00:02:08.000 --> 00:02:13.759 float yVelocity 33 00:02:13.759 --> 00:02:18.000 Since there is no initial movement, we set it to zero 34 00:02:18.000 --> 00:02:21.000 Then, in the update function, 35 00:02:21.000 --> 00:02:27.960 we will ensure that gravity is continuously applied 36 00:02:27.960 --> 00:02:34.759 before movement calculations 37 00:02:34.759 --> 00:02:37.600 To do this, we will add the gravity value to yVelocity 38 00:02:37.600 --> 00:02:39.320 over time 39 00:02:39.320 --> 00:02:43.479 On our gravity value 40 00:02:43.479 --> 00:02:47.199 Next, using Time.deltaTime, 41 00:02:47.199 --> 00:02:52.080 it ensures that the vertical velocity 42 00:02:52.080 --> 00:02:55.180 accumulates the effects 43 00:02:55.180 --> 00:02:59.000 of gravity per frame in yVelocity 44 00:02:59.000 --> 00:03:00.199 So what do we do? 45 00:03:00.199 --> 00:03:02.800 dir means direction 46 00:03:02.800 --> 00:03:06.399 So dir, and its y value is 47 00:03:06.399 --> 00:03:09.839 yVelocity 48 00:03:09.839 --> 00:03:13.600 Then, the gravity is applied 49 00:03:13.600 --> 00:03:18.320 If we temporarily comment out this gravity application 50 00:03:18.320 --> 00:03:21.320 and test in the editor, 51 00:03:21.320 --> 00:03:25.679 looking up and pressing W will cause the character 52 00:03:25.679 --> 00:03:28.199 to float indefinitely 53 00:03:28.199 --> 00:03:32.559 However, when we re-enable gravity, 54 00:03:32.559 --> 00:03:35.000 undo the comment out, 55 00:03:35.000 --> 00:03:40.719 and test again in the editor, 56 00:03:40.720 --> 00:03:44.479 the character will no longer float upwards 57 00:03:44.479 --> 00:03:47.479 but instead move forward, 58 00:03:47.479 --> 00:03:53.399 as gravity is pulling it downward 59 00:03:53.399 --> 00:03:56.880 Now that gravity is applied, 60 00:03:56.880 --> 00:04:00.279 let's make the player jump 61 00:04:00.279 --> 00:04:02.679 Jumping involves initially moving upward, 62 00:04:02.679 --> 00:04:05.800 reaching a peak, and then falling back down due to gravity 63 00:04:05.800 --> 00:04:09.000 This motion is governed by what? 64 00:04:09.000 --> 00:04:15.240 This jump is governed by gravity 65 00:04:15.240 --> 00:04:18.320 To implement jumping, 66 00:04:18.320 --> 00:04:22.440 we will add another global variable 67 00:04:22.440 --> 00:04:26.880 To determine the jump strength, 68 00:04:26.880 --> 00:04:33.119 let's create a variable called jumpPower 69 00:04:33.119 --> 00:04:39.920 float jumpPower = 10 70 00:04:39.920 --> 00:04:44.200 and can be adjusted as needed 71 00:04:44.200 --> 00:04:48.160 when the jump is implemented 72 00:04:48.160 --> 00:04:50.959 In the update function, 73 00:04:50.959 --> 00:04:56.119 before applying gravity, make some space 74 00:04:56.119 --> 00:04:58.828 Once the spacebar is pressed, 75 00:05:04.713 --> 00:05:14.450 it assigns jumpPower to yVelocity 76 00:05:14.450 --> 00:05:16.839 That's the code we're adding 77 00:05:16.839 --> 00:05:21.519 If input, and among what you have, 78 00:05:21.519 --> 00:05:25.200 use the function GetButtonDown 79 00:05:25.200 --> 00:05:31.920 Open a parenthesis, and use Jump as the parameter 80 00:05:31.920 --> 00:05:36.279 Then, when we press the spacebar, 81 00:05:36.279 --> 00:05:38.359 this function returns true 82 00:05:38.359 --> 00:05:42.119 So this condition is met, 83 00:05:42.119 --> 00:05:44.519 and whatever is inside the parenthesis will happen 84 00:05:44.519 --> 00:05:46.359 And what is it? 85 00:05:46.359 --> 00:05:50.320 Assigning jumpPower to yVelocity 86 00:05:50.320 --> 00:05:53.270 So, to yVelocity, 87 00:05:53.270 --> 00:05:58.079 we add jumpPower 88 00:05:58.079 --> 00:06:03.640 Here, jumpPower is 10 89 00:06:03.640 --> 00:06:08.200 So when we press the spacebar, yVelocity becomes 10 90 00:06:08.200 --> 00:06:13.600 Multiplying gravity with Time.deltaTime 91 00:06:13.600 --> 00:06:15.559 will return a decimal value 92 00:06:15.559 --> 00:06:20.200 So it will be less than this 10 93 00:06:20.200 --> 00:06:23.320 Let's say that we get 9 here 94 00:06:23.320 --> 00:06:27.880 Then, the dir.y value will be 9, 95 00:06:27.880 --> 00:06:33.920 causing the y value to move upwards 96 00:06:33.920 --> 00:06:40.079 This makes the character move upwards as well 97 00:06:40.079 --> 00:06:42.329 In the next frame, yVelocity of 9 98 00:06:42.329 --> 00:06:44.040 may become 8, 99 00:06:44.040 --> 00:06:50.160 slightly reducing the upward movement 100 00:06:50.160 --> 00:06:52.799 Eventually, this value decreases further, 101 00:06:52.799 --> 00:06:57.000 reversing the direction at one point 102 00:06:57.000 --> 00:07:02.880 and causing the character to fall back down in a jump 103 00:07:02.880 --> 00:07:04.996 Let's switch to the editor and play the scene 104 00:07:07.679 --> 00:07:09.729 When we press the spacebar, 105 00:07:09.729 --> 00:07:11.631 we can see that the character jumps 106 00:07:15.640 --> 00:07:19.290 If the jump height feels too high, 107 00:07:19.290 --> 00:07:22.839 we can reduce the jump power 108 00:07:22.839 --> 00:07:26.000 To make it easier to adjust, 109 00:07:26.000 --> 00:07:29.640 we change the jumpPower variable to public, 110 00:07:29.640 --> 00:07:35.000 then go back to the editor, select the Player object, 111 00:07:35.000 --> 00:07:38.100 and go to PlayerMove 112 00:07:38.100 --> 00:07:42.200 and change JumpPower to 5 113 00:07:42.200 --> 00:07:46.640 Let's test again, 114 00:07:46.640 --> 00:07:50.600 and observe that the character now jumps with a lower height 115 00:07:50.600 --> 00:07:55.628 It can even jump on this block 116 00:07:55.628 --> 00:07:57.320 However, there's an issue 117 00:07:57.320 --> 00:08:00.119 Let's go up to this block 118 00:08:00.119 --> 00:08:02.959 When we do, 119 00:08:02.959 --> 00:08:06.640 let's look at the scene view 120 00:08:06.640 --> 00:08:10.040 When the character moves forward here, 121 00:08:10.040 --> 00:08:13.959 it should naturally fall if there's no ground 122 00:08:13.959 --> 00:08:17.040 So the character should fall down 123 00:08:17.040 --> 00:08:19.920 But when we test it, 124 00:08:19.920 --> 00:08:21.578 see what happens 125 00:08:24.359 --> 00:08:28.880 The character just teleports down 126 00:08:28.880 --> 00:08:31.119 This happens 127 00:08:31.119 --> 00:08:32.719 because while standing on the ground, 128 00:08:32.719 --> 00:08:35.719 the yVelocity, though it works perfectly, 129 00:08:35.719 --> 00:08:39.799 continues to decrease due to gravity, 130 00:08:39.799 --> 00:08:42.679 even though the character is not moving downward 131 00:08:42.679 --> 00:08:44.960 So over time, 132 00:08:44.960 --> 00:08:48.239 this value we have at yVelocity will drop down 133 00:08:48.239 --> 00:08:52.159 and accumulate into a very large negative number, 134 00:08:52.159 --> 00:08:55.719 like -10000, or even -100000 135 00:08:55.719 --> 00:08:59.519 So this yVelocity value 136 00:08:59.519 --> 00:09:03.320 is a big negative number 137 00:09:03.320 --> 00:09:08.119 When the character finally moves off the edge, 138 00:09:08.119 --> 00:09:10.019 this extreme value 139 00:09:10.019 --> 00:09:13.719 causes it to drop instantly 140 00:09:13.719 --> 00:09:15.039 So what happens? 141 00:09:15.039 --> 00:09:19.080 The character appears as though it teleports 142 00:09:19.080 --> 00:09:22.640 So how do we fix this? 143 00:09:22.640 --> 00:09:24.840 Whenever the character is on the ground, 144 00:09:24.840 --> 00:09:28.190 we reset yVelocity to zero 145 00:09:28.190 --> 00:09:34.091 This little code will solve the problem 146 00:09:34.091 --> 00:09:36.479 Before we press the spacebar, 147 00:09:36.479 --> 00:09:44.673 if the character is touching the ground, 148 00:09:44.673 --> 00:09:50.723 set yVelocity to 0 149 00:09:50.723 --> 00:09:54.109 That's the condition we'll be adding 150 00:09:54.109 --> 00:09:58.259 Whether the character is touching the ground 151 00:09:58.259 --> 00:10:02.000 can be checked at CharacterController 152 00:10:02.000 --> 00:10:06.000 So of all properties, 153 00:10:06.000 --> 00:10:09.280 it has isGrounded 154 00:10:09.280 --> 00:10:12.423 It's a bool type, which returns true if the character is on the ground 155 00:10:12.423 --> 00:10:15.799 and false if it is in the air 156 00:10:15.799 --> 00:10:19.640 If isGrounded is true, 157 00:10:19.640 --> 00:10:23.599 we set yVelocity to 0 158 00:10:23.599 --> 00:10:29.270 So, yVelocity = 0 159 00:10:29.270 --> 00:10:33.440 Let's return to the editor and test again 160 00:10:33.440 --> 00:10:38.886 The character is up here again 161 00:10:38.886 --> 00:10:41.436 Let's fall down 162 00:10:41.436 --> 00:10:44.039 We've been sitting here for a while now 163 00:10:44.039 --> 00:10:46.039 Now, let's move forward 164 00:10:46.039 --> 00:10:49.278 Now it falls naturally, instead of teleporting 165 00:10:54.159 --> 00:10:56.937 It was a very natural motion 166 00:10:59.068 --> 00:11:02.770 Throwable weapon 167 00:11:03.320 --> 00:11:09.101 Now, let's create a throwable weapon 168 00:11:09.121 --> 00:11:12.760 We will make a grenade-like object 169 00:11:12.760 --> 00:11:15.510 In the Hierarchy window, click the + button, 170 00:11:15.510 --> 00:11:21.400 select 3D Object > Sphere, 171 00:11:21.400 --> 00:11:25.320 and rename it to Bomb 172 00:11:25.320 --> 00:11:29.170 When the right mouse button is pressed, 173 00:11:29.170 --> 00:11:35.316 the bomb will be created 174 00:11:35.316 --> 00:11:38.080 and launched forward, in the direction of the camera 175 00:11:38.080 --> 00:11:43.599 So the bomb will be moving this way here 176 00:11:43.599 --> 00:11:45.649 Instead of moving in a straight line indefinitely, 177 00:11:45.649 --> 00:11:47.199 what does gravity do? 178 00:11:47.199 --> 00:11:53.749 The bomb should fall naturally 179 00:11:53.749 --> 00:11:57.399 To assign such gravity, 180 00:11:57.399 --> 00:12:00.849 we could manually implement gravity in the script 181 00:12:00.849 --> 00:12:05.064 by writing the code out 182 00:12:05.064 --> 00:12:08.864 But Unity provides a built-in Rigidbody component 183 00:12:08.864 --> 00:12:15.320 that handles physics calculations, including gravity 184 00:12:15.320 --> 00:12:19.020 To apply it, select the Bomb object, 185 00:12:19.020 --> 00:12:21.041 go to Add Component, 186 00:12:21.041 --> 00:12:27.391 search for Rigidbody, 187 00:12:27.391 --> 00:12:30.119 make sure it's not Rigidbody2D 188 00:12:30.119 --> 00:12:33.877 Select Rigidbody 189 00:12:33.880 --> 00:12:37.480 Now, check the Use Gravity option 190 00:12:37.480 --> 00:12:41.530 If checked, 191 00:12:41.530 --> 00:12:46.919 the bomb will fall due to gravity when played 192 00:12:46.919 --> 00:12:50.969 If unchecked, the bomb will not be affected by gravity 193 00:12:50.969 --> 00:12:55.080 At this stage, the bomb is not fully functional yet 194 00:12:55.080 --> 00:12:59.780 Before finalizing it, let's apply that when we right-click, 195 00:12:59.780 --> 00:13:03.180 it will spawn at a location and launch 196 00:13:03.180 --> 00:13:08.669 in the direction the camera is facing 197 00:13:08.669 --> 00:13:12.969 To do this, we convert Bomb into a Prefab, 198 00:13:12.969 --> 00:13:16.559 allowing it to be instantiated dynamically 199 00:13:16.559 --> 00:13:19.559 To create the prefab, select the Assets folder, 200 00:13:19.559 --> 00:13:23.409 then click the + button in the Project window 201 00:13:23.409 --> 00:13:29.575 and create a new folder named Prefabs 202 00:13:29.575 --> 00:13:32.075 Drag the Bomb object from the Hierarchy 203 00:13:32.075 --> 00:13:34.345 Drag this Bomb 204 00:13:34.345 --> 00:13:37.845 into this folder 205 00:13:37.845 --> 00:13:41.159 to convert it into a prefab 206 00:13:41.159 --> 00:13:47.213 Next, delete the Bomb object from the Hierarchy 207 00:13:47.213 --> 00:13:49.824 Then, we will create a script 208 00:13:49.824 --> 00:13:52.024 to instantiate and launch the bomb forward 209 00:13:52.024 --> 00:13:57.320 for our player, or the character 210 00:13:57.320 --> 00:14:01.020 In the Assets folder, navigate to the Scripts folder 211 00:14:01.020 --> 00:14:04.270 and create a new C# script by clicking the + button 212 00:14:04.270 --> 00:14:10.472 Name this script PlayerFire 213 00:14:10.472 --> 00:14:13.472 After that, select the Player object in the Hierarchy, 214 00:14:13.472 --> 00:14:16.879 drag the PlayerFire script onto it, 215 00:14:16.879 --> 00:14:18.322 and attach it to the Player 216 00:14:18.322 --> 00:14:23.320 so that it is properly integrated 217 00:14:23.320 --> 00:14:27.270 Now, open the PlayerFire script 218 00:14:27.270 --> 00:14:33.159 To fire bombs, we need two global variables: 219 00:14:33.159 --> 00:14:37.046 The bomb, 220 00:14:37.046 --> 00:14:41.146 and the fire position 221 00:14:41.146 --> 00:14:45.320 from which the bomb will be launched 222 00:14:45.320 --> 00:14:48.020 We created our Bomb prefab 223 00:14:48.020 --> 00:14:49.320 by drag-and-dropping GameObject 224 00:14:49.320 --> 00:14:53.620 Since the bomb prefab is an external asset, 225 00:14:53.620 --> 00:14:57.985 its data type must be GameObject 226 00:14:57.985 --> 00:15:00.385 Mark it as public 227 00:15:00.385 --> 00:15:03.035 so that we can assign it in the Inspector 228 00:15:03.035 --> 00:15:05.599 And the data type is GameObject 229 00:15:05.599 --> 00:15:09.760 Then, name the varible 230 00:15:09.760 --> 00:15:14.992 Let's name it bombFactory 231 00:15:14.992 --> 00:15:18.742 Let's create GameObject for the launch location 232 00:15:18.742 --> 00:15:21.842 and add it in there 233 00:15:21.842 --> 00:15:28.093 public GameObject firePosition; 234 00:15:28.093 --> 00:15:31.817 We haven't created the fire position yet, 235 00:15:31.817 --> 00:15:34.117 but after writing this code, 236 00:15:34.117 --> 00:15:39.382 we will set it up in the editor 237 00:15:39.382 --> 00:15:42.432 In the Update function, 238 00:15:42.432 --> 00:15:52.510 we check if the right mouse button is pressed 239 00:15:52.510 --> 00:15:58.325 If so, we create a bomb 240 00:15:58.325 --> 00:16:05.406 at Bomb Prefab 241 00:16:05.406 --> 00:16:10.056 Next, we instantiate that bomb 242 00:16:10.056 --> 00:16:18.293 at the fire position 243 00:16:18.293 --> 00:16:22.093 To detect right-click input, we use this 244 00:16:22.093 --> 00:16:26.579 If, Input, and of all the things it has, 245 00:16:26.579 --> 00:16:32.799 we use the function GetMouseButtonDown 246 00:16:32.799 --> 00:16:37.120 We put them in parentheses, and we put a number here 247 00:16:37.120 --> 00:16:41.920 Using 0 will return true 248 00:16:41.920 --> 00:16:43.470 when we left-click 249 00:16:43.470 --> 00:16:45.970 Using 1, 250 00:16:45.970 --> 00:16:49.440 it returns true 251 00:16:49.440 --> 00:16:51.940 when we right-click 252 00:16:51.940 --> 00:16:55.590 We can also add 2, which returns true 253 00:16:55.590 --> 00:16:59.880 when we click on the mouse wheel 254 00:16:59.880 --> 00:17:04.580 Since we decided that we're using the right click, 255 00:17:04.580 --> 00:17:06.587 we just add 1 256 00:17:09.834 --> 00:17:13.529 Then, we do these two 257 00:17:16.359 --> 00:17:22.204 Instantiate, open up a parenthesis, 258 00:17:22.204 --> 00:17:28.057 and add our bomb prefab, the bombFactory 259 00:17:28.057 --> 00:17:32.557 This creates a copy of the bomb prefab, 260 00:17:32.557 --> 00:17:34.760 and we store the reference in bomb 261 00:17:34.760 --> 00:17:36.960 Now, we need to get that value 262 00:17:36.960 --> 00:17:41.060 GameObject bomb = 263 00:17:41.060 --> 00:17:44.396 That's how we can answer that 264 00:17:44.396 --> 00:17:48.296 All the result is saved in this variable bomb 265 00:17:48.296 --> 00:17:51.959 We can change the position with this variable 266 00:17:51.959 --> 00:17:56.509 So we use bomb.transform.position 267 00:17:56.509 --> 00:17:57.759 So we approach position 268 00:17:57.759 --> 00:18:01.000 to set it up, but how? 269 00:18:01.000 --> 00:18:04.950 We'll set it as the position value 270 00:18:04.950 --> 00:18:10.164 of transform that firePosition owns 271 00:18:10.164 --> 00:18:16.040 Let's return to the editor and select the Player object 272 00:18:16.040 --> 00:18:20.471 Under Inspector, Bomb Factory field is None 273 00:18:20.471 --> 00:18:25.271 Now, to the Assets folder here, 274 00:18:25.271 --> 00:18:27.242 the Bomb prefab from the Prefabs folder 275 00:18:27.242 --> 00:18:29.592 Drag this Prefab into this field 276 00:18:29.592 --> 00:18:32.160 Just like that 277 00:18:32.160 --> 00:18:36.360 We haven't created fire position yet, so we should now 278 00:18:36.360 --> 00:18:40.480 In the Hierarchy, select the Player object, 279 00:18:40.480 --> 00:18:46.330 right-click, and choose Create Empty 280 00:18:46.330 --> 00:18:51.735 Rename this object to FirePos 281 00:18:51.735 --> 00:18:54.558 Then, move it to a suitable position above the player's head, 282 00:18:54.558 --> 00:18:57.365 just like that 283 00:19:01.359 --> 00:19:07.546 Let's try around 1.8 units high 284 00:19:07.546 --> 00:19:11.396 Finally, select the Player object again, 285 00:19:11.396 --> 00:19:15.520 drag FirePos 286 00:19:15.520 --> 00:19:21.280 into the Fire Position field in the Inspector 287 00:19:21.280 --> 00:19:24.030 Now, when we press the right mouse button, 288 00:19:24.030 --> 00:19:27.680 a bomb will be instantiated 289 00:19:27.680 --> 00:19:29.030 So what do we do with this? 290 00:19:29.030 --> 00:19:32.280 We put it at the fire position 291 00:19:32.280 --> 00:19:34.980 All this has been coded in what we have 292 00:19:34.980 --> 00:19:40.173 Let's play and test it 293 00:19:40.173 --> 00:19:43.673 When right-clicking, bombs are created 294 00:19:43.673 --> 00:19:45.273 and they drop 295 00:19:45.273 --> 00:19:50.465 More bombs appear and fall 296 00:19:50.465 --> 00:19:54.165 Currently, the bombs collide with the player, 297 00:19:54.165 --> 00:19:55.526 so it looks like this 298 00:19:55.526 --> 00:19:59.277 But we will later implement a fix to prevent this 299 00:19:59.277 --> 00:20:01.677 Now, we implemented the bomb instantiation 300 00:20:01.677 --> 00:20:05.016 However, at this stage, the bombs are only being created, 301 00:20:05.016 --> 00:20:08.080 not actually being launched 302 00:20:08.080 --> 00:20:12.062 Now, let's make the bomb launch in the direction 303 00:20:12.062 --> 00:20:15.908 of the camera, similar to a grenade throw 304 00:20:15.908 --> 00:20:19.858 Go to the PlayerFire script 305 00:20:19.858 --> 00:20:23.520 and define a new variable for the throw power 306 00:20:23.520 --> 00:20:27.637 Let's stary with public float 307 00:20:27.637 --> 00:20:31.087 Name the variable as throwPower 308 00:20:31.087 --> 00:20:37.309 Let's add around 1000 309 00:20:37.309 --> 00:20:39.309 This force is applied 310 00:20:39.309 --> 00:20:41.409 for the gravity to the bomb 311 00:20:41.409 --> 00:20:44.560 using Rigidbody 312 00:20:44.560 --> 00:20:49.560 We can also use it to apply force 313 00:20:49.560 --> 00:20:53.919 We can create the bomb using a right-click here, 314 00:20:53.919 --> 00:20:59.166 so let's add the force application at the bottom 315 00:21:02.360 --> 00:21:09.642 So we bring in the Rigidbody component 316 00:21:09.642 --> 00:21:18.452 from the bomb using this method up here 317 00:21:18.452 --> 00:21:27.780 And we use GetComponent for the force 318 00:21:27.780 --> 00:21:35.704 All in the direction of the camera 319 00:21:35.704 --> 00:21:39.354 Let's now define a variable to store Rigidbody 320 00:21:39.354 --> 00:21:42.304 Data type is Rigidbody 321 00:21:42.304 --> 00:21:44.800 Let's name it as rb 322 00:21:44.800 --> 00:21:47.200 Next, we bring 323 00:21:47.200 --> 00:21:51.360 GetComponent from bomb 324 00:21:51.360 --> 00:21:53.960 Since we have Rigidbody 325 00:21:53.960 --> 00:21:56.440 attached to bomb, 326 00:21:56.440 --> 00:22:00.290 we need access to the compoennt 327 00:22:00.290 --> 00:22:02.190 using this variable bomb 328 00:22:02.190 --> 00:22:07.182 What if we didn't have this part? 329 00:22:07.182 --> 00:22:10.040 It means we're getting it from the player 330 00:22:10.040 --> 00:22:14.240 This will result in an error, 331 00:22:14.240 --> 00:22:17.340 because our player has no Rigidbody 332 00:22:17.340 --> 00:22:20.190 So we ask bomb 333 00:22:20.190 --> 00:22:22.190 to use Getcomponent function 334 00:22:22.190 --> 00:22:27.639 to retrieve the component that it already has 335 00:22:27.639 --> 00:22:29.539 In a set of angle brackets, 336 00:22:29.539 --> 00:22:33.439 add in the component type we want 337 00:22:33.439 --> 00:22:35.639 Since we want Rigidbody, 338 00:22:35.639 --> 00:22:38.939 add Rigidbody, type in the parentheses 339 00:22:38.939 --> 00:22:41.399 Use a semicolon 340 00:22:41.399 --> 00:22:43.299 So for the variable rb, 341 00:22:43.299 --> 00:22:46.949 it has the Rigidbody component 342 00:22:46.949 --> 00:22:48.479 attached to the bomb 343 00:22:48.479 --> 00:22:51.751 So of all functions that rb has, 344 00:22:51.751 --> 00:22:53.601 there is AddForce 345 00:22:53.601 --> 00:22:58.997 This can apply force 346 00:22:58.997 --> 00:23:02.697 So we add force and direction here 347 00:23:02.697 --> 00:23:05.855 So to the camera, 348 00:23:05.855 --> 00:23:08.705 the main camera, 349 00:23:08.705 --> 00:23:12.305 we use transform 350 00:23:12.305 --> 00:23:15.080 and forward, because we need the force forward 351 00:23:15.080 --> 00:23:18.646 This will give us a very little force, 352 00:23:18.646 --> 00:23:20.046 because it is 1 353 00:23:20.046 --> 00:23:27.975 So we use * and multiply it by the variable throwPower 354 00:23:27.975 --> 00:23:30.175 If this force is too weak or too strong, 355 00:23:30.175 --> 00:23:33.520 we can edit it at the Inspector 356 00:23:33.520 --> 00:23:39.031 Go back to Editor and play 357 00:23:39.031 --> 00:23:40.981 Right click, 358 00:23:40.981 --> 00:23:45.616 and the bombs are flying around 359 00:23:45.616 --> 00:23:48.266 Select Player, 360 00:23:48.266 --> 00:23:54.442 and adjust the throwPower in the Inspector to 700 361 00:23:54.442 --> 00:24:01.265 Now, we see that the throw distance has decreased 362 00:24:01.265 --> 00:24:05.915 Currently, the bomb just bounces 363 00:24:05.915 --> 00:24:09.919 when it hits the ground or walls 364 00:24:09.919 --> 00:24:12.269 Let's modify it a little, so that 365 00:24:12.269 --> 00:24:16.321 it disappears on impact 366 00:24:16.321 --> 00:24:19.221 In the Scripts folder, 367 00:24:19.221 --> 00:24:22.600 create a new C# script 368 00:24:22.600 --> 00:24:29.751 and name it BombAction 369 00:24:29.751 --> 00:24:32.801 Next, go to Assets folder, 370 00:24:32.801 --> 00:24:34.701 choose Prefabs folder, 371 00:24:34.701 --> 00:24:37.320 and get the Bomb prefab 372 00:24:37.320 --> 00:24:40.220 In the Inspector, click Add Component, 373 00:24:40.220 --> 00:24:45.820 search for BombAction we just created, 374 00:24:45.820 --> 00:24:48.480 and attach it 375 00:24:48.480 --> 00:24:51.920 Double click to open it 376 00:24:51.920 --> 00:24:54.570 When this bomb collides with any object, 377 00:24:54.570 --> 00:24:57.720 it will destroy itself using this code 378 00:24:57.720 --> 00:25:01.945 So search for oncoll 379 00:25:01.945 --> 00:25:03.480 and we get OnCollisionEnter 380 00:25:03.480 --> 00:25:08.440 Let's complete this function 381 00:25:08.440 --> 00:25:11.040 This function is called 382 00:25:11.040 --> 00:25:12.880 whenever something has a physical collision 383 00:25:12.880 --> 00:25:14.839 And, what do we want here? 384 00:25:14.839 --> 00:25:20.385 Destroy itself 385 00:25:20.385 --> 00:25:24.046 Destroy(gameObject); 386 00:25:24.046 --> 00:25:29.107 This code will make the object destroy itself 387 00:25:29.107 --> 00:25:33.677 Now, play again 388 00:25:33.679 --> 00:25:37.600 The bomb disappears upon hitting the ground 389 00:25:37.600 --> 00:25:39.799 It does the same with this block 390 00:25:44.838 --> 00:25:50.436 Next, let's create a shooting weapon 391 00:25:50.436 --> 00:25:55.399 This will be using Ray 392 00:25:55.399 --> 00:25:59.880 Let's say this is the camera 393 00:25:59.880 --> 00:26:04.080 We will cast a Ray from the camera's position 394 00:26:04.080 --> 00:26:07.079 and moving forward 395 00:26:07.079 --> 00:26:08.629 It's like laser, 396 00:26:08.629 --> 00:26:10.920 which keeps moving forward 397 00:26:10.920 --> 00:26:14.498 If there is a wall here, 398 00:26:14.498 --> 00:26:18.119 this Ray will hit the wall, right? 399 00:26:18.119 --> 00:26:22.798 Then, we can get this impact location 400 00:26:22.799 --> 00:26:25.899 We can use left-click 401 00:26:25.899 --> 00:26:28.480 to create Ray, shoot it, 402 00:26:28.480 --> 00:26:32.277 and add a visual effect on the impact location 403 00:26:37.480 --> 00:26:40.180 like sparks or bullet impact 404 00:26:40.180 --> 00:26:42.600 This will look like a fast bullet 405 00:26:42.600 --> 00:26:45.920 traveling until it hits the surface 406 00:26:45.920 --> 00:26:47.870 Using this, 407 00:26:47.870 --> 00:26:52.838 let's implement the shooting weapon 408 00:26:52.839 --> 00:26:55.519 First, in the PlayerFire script, 409 00:26:55.519 --> 00:26:57.719 go to the existing bomb-throwing function 410 00:26:57.719 --> 00:27:00.819 Instead of keeping it in Update, 411 00:27:00.819 --> 00:27:05.160 we will move it to a separate function 412 00:27:05.160 --> 00:27:14.298 Below Update, add void Firebomb 413 00:27:14.298 --> 00:27:18.359 Now, use Ctrl+X to cut the bomb-throwing code 414 00:27:18.359 --> 00:27:25.480 from Update and paste it inside the FireBomb function 415 00:27:26.079 --> 00:27:32.479 Finally, call the FireBomb function 416 00:27:32.479 --> 00:27:34.239 inside the Update function 417 00:27:34.239 --> 00:27:39.119 Now, the behavior remains the same 418 00:27:39.119 --> 00:27:42.519 Similarly, we will create a function 419 00:27:42.519 --> 00:27:46.000 for the shooting weapon 420 00:27:46.000 --> 00:27:49.819 void FireRay 421 00:27:54.680 --> 00:28:02.438 It checks if the left mouse button is pressed 422 00:28:09.000 --> 00:28:15.236 If so, this Ray will move 423 00:28:15.236 --> 00:28:24.310 from the camera's position and forward 424 00:28:24.310 --> 00:28:29.583 Next, this Ray will be fired 425 00:28:29.583 --> 00:28:40.093 sing the function Raycast 426 00:28:40.093 --> 00:28:48.861 Once this Ray hits something, 427 00:28:48.861 --> 00:29:01.478 we add the visual effect on that position 428 00:29:01.479 --> 00:29:06.325 That's the order of this coding 429 00:29:06.325 --> 00:29:11.000 If, of all functions in Input, 430 00:29:11.000 --> 00:29:16.039 we use GetMouseButtonDown 431 00:29:16.039 --> 00:29:20.560 And with 0, or the left-click, 432 00:29:20.560 --> 00:29:24.917 we get true 433 00:29:24.917 --> 00:29:28.267 Inside parentheses, use 2, 3, 4, and 5 434 00:29:28.267 --> 00:29:30.659 Everything goes inside 435 00:29:34.292 --> 00:29:36.442 Let's create a Ray now 436 00:29:36.442 --> 00:29:38.542 Its data type is Ray 437 00:29:38.542 --> 00:29:41.799 For that, we create a variable called ray with a lower case 438 00:29:41.799 --> 00:29:45.699 Let's create a new Ray here 439 00:29:45.699 --> 00:29:49.159 When creating a Ray, we can specify two parameters 440 00:29:49.159 --> 00:29:54.520 We can have Starting position and the direction 441 00:29:54.520 --> 00:29:57.370 Since we want the ray to originate from the camera 442 00:29:57.370 --> 00:29:59.320 and move in the direction the camera is facing, 443 00:29:59.320 --> 00:30:03.020 Camera.main, and then 444 00:30:03.020 --> 00:30:08.808 transform.position 445 00:30:08.818 --> 00:30:10.920 And after a comma, 446 00:30:10.920 --> 00:30:14.520 Camera.main 447 00:30:14.520 --> 00:30:20.664 Next, transform.forward 448 00:30:20.664 --> 00:30:25.619 This is how we create a Ray 449 00:30:25.619 --> 00:30:27.769 Next, we use Raycast 450 00:30:27.769 --> 00:30:30.000 to check for collisions along this 451 00:30:30.000 --> 00:30:35.280 Raycast is under Physics 452 00:30:35.280 --> 00:30:40.799 So start with Physics 453 00:30:40.799 --> 00:30:43.599 and add Raycast 454 00:30:43.599 --> 00:30:47.599 First, add ray 455 00:30:47.599 --> 00:30:50.649 Next, the second parameter 456 00:30:50.649 --> 00:30:53.440 is the direction in which 457 00:30:53.440 --> 00:30:57.740 the ray will travel in the case of the collision 458 00:30:57.740 --> 00:31:03.080 The variable will set this information up 459 00:31:03.080 --> 00:31:05.880 So we need to create the variable 460 00:31:05.880 --> 00:31:13.479 The data type is RaycastHit 461 00:31:13.479 --> 00:31:18.655 Let's name the variable hitInfo 462 00:31:18.655 --> 00:31:20.355 To the second parameter, 463 00:31:20.355 --> 00:31:27.009 use out for the hinInfo 464 00:31:27.009 --> 00:31:30.509 Raycast returns true 465 00:31:30.509 --> 00:31:35.177 if this ray has hit any surface 466 00:31:35.177 --> 00:31:37.127 Next, this hitInfo 467 00:31:37.127 --> 00:31:42.136 will contain the information about that position 468 00:31:42.136 --> 00:31:44.636 So these two, the third and the fourth, 469 00:31:44.636 --> 00:31:49.320 work at the same time with Raycast 470 00:31:49.320 --> 00:31:51.620 So we can use the if statement 471 00:31:51.620 --> 00:31:54.168 for our variable, Physics.Raycast 472 00:31:57.599 --> 00:32:01.699 If the ray collides with an object 473 00:32:01.699 --> 00:32:03.749 after traveling in the camera direction, 474 00:32:03.749 --> 00:32:06.618 raycast returns true 475 00:32:06.618 --> 00:32:10.168 Next, it stores the impact details 476 00:32:10.168 --> 00:32:15.408 in this variable, hitInfo 477 00:32:15.408 --> 00:32:20.119 We need to display a particle effect at the impact location 478 00:32:20.119 --> 00:32:24.169 However, since we don’t have 479 00:32:24.169 --> 00:32:30.048 a particle asset ready 480 00:32:30.048 --> 00:32:32.948 We will first verify 481 00:32:32.948 --> 00:32:37.538 that the raycast is working correctly, 482 00:32:37.538 --> 00:32:38.838 or if our ray has collided with a game object 483 00:32:38.838 --> 00:32:45.559 by printing debug information 484 00:32:45.559 --> 00:32:50.437 print, hitInfo 485 00:32:50.437 --> 00:32:53.037 To this variable, hitInfo, 486 00:32:53.037 --> 00:32:57.799 there is information on the collision detail 487 00:32:57.799 --> 00:33:01.249 So using hitInfo, 488 00:33:01.249 --> 00:33:04.679 we can bring in the name of the game object 489 00:33:04.679 --> 00:33:08.429 so, hitInfo.transform 490 00:33:08.429 --> 00:33:14.742 This will give us the name 491 00:33:14.742 --> 00:33:18.892 Now, use + and then a comma 492 00:33:18.892 --> 00:33:21.960 Next, + and the collision point 493 00:33:21.960 --> 00:33:23.637 so hitInfo, and 494 00:33:23.637 --> 00:33:31.054 the location is saved in the variable point 495 00:33:31.054 --> 00:33:34.704 Since we have the variable FireRay, 496 00:33:34.704 --> 00:33:37.960 let's update it and continue 497 00:33:37.960 --> 00:33:42.028 FireRay 498 00:33:42.028 --> 00:33:46.436 Save, and come back to the editor 499 00:33:46.440 --> 00:33:49.940 Enable the console window 500 00:33:49.940 --> 00:33:52.890 If this Collapse is checked 501 00:33:52.890 --> 00:33:58.919 in this gray area, click to remove 502 00:33:58.919 --> 00:34:05.677 Press Ctrl+P to run 503 00:34:05.677 --> 00:34:09.377 Left-click, and in this game view, 504 00:34:09.377 --> 00:34:13.359 we get Ray traveling from the center 505 00:34:13.359 --> 00:34:17.809 If I left-click facing this wall, 506 00:34:17.809 --> 00:34:20.760 we get the name Wall 507 00:34:20.760 --> 00:34:23.560 (-0.12, 0.92, 7.47) 508 00:34:23.560 --> 00:34:26.559 We get the coordinate values for the collision point 509 00:34:26.559 --> 00:34:30.659 If you slightly shift your view toward the left edge 510 00:34:30.659 --> 00:34:34.520 and click the left mouse button 511 00:34:34.520 --> 00:34:36.070 you will notice that the Wall object is still detected 512 00:34:36.070 --> 00:34:38.420 But the collision point has changed 513 00:34:38.420 --> 00:34:40.570 As a result, the coordinates displayed in the console 514 00:34:40.570 --> 00:34:44.972 are different from the previous click 515 00:34:44.972 --> 00:34:47.622 Now, we will use this collision point 516 00:34:47.622 --> 00:34:50.372 to display a particle effect 517 00:34:50.372 --> 00:34:56.276 at the exact impact location 518 00:34:56.276 --> 00:34:59.226 Open Unity's Asset Store 519 00:34:59.226 --> 00:35:02.876 Go to Window > Asset Store from the top menu 520 00:35:02.876 --> 00:35:07.039 Go to the Asset Store 521 00:35:07.039 --> 00:35:11.303 And search for 522 00:35:11.303 --> 00:35:14.367 war fx 523 00:35:17.119 --> 00:35:19.969 Select this 524 00:35:19.969 --> 00:35:24.119 Add it to your assets 525 00:35:24.119 --> 00:35:28.855 Click OK for this popup window 526 00:35:28.855 --> 00:35:32.855 Then, you will get another window 527 00:35:32.855 --> 00:35:36.440 Open it using Unity 528 00:35:36.440 --> 00:35:39.437 Next, open Unity Editor 529 00:35:41.719 --> 00:35:45.119 It opens Package Manger window, 530 00:35:45.119 --> 00:35:48.400 so that we can download our war fx 531 00:35:48.400 --> 00:35:51.978 Download it 532 00:35:51.978 --> 00:35:55.528 Next, we get Import and Re-Download 533 00:35:55.528 --> 00:35:58.320 We get two buttons 534 00:35:58.320 --> 00:36:02.941 Click on Import 535 00:36:02.941 --> 00:36:07.691 Then, we get a list of assets to import 536 00:36:07.691 --> 00:36:09.491 Import everything 537 00:36:09.491 --> 00:36:12.457 Click Import again 538 00:36:15.200 --> 00:36:19.750 Next, go to the Project window 539 00:36:19.750 --> 00:36:23.640 Find a folder named JMO Assets 540 00:36:23.640 --> 00:36:28.239 This is where we can see our war fx 541 00:36:28.239 --> 00:36:34.039 Double click on _Effects folder to enter 542 00:36:34.039 --> 00:36:38.039 We have a folder named Bullet Impacts 543 00:36:38.039 --> 00:36:40.618 Go inside the folder, 544 00:36:40.618 --> 00:36:44.268 and we have various particles 545 00:36:44.268 --> 00:36:49.200 Let's use WFX_BImpact 546 00:36:49.200 --> 00:36:52.750 And go with Concrete NoCollision 547 00:36:52.750 --> 00:36:57.159 Drag and drop this prefab to Hierarchy 548 00:36:57.159 --> 00:37:00.909 In the Inspector, 549 00:37:00.909 --> 00:37:03.960 there is additional script 550 00:37:03.960 --> 00:37:08.060 Let's remove this script 551 00:37:08.060 --> 00:37:12.479 Hover over the script name, 552 00:37:12.479 --> 00:37:14.729 right click 553 00:37:14.729 --> 00:37:16.659 and choose Remove Component 554 00:37:19.079 --> 00:37:25.033 Rename it to BulletImpact 555 00:37:27.746 --> 00:37:30.246 We will make this BulletImpact in Hierarchy 556 00:37:30.246 --> 00:37:32.800 into our own Prefab 557 00:37:32.800 --> 00:37:35.300 Go to the Prefabs folder 558 00:37:35.300 --> 00:37:39.160 drag it down here 559 00:37:39.160 --> 00:37:44.646 Once we get this popup window, click on Origin Prefab 560 00:37:44.646 --> 00:37:47.846 Now, this Prefab from the Asset Store 561 00:37:47.846 --> 00:37:49.496 has its original retained 562 00:37:49.496 --> 00:37:51.839 Using this, we just made 563 00:37:51.839 --> 00:37:54.489 a new Prefab for ourselves 564 00:37:54.489 --> 00:38:02.322 Remove this BulletImpact from the Hierarchy 565 00:38:02.322 --> 00:38:06.237 Next, select the BulletImpact prefab 566 00:38:06.237 --> 00:38:10.458 In the Inspector, make sure Play On Awake 567 00:38:10.458 --> 00:38:13.839 is enabled 568 00:38:13.839 --> 00:38:17.339 This option ensures that the effect plays 569 00:38:17.339 --> 00:38:19.639 automatically when instantiated 570 00:38:19.639 --> 00:38:21.009 Now, for this Particle System, 571 00:38:23.680 --> 00:38:26.230 go to the PlayerFire script 572 00:38:26.230 --> 00:38:29.080 Right now, when the bullet collides with an object, 573 00:38:29.080 --> 00:38:31.520 we are only printing its information to the Console 574 00:38:31.520 --> 00:38:36.160 Now, comment out the debug print statement 575 00:38:36.160 --> 00:38:38.660 Now, let's display a bullet impact effect 576 00:38:38.660 --> 00:38:40.895 at the exact location where the ray collides 577 00:38:43.687 --> 00:38:45.795 First, we need to create a global variable 578 00:38:48.560 --> 00:38:54.090 We need our BulletImpact prefab 579 00:38:54.090 --> 00:39:04.934 public GameObject bulletImpactFactory; 580 00:39:04.934 --> 00:39:08.234 Later, we will assign this prefab 581 00:39:08.234 --> 00:39:13.319 in Unity’s Inspector after writing out the code 582 00:39:13.319 --> 00:39:20.656 Go back to the FireRay() function 583 00:39:20.656 --> 00:39:26.228 and add the following code under number five 584 00:39:26.228 --> 00:39:34.517 Then, we will put the effect 585 00:39:34.520 --> 00:39:41.215 at the collision point 586 00:39:41.215 --> 00:39:43.565 This is the order we will take 587 00:39:43.565 --> 00:39:47.445 Instantiate 588 00:39:47.445 --> 00:39:51.800 Next, add our bullet impact effect prefab 589 00:39:51.800 --> 00:39:56.079 bulletImpactFactory 590 00:39:56.079 --> 00:40:01.688 GameObject bulletImpact = 591 00:40:01.688 --> 00:40:04.000 That's how we get it 592 00:40:04.000 --> 00:40:06.350 Next, for bulletImpact, 593 00:40:06.350 --> 00:40:08.900 we use tranform.position 594 00:40:08.900 --> 00:40:11.239 To change the position 595 00:40:11.239 --> 00:40:13.089 Where should it go? 596 00:40:13.089 --> 00:40:19.239 To hitInfo.point 597 00:40:19.239 --> 00:40:22.900 Save the script, return to the editor 598 00:40:22.900 --> 00:40:26.439 Select the Player GameObject 599 00:40:26.439 --> 00:40:30.039 In the Inspector, locate the Player Fire component 600 00:40:30.039 --> 00:40:31.989 Find the Bullet Impact Factory field 601 00:40:31.989 --> 00:40:35.739 Drag the BulletImpact prefab 602 00:40:35.739 --> 00:40:39.140 into this field 603 00:40:39.140 --> 00:40:41.096 Next, let's play it 604 00:40:44.000 --> 00:40:47.600 When you click the left mouse button, 605 00:40:47.600 --> 00:40:51.004 though it may not be very visible from a distane, 606 00:40:51.004 --> 00:40:54.404 you can see the debris effect appearing 607 00:40:54.404 --> 00:40:59.648 Similarly, if you shoot at the floor, the debris effect is distinctly visible 608 00:41:02.920 --> 00:41:06.720 One issue here is that after the debris effect is fully displayed, 609 00:41:06.720 --> 00:41:11.674 it remains on the screen instead of disappearing 610 00:41:11.680 --> 00:41:13.880 Another problem arises 611 00:41:13.880 --> 00:41:20.006 when shooting at a wall While the effect appears rich and full on the floor, 612 00:41:20.006 --> 00:41:23.406 doing it on the wall 613 00:41:23.406 --> 00:41:26.520 only shows a partial amount of it 614 00:41:26.520 --> 00:41:29.420 This happens because 615 00:41:29.420 --> 00:41:34.239 the debris effect shoots upward when it collides with the wall 616 00:41:34.239 --> 00:41:40.039 As a result, one half of the effect remains visible outside the wall, 617 00:41:40.039 --> 00:41:45.303 but the other half gets embedded inside the wall, 618 00:41:45.303 --> 00:41:48.239 making it invisible 619 00:41:48.239 --> 00:41:51.689 To ensure the effect appears fully outside the wall, 620 00:41:51.689 --> 00:41:56.189 we need to adjust it accordingly 621 00:41:56.189 --> 00:41:58.599 so that we get that same effect 622 00:41:58.599 --> 00:42:03.782 Let's adjust these two things 623 00:42:03.782 --> 00:42:06.732 Open the PlayerFire script 624 00:42:06.732 --> 00:42:16.760 First, set the bulletImpact to be destroyed after 2 seconds 625 00:42:16.760 --> 00:42:24.488 sing the Destroy(bulletImpact); function will do it 626 00:42:24.488 --> 00:42:27.599 As we see, it immediately deletes the effect upon creation 627 00:42:27.599 --> 00:42:32.199 To this Destory function, we can add a comma 628 00:42:32.199 --> 00:42:34.499 to add a second parameter 629 00:42:34.499 --> 00:42:37.949 If we add the number 2, 630 00:42:37.949 --> 00:42:40.299 it destroys bulletImpact, 631 00:42:40.299 --> 00:42:45.485 after two seconds 632 00:42:45.485 --> 00:42:48.281 So bulletImpact, after showing its effect, 633 00:42:48.281 --> 00:42:52.531 disappears in two seconds 634 00:42:52.531 --> 00:42:56.981 Next, we need to solve the issue 635 00:42:56.981 --> 00:42:59.481 where the effect gets embedded inside the wall 636 00:42:59.481 --> 00:43:04.000 Let's bring it to face the direction of the wall 637 00:43:04.000 --> 00:43:08.750 When the Ray collides with a vertical surface, 638 00:43:08.750 --> 00:43:13.800 the debris effect currently spreads outward, 639 00:43:13.800 --> 00:43:16.479 which makes this part invisible 640 00:43:16.479 --> 00:43:17.779 So what do we do with it? 641 00:43:17.779 --> 00:43:20.979 We need to orient the effect in a direction 642 00:43:20.979 --> 00:43:24.598 perpendicular to the wall 643 00:43:24.598 --> 00:43:30.218 What if it hits the floor? 644 00:43:30.218 --> 00:43:34.618 The effect should spread outward 645 00:43:34.618 --> 00:43:39.979 based on the normal vector of the surface 646 00:43:39.979 --> 00:43:43.379 So, there are perpendicular vectors to this surface 647 00:43:43.379 --> 00:43:45.959 These perpendicular vectors 648 00:43:45.959 --> 00:43:52.426 are called Normal Vectors or simply Normals 649 00:43:52.426 --> 00:43:58.838 This Normal Vector is already calculated within the hitInfo variable 650 00:43:58.839 --> 00:44:05.714 We will modify its forward direction 651 00:44:05.719 --> 00:44:16.829 to match the Normal Vector of the collided surface 652 00:44:19.868 --> 00:44:21.718 So, bulletImpact, 653 00:44:21.718 --> 00:44:24.760 transform.forward 654 00:44:24.760 --> 00:44:29.818 equals to hitInfo.normal; 655 00:44:32.920 --> 00:44:34.216 Save it 656 00:44:36.880 --> 00:44:39.726 Go back to the editor to play it 657 00:44:42.437 --> 00:44:45.187 Left click, 658 00:44:45.187 --> 00:44:50.400 and we get this impact effect 659 00:44:50.400 --> 00:44:52.200 Now, underHierarchy, 660 00:44:52.200 --> 00:44:54.950 the effect disappears after two seconds 661 00:44:54.950 --> 00:44:58.426 just as we see, like so 662 00:45:02.653 --> 00:45:05.753 When firing with Raycast, 663 00:45:05.753 --> 00:45:09.103 it's difficult to aim precisely 664 00:45:09.103 --> 00:45:13.003 To make targeting easier, we will add a UI element 665 00:45:13.003 --> 00:45:16.079 to serve as a crosshair at the center 666 00:45:16.079 --> 00:45:18.929 In the Hierarchy, click the + button 667 00:45:18.929 --> 00:45:21.779 Select UI > Image 668 00:45:21.779 --> 00:45:28.136 Rename the newly created Image to Crosshair 669 00:45:28.136 --> 00:45:31.036 In the Inspector, adjust: 670 00:45:31.036 --> 00:45:36.040 Width to 10, and Height to 10 671 00:45:36.040 --> 00:45:38.790 Change the color of the image 672 00:45:38.790 --> 00:45:43.000 to your preferred aiming color 673 00:45:43.000 --> 00:45:45.404 Save the scene and play again 674 00:45:45.404 --> 00:45:50.000 Now, you can use the red crosshair as a reference point 675 00:45:50.000 --> 00:45:53.150 when firing with Raycast 676 00:45:53.150 --> 00:45:55.350 This gives us the bullet impact effect 677 00:45:55.350 --> 00:45:58.280 exactly where we're aiming 678 00:45:58.280 --> 00:46:02.053 Let's go over what we have learned today 679 00:46:02.735 --> 00:46:03.785 Character Jumping Gravity applied to the player object: yVelocity += gravity * Time.deltaTime; dir.y = yVelocity; 680 00:46:03.785 --> 00:46:04.835 Jump when pressing the space bar: if (Input.GetButtonDown("Jump")) { yVelocity = jumpPower; } 681 00:46:04.835 --> 00:46:05.885 Reset yVelocity when the player is on the ground to ensure smooth falling: 682 00:46:05.885 --> 00:46:06.982 if (cc.isGrounded) { yVelocity = 0; } 683 00:46:06.982 --> 00:46:07.582 Throwable Weapon (Grenade) Create a Bomb object as a Prefab and throw it in the camera's direction when right-clicking: 684 00:46:07.582 --> 00:46:08.132 if (Input.GetMouseButtonDown(1)) (0): Returns true when the left mouse button is clicked 685 00:46:08.132 --> 00:46:08.632 (1): Returns true when the right mouse button is clicked (2): Returns true when the mouse wheel button is clicked 686 00:46:08.632 --> 00:46:09.232 Create a bomb from the bomb Prefab GameObject bomb = Instantiate(bombFactory); 687 00:46:09.232 --> 00:46:09.782 Place the created bomb at the firing position bomb.transform.position = firePosition.transform.position; 688 00:46:09.782 --> 00:46:10.332 Create the FirePosition object Add an empty GameObject to the Player 689 00:46:10.332 --> 00:46:10.882 Change the y-value of the FirePos object's transform position to 1.8 Drag and drop FirePos into the Fire Position of the Player object 690 00:46:10.882 --> 00:46:12.332 Launch in the direction the camera is facing Get the Rigidbody component from the created bomb Rigidbody rb = bomb.GetComponent(); 691 00:46:12.332 --> 00:46:13.732 Apply force using the retrieved component rb.AddForce(Camera.main.transform.forward * throwPower); 692 00:46:13.732 --> 00:46:15.106 Make the bomb disappear after collision OnCollisionEnter() function is called when a physical collision occurs Destroy(); 693 00:46:15.106 --> 00:46:15.706 Define the shooting weapon function Implement void FireRay() function to handle shooting Left mouse click → Fire a Ray and insert an impact effect at 694 00:46:15.706 --> 00:46:16.343 if (Input.GetMouseButtonDown(0)) Create a Ray moving from the camera position in the forward direction 695 00:46:16.343 --> 00:46:16.946 Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward); RaycastHit hitInfo; 696 00:46:16.946 --> 00:46:17.496 Fire the Ray using the Raycast function if (Physics.Raycast(ray, out hitInfo)) 697 00:46:17.496 --> 00:46:18.046 For collisions, if (Physics.Raycast(ray, out hitInfo) 698 00:46:18.046 --> 00:46:18.596 Create an impact effect GameObject bulletImpact = Instantiate(bulletImpactFactory); 699 00:46:18.596 --> 00:46:19.145 Place the created impact effect at the collision position bulletImpact.transform.position = hitInfo.point; 700 00:46:19.145 --> 00:46:20.345 Destroy the impact effect after 2 seconds to prevent clutter Destroy(bulletImpact, 2) 701 00:46:20.345 --> 00:46:21.495 The impact effect is insufficiently displayed when colliding with a wall 702 00:46:21.495 --> 00:46:22.683 Adjust the impact effect orientation to align with the normal vector of the hit surface bulletImpact.transform.forward = hitInfo.normal;