All language subtitles for 1. Main Player Overview (GOOD)

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian Download
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 0 1 00:00:00,060 --> 00:00:02,150 Welcome to the main player functionality. 1 2 00:00:02,160 --> 00:00:09,930 In this video we will dive deep into the player and how its main functionalities actually work. Here, 2 3 00:00:09,930 --> 00:00:16,230 in the main scene there is the player instance, but the player is actually a scene in itself, so we're 3 4 00:00:16,230 --> 00:00:17,700 going to head right into it. 4 5 00:00:17,760 --> 00:00:20,190 What are the main functionalities of the player? 5 6 00:00:20,190 --> 00:00:21,300 And this is important. 6 7 00:00:21,300 --> 00:00:23,670 If I quickly play this. 7 8 00:00:24,760 --> 00:00:28,030 You'll see that the player can rotate the turret. 8 9 00:00:28,600 --> 00:00:29,750 It can move. 9 10 00:00:29,770 --> 00:00:30,940 With W, 10 11 00:00:30,970 --> 00:00:31,540 A 11 12 00:00:31,570 --> 00:00:31,990 S 12 13 00:00:31,990 --> 00:00:32,470 D 13 14 00:00:32,500 --> 00:00:34,090 And also the arrow keys. 14 15 00:00:35,330 --> 00:00:37,380 And also it can fire. 15 16 00:00:37,400 --> 00:00:42,410 The turret will move to a specific position where the cursor is pointed at. 16 17 00:00:43,190 --> 00:00:48,260 And if you press the leftmost button, the tank will fire. 17 18 00:00:48,860 --> 00:00:52,100 Basically these are the main functionalities of the player. 18 19 00:00:52,730 --> 00:00:57,190 There are a couple of hidden ones, for example, the turret animation. 19 20 00:00:57,200 --> 00:01:03,710 As you can see, the turret slightly moves back and also the tank body slightly moves back. 20 21 00:01:04,460 --> 00:01:09,020 And if I aim in the other direction, you see that it moves in the other direction. 21 22 00:01:09,410 --> 00:01:10,720 So this is also in place. 22 23 00:01:10,730 --> 00:01:13,420 This is basically a game polish thing. 23 24 00:01:13,430 --> 00:01:14,930 It's not a functionality. 24 25 00:01:15,380 --> 00:01:18,170 But we will also cover this in this episode. 25 26 00:01:19,040 --> 00:01:21,200 Okay, so let's deep dive. 26 27 00:01:22,190 --> 00:01:26,060 The player, as I mentioned, is a self-contained scene. Inside of it 27 28 00:01:26,090 --> 00:01:31,820 there are two main parts, the dynamic one or the moving one and the static one. 28 29 00:01:32,570 --> 00:01:39,980 And basically the moving one is the actual player mesh and the collision and things that the player 29 30 00:01:39,980 --> 00:01:43,460 actually moves when they press the keys. 30 31 00:01:44,330 --> 00:01:49,970 The systems part or the static one is the part that actually stays in place all the time. 31 32 00:01:50,630 --> 00:01:57,560 I took this decision because in some cases, some systems and some functionalities do require a fixed 32 33 00:01:57,560 --> 00:02:04,190 position in the scene, and instead of taking it out from the player, it's better to have it self-contained 33 34 00:02:04,190 --> 00:02:07,910 because they're in fact functionalities of the player. 34 35 00:02:08,120 --> 00:02:10,490 But we'll get into that a little later. 35 36 00:02:10,640 --> 00:02:13,010 As I mentioned, the player body is the moving part. 36 37 00:02:13,670 --> 00:02:14,870 What does it contain? 37 38 00:02:14,880 --> 00:02:16,790 Of course it has the player camera. 38 39 00:02:17,300 --> 00:02:20,750 And the camera is what actually makes the player visible. 39 40 00:02:20,960 --> 00:02:25,250 But in this scene, we have two cameras that you can cycle through. 40 41 00:02:25,760 --> 00:02:30,770 If I play it again and press [C] we have this big camera, which is actually a scene camera, 41 42 00:02:30,770 --> 00:02:32,180 and this is the player camera. 42 43 00:02:32,210 --> 00:02:35,210 This is your experience as the player camera. 43 44 00:02:35,660 --> 00:02:41,750 This camera moves the the player. The movement is done automatically because the camera is a child 44 45 00:02:41,750 --> 00:02:42,350 to the player. 45 46 00:02:42,360 --> 00:02:43,970 So that's easily fixed. 46 47 00:02:44,000 --> 00:02:47,840 Next we have the 3D mesh of the player. 47 48 00:02:47,900 --> 00:02:51,650 This is basically the 3D models that make the player up. 48 49 00:02:51,740 --> 00:02:55,760 We also have the collision shape, which is a box shape in this case. 49 50 00:02:55,850 --> 00:03:00,830 This handles the projectile collisions with the player, but also the collisions with the building. 50 51 00:03:00,830 --> 00:03:03,440 So we don't let the player go through the buildings. 51 52 00:03:03,470 --> 00:03:06,790 It also has an animation, which is the turret animation. 52 53 00:03:06,830 --> 00:03:08,810 We'll get into that a little later. 53 54 00:03:08,900 --> 00:03:10,670 And also an HP system. 54 55 00:03:10,850 --> 00:03:17,060 This will be discussed separately, but I aimed to have the systems as modular as possible so that 55 56 00:03:17,060 --> 00:03:19,010 you can use them in your own project. 56 57 00:03:19,040 --> 00:03:23,780 So basically this is just the drag and drop and basically you can do the same in your own project. 57 58 00:03:23,810 --> 00:03:29,740 The HP system is basically the only system right now that is in the player body. 58 59 00:03:29,750 --> 00:03:31,580 The other systems are in systems. 59 60 00:03:32,270 --> 00:03:39,140 And this is mainly due to the fact that when a projectile enters the collision with the kinematic body, 60 61 00:03:39,950 --> 00:03:44,600 it's easier to just get one of its nodes and check if it has the HP system. 61 62 00:03:44,600 --> 00:03:49,490 Otherwise I would have to parse all this player tree and get the HP system from the other part. 62 63 00:03:49,610 --> 00:03:51,470 And that would have been a little messy. 63 64 00:03:52,190 --> 00:03:57,980 Note that this structure will be followed exactly for the enemy as well, so that the projectile code 64 65 00:03:57,980 --> 00:04:02,510 doesn't need to change if it's the player that's hitting or the enemy that's hitting. 65 66 00:04:02,510 --> 00:04:09,500 The static part consists of the three remaining systems which are the player mover: handling the movement 66 67 00:04:09,500 --> 00:04:11,930 of the player, the targeting system: 67 68 00:04:12,050 --> 00:04:17,510 When the player moves the mouse around, the intersection between the plane and the mouse will be where 68 69 00:04:17,510 --> 00:04:23,390 the target is positioned. And the weapon system that handles the firing of the actual weapons. 69 70 00:04:23,570 --> 00:04:29,240 Now that you have a basic idea of how the player is structured, let's go from top to bottom and deep 70 71 00:04:29,240 --> 00:04:32,150 dive into each one of these and check them out. 71 72 00:04:32,210 --> 00:04:33,230 At the topmost level 72 73 00:04:33,230 --> 00:04:37,490 we have the player script, which is responsible for gluing everything together. 73 74 00:04:37,520 --> 00:04:41,660 What we have in here is of course, some parameters. 74 75 00:04:41,660 --> 00:04:47,210 And then one really important one is this meta "tag", which is type and player. 75 76 00:04:47,240 --> 00:04:50,030 This will be used for projectile collisions. 76 77 00:04:50,150 --> 00:04:56,330 There are two functions that handle the changing of the color of the player tank material. 77 78 00:04:56,330 --> 00:05:03,620 So init_color() which gets the current material from the mesh, I made it so that most of the materials 78 79 00:05:03,620 --> 00:05:04,850 are in the position zero. 79 80 00:05:04,880 --> 00:05:06,340 Then it duplicates (the material). 80 81 00:05:06,350 --> 00:05:11,460 One issue in Godot is the fact that the materials are shared between instances. 81 82 00:05:11,480 --> 00:05:14,630 It's really important that it gets duplicated. 82 83 00:05:14,630 --> 00:05:17,780 And then there is the second function called change_material(). 83 84 00:05:17,810 --> 00:05:23,000 This will actually go through the tank mesh and apply the highlight material, which is our new duplicated 84 85 00:05:23,000 --> 00:05:24,650 material to all the components. 85 86 00:05:24,680 --> 00:05:30,890 Once this is done, the highlight material will get its color change based on the team color specified 86 87 00:05:30,890 --> 00:05:31,510 in globals. 87 88 00:05:31,520 --> 00:05:34,580 So basically this is just a tint of green. The change_material, 88 89 00:05:35,230 --> 00:05:40,900 on the other hand, is a recursive function that means it calls itself and while calling itself, of 89 90 00:05:40,900 --> 00:05:47,080 course, it may call to infinity, but in this case, since the nodes of the mesh are limited, it won't 90 91 00:05:47,080 --> 00:05:48,460 call itself to infinity. 91 92 00:05:48,460 --> 00:05:50,020 So we are lucky if that. 92 93 00:05:50,080 --> 00:05:52,330 What it does, it takes the current tank mesh. 93 94 00:05:52,330 --> 00:05:55,480 In this case this one, and then it parses its children. 94 95 00:05:55,480 --> 00:06:01,930 The tank_turret_normal, tank_body and if the children is a mesh instance, then it will change the surface material 95 96 00:06:01,960 --> 00:06:05,170 to the material we specified, which is our new duplicated material. 96 97 00:06:05,180 --> 00:06:11,130 Note that there's one small hack here, and this is because one of my modelling mistakes: I assigned the 97 98 00:06:11,140 --> 00:06:15,160 material that we want to change on index one instead of zero. 98 99 00:06:15,190 --> 00:06:17,530 So this is not relevant if you do it correctly. 99 100 00:06:17,680 --> 00:06:20,920 Just take this out and just use the first one. 100 101 00:06:20,920 --> 00:06:26,200 Basically this is what it does and of course the change material calls itself, but it calls itself 101 102 00:06:26,200 --> 00:06:26,800 for the nodes. 102 103 00:06:26,800 --> 00:06:32,200 For example, we call it first here and then it's called for the tank_turret_normal and then for tank_body. 103 104 00:06:32,200 --> 00:06:38,620 It goes through these children and through these children as well. 104 105 00:06:38,920 --> 00:06:44,680 And once it doesn't have any more children, then these functions and all of the tree created by them 105 106 00:06:44,680 --> 00:06:49,300 goes up and up and up until it ends and the function eventually stops. 106 107 00:06:49,300 --> 00:06:54,700 Basically this is the logic for this one. Other than this, of course, we do have on_destroyed. 107 108 00:06:54,880 --> 00:07:02,050 And as you see here, we get the HP system and the HP system has this nice signal on destroyed which 108 109 00:07:02,050 --> 00:07:09,640 gets triggered when the HP system detects that the object that it's monitoring is finished, is done 109 110 00:07:09,760 --> 00:07:13,120 on_destroyed here gets called, of course we remove it. 110 111 00:07:13,420 --> 00:07:19,120 But before this we also remove the camera from the camera manager because we cannot allow the player 111 112 00:07:19,120 --> 00:07:21,160 to change the camera to an invalid camera. 112 113 00:07:21,820 --> 00:07:27,490 And here also the UI gets the show response screen, but this is just more visual stuff. 113 114 00:07:27,490 --> 00:07:30,340 Basically this is what we have at the topmost level. 114 115 00:07:30,340 --> 00:07:36,940 One last line here that I mentioned: that in on_destroyed the camera gets free from the camera manager. 115 116 00:07:37,030 --> 00:07:42,970 Of course, the camera first when the player gets instantiated, it needs to be registered to the camera 116 117 00:07:42,970 --> 00:07:43,540 manager. 117 118 00:07:43,540 --> 00:07:45,580 And this is the line that does this. 118 119 00:07:45,590 --> 00:07:51,130 Basically it tells the camera manager that's in the environment, hey, add new camera and basically 119 120 00:07:51,130 --> 00:07:56,500 it adds this player camera. And the camera manager basically has the list of cameras and the player can 120 121 00:07:56,500 --> 00:08:01,090 cycle through that list and choose the current camera via using the [C] (button). 121 122 00:08:01,090 --> 00:08:08,800 By the way, all of the buttons are assigned in project/input map/ and here are all of the possibilities. 122 123 00:08:08,800 --> 00:08:14,620 Move up, move down, left or right, fire, right mouse change camera, and hide_all. 123 124 00:08:14,920 --> 00:08:16,090 Don't worry about the camera. 124 125 00:08:16,090 --> 00:08:20,230 It will respond when the player gets respond and it'll call this again. 125 126 00:08:20,230 --> 00:08:21,820 So you don't have to worry about that. 126 127 00:08:21,850 --> 00:08:24,430 Now let's move to the next script, which is the camera script. 127 128 00:08:25,360 --> 00:08:28,900 And in here most of the code, if not all of it. 128 129 00:08:29,050 --> 00:08:37,150 And actually it's all of it is responsible for shaking the camera when a projectile hits the ground 129 130 00:08:37,150 --> 00:08:39,550 or hits the player or hits an obstacle. 130 131 00:08:39,970 --> 00:08:42,220 So basically, this is a shaking algorithm. 131 132 00:08:42,610 --> 00:08:49,060 What it does, it just moves the offsets of the camera so that, for example, I'm going to use the 132 133 00:08:49,070 --> 00:08:52,360 second camera so that I can show you. 133 134 00:08:52,360 --> 00:09:00,190 So if I do the preview and I do the H offset and the V offset, you see it, it moves the parameters 134 135 00:09:00,190 --> 00:09:00,610 like this. 135 136 00:09:00,610 --> 00:09:04,240 So the primary experience kind of for shakiness of the camera. 136 137 00:09:04,690 --> 00:09:06,460 So nothing fancy is just this. 137 138 00:09:06,460 --> 00:09:10,510 You just shake the camera when the projectile collision hits something. 138 139 00:09:10,510 --> 00:09:15,670 If you look into the tank mesh, we will find the components of the tank, the turret and the body they 139 140 00:09:15,670 --> 00:09:18,880 contain the 3D meshes that make the tank up beside the meshes. 140 141 00:09:18,880 --> 00:09:22,180 There are two other components that need to be there. 141 142 00:09:22,180 --> 00:09:26,470 First, there is the Farpoint, and second there is the tank turret position. 142 143 00:09:26,470 --> 00:09:28,750 Let's discuss a little about the fire point. 143 144 00:09:28,750 --> 00:09:32,440 Basically, what the fire plan does is just the position 3D node. 144 145 00:09:32,440 --> 00:09:37,770 It's nothing visual, but it tells where exactly the projectile should get spotted. 145 146 00:09:37,780 --> 00:09:44,110 So this is really important because the weapon manager needs to know where it just upon the projectile 146 147 00:09:44,110 --> 00:09:47,470 and it should not be the target position, which is you can see it's here. 147 148 00:09:47,470 --> 00:09:50,830 So we don't want the projectile to be spawn here, Mr. Bond here. 148 149 00:09:51,310 --> 00:09:54,490 And there are some other cases, like some other turret types. 149 150 00:09:54,490 --> 00:10:01,660 We actually have more fired points and the weapon manager responsible for that will actually cycle through 150 151 00:10:01,660 --> 00:10:05,110 each file point and fire the projectiles accordingly. 151 152 00:10:05,110 --> 00:10:10,720 Lastly, we need the tank turret position to be specified on the body because the tank turret moves 152 153 00:10:10,720 --> 00:10:17,980 a lot separately from the body and as one of the last steps of the adjusting the turret to its new position 153 154 00:10:17,980 --> 00:10:23,800 is setting it up exactly on the body because as you see, the body also moves. 154 155 00:10:23,800 --> 00:10:27,340 So it's not really that hard to get them out of sync. 155 156 00:10:27,340 --> 00:10:30,640 And lastly, the collision shape is just the collision box. 156 157 00:10:30,850 --> 00:10:34,440 And this also gets adjusted in code because the tank. 157 158 00:10:34,500 --> 00:10:36,780 The body needs to be synchronized with the collision shape. 158 159 00:10:36,780 --> 00:10:42,420 And the question shape needs to be the child of player body, because this is the kinematic body. 159 160 00:10:42,420 --> 00:10:46,080 The animation player holds basically the animation of the turret moving. 160 161 00:10:46,200 --> 00:10:51,120 But here instead of moving the turret on the z-axis, we actually move just the parameter. 161 162 00:10:51,120 --> 00:10:57,960 And this is because for example, if the turret has this position and it moves on the z-axis, it's 162 163 00:10:57,960 --> 00:11:02,670 not the local one, it'll be the global one and it'll move like this. 163 164 00:11:03,120 --> 00:11:10,080 So to fix this, what I did was just the short here animator a parameter, and that parameter gets added 164 165 00:11:10,080 --> 00:11:11,660 to the correct direction. 165 166 00:11:11,670 --> 00:11:17,550 Now let's look at the systems that make the player work, and let's start with the mouse target, because 166 167 00:11:17,550 --> 00:11:18,630 this one is the smallest. 167 168 00:11:19,650 --> 00:11:24,210 So in here, as you see, it's just the 22 lines of code. 168 169 00:11:24,210 --> 00:11:25,460 So nothing special. 169 170 00:11:25,470 --> 00:11:28,230 But what it does here, it takes the current active camera. 170 171 00:11:28,350 --> 00:11:33,510 So regardless if it's the top down camera or the player camera gets referenced here, basically what 171 172 00:11:33,510 --> 00:11:39,870 the script does is create the array from the cursor on the screen to a position in the world and then 172 173 00:11:39,870 --> 00:11:42,000 checks if there was an intersection. 173 174 00:11:42,060 --> 00:11:47,910 So we first need to get the mouse position and we create the array out of that one. 174 175 00:11:47,910 --> 00:11:53,970 And then we use the space state, which is good of functionality to be able to intersect the array. 175 176 00:11:53,970 --> 00:11:59,520 And if there was an intersection then we need to put up the lookup position and this one will be used 176 177 00:11:59,520 --> 00:12:01,260 to actually move the turret around. 177 178 00:12:02,100 --> 00:12:05,520 But there's also a debug function and then this is just a small target. 178 179 00:12:05,520 --> 00:12:06,570 It's invisible now. 179 180 00:12:06,780 --> 00:12:10,590 But if we added a mesh, let's say cylinder mesh, it doesn't matter. 180 181 00:12:11,590 --> 00:12:12,190 And save it. 181 182 00:12:13,600 --> 00:12:17,320 We can see actually where the cursor points on the screen. 182 183 00:12:17,320 --> 00:12:20,800 So this is just for debug purposes, it doesn't have any use. 183 184 00:12:22,560 --> 00:12:22,950 Okay. 184 185 00:12:22,980 --> 00:12:26,880 Now let's remove this because we don't want this functionality. 185 186 00:12:27,690 --> 00:12:29,700 So now let's head over to the weapon system. 186 187 00:12:29,700 --> 00:12:36,270 And what the weapon system does is basically first it gathers input from the player, which is the leftmost 187 188 00:12:36,270 --> 00:12:36,660 button. 188 189 00:12:36,660 --> 00:12:40,680 When it's clicked, instantiate a projectile at the tip of the turret. 189 190 00:12:40,800 --> 00:12:46,580 It handles the cooling down or the reload rate and also plays some animations and effects. 190 191 00:12:46,590 --> 00:12:50,610 Let's go into it and see how this all works. 191 192 00:12:50,880 --> 00:12:55,860 So the first thing that this group does when it initializes, it takes all the turret children and checks 192 193 00:12:55,860 --> 00:13:00,000 if they're five points, basically, if their name has five point in their name. 193 194 00:13:00,480 --> 00:13:05,790 And this is because, as I mentioned, if the turret has multiple fire points, it will cycle through 194 195 00:13:05,790 --> 00:13:06,540 each one of them. 195 196 00:13:07,140 --> 00:13:09,660 And these are the two variables that handle this. 196 197 00:13:09,660 --> 00:13:13,770 So the fire point is actually a list that will contain all the fire points. 197 198 00:13:14,250 --> 00:13:19,920 And the fire point index is basically a number telling which fire point should be fired at this moment. 198 199 00:13:19,980 --> 00:13:23,220 Next, we get the animation player, which is this one. 199 200 00:13:23,460 --> 00:13:25,650 So we need to go up two levels. 200 201 00:13:25,650 --> 00:13:29,130 So the first one would be systems and the second one would be player. 201 202 00:13:29,550 --> 00:13:32,820 And then we need to go into the player body and then the animation player. 202 203 00:13:33,510 --> 00:13:36,030 So this is how we get referenced in animation player. 203 204 00:13:36,510 --> 00:13:40,110 Of course this is hardcoded, but since this won't change, it's fine. 204 205 00:13:41,260 --> 00:13:41,620 Next. 205 206 00:13:41,620 --> 00:13:43,270 We also hook the weapon. 206 207 00:13:43,270 --> 00:13:44,200 Cool, long timer. 207 208 00:13:44,560 --> 00:13:51,100 And the weapon called Long Timer is basically just the go to timer that has specified a wait time and 208 209 00:13:51,310 --> 00:13:52,050 one shot. 209 210 00:13:52,060 --> 00:13:58,060 It doesn't auto start because we want to make sure when the weapon coolant actually happens in the process, 210 211 00:13:58,060 --> 00:14:01,330 which happens every single frame, we just need to check out. 211 212 00:14:01,330 --> 00:14:07,240 If the fire was pressed and if it was, then of course we need to actually fire the projectile. 212 213 00:14:07,240 --> 00:14:10,420 And what happens when we fire a projectile? 213 214 00:14:10,450 --> 00:14:15,400 Well, first we need to check if it's not actually cooling down, because if it is cooling down, we 214 215 00:14:15,400 --> 00:14:17,380 don't want to fire another projectile. 215 216 00:14:17,980 --> 00:14:24,640 Otherwise the player can just spam the leftmost button and it will fire projectiles in. 216 217 00:14:24,640 --> 00:14:30,220 Definitely one thing here, the action just press that means that it needs to be released. 217 218 00:14:30,220 --> 00:14:39,670 If we use is is action press then we can make this work just by holding the most button so I don't have 218 219 00:14:39,670 --> 00:14:41,110 to actually release it. 219 220 00:14:41,110 --> 00:14:48,130 I can just hold it and the player will shoot at the fire rate that we specified in the timer, which 220 221 00:14:48,130 --> 00:14:50,140 is 0.5 seconds. 221 222 00:14:50,500 --> 00:14:51,700 Actually, this is better. 222 223 00:14:51,700 --> 00:14:52,780 So I leave it like this. 223 224 00:14:55,070 --> 00:14:57,530 So what happens when it's not cooling down? 224 225 00:14:57,620 --> 00:14:59,490 Well, two things happen. 225 226 00:14:59,510 --> 00:15:04,560 First, we instantiate the projectile, and then we restart the cooling down functionality. 226 227 00:15:04,580 --> 00:15:07,310 So let's look at the instantiate projectile. 227 228 00:15:07,370 --> 00:15:11,840 So here we need to take the projectile prefab, which is specified here. 228 229 00:15:12,020 --> 00:15:15,980 So export variables are variables that are visible here. 229 230 00:15:16,490 --> 00:15:22,940 And the projectile prefab is just another different good option that's being dragged up from the file 230 231 00:15:22,940 --> 00:15:24,110 system into here. 231 232 00:15:25,840 --> 00:15:29,650 And we use instance to create the new instance of that projectile. 232 233 00:15:30,370 --> 00:15:33,580 Once you do this, the projectile is not actually in the scene. 233 234 00:15:33,760 --> 00:15:40,870 So by using get three root get child, you actually get the main scene route. 234 235 00:15:41,500 --> 00:15:44,750 And why don't we just add the child here? 235 236 00:15:44,770 --> 00:15:47,890 Well, we could add the child here, and technically it should work. 236 237 00:15:47,980 --> 00:15:54,490 But just to make sure it's better to edit at the root level because of the transforms and the position 237 238 00:15:54,490 --> 00:16:01,210 and we have a deep hierarchy of nodes if one no changes the position, for example, when the developer 238 239 00:16:01,210 --> 00:16:08,380 moves the player like this, well, the whole hierarchy inside will actually get position changes because 239 240 00:16:08,380 --> 00:16:08,860 of this. 240 241 00:16:09,250 --> 00:16:16,810 So in order to avoid any kind of issues, we just add it to the main route so that we know that zero 241 242 00:16:16,810 --> 00:16:21,160 is always zero and vector 3.0 is hold is 000. 242 243 00:16:21,280 --> 00:16:27,190 Next we get the current farpoint and as I mentioned, the Farpoint index cycles through all the five 243 244 00:16:27,190 --> 00:16:30,100 points and we need to do the cycling as well. 244 245 00:16:30,580 --> 00:16:36,430 So of course we actually increase the Farpoint index only if we have multiple far points. 245 246 00:16:37,390 --> 00:16:41,050 And then if it reaches the five point position, that means the last one. 246 247 00:16:41,500 --> 00:16:47,110 Then we need to go back to zero and then restart the counting from the beginning. 247 248 00:16:48,670 --> 00:16:53,080 So once we have this in place, we can properly initialize the projectile. 248 249 00:16:53,830 --> 00:16:57,230 And the the projectile in show zation has multiple steps. 249 250 00:16:57,250 --> 00:17:02,170 Of course we need the current fire point, which will give the projectile its initial position and rotation. 250 251 00:17:02,260 --> 00:17:06,700 It'll also give the lookout position, which is the most target. 251 252 00:17:06,730 --> 00:17:11,150 And this is important because the projectile needs to be aimed at this position. 252 253 00:17:11,170 --> 00:17:16,360 The damage can be specified at the projectile level, but it can also be specified that the player level 253 254 00:17:16,360 --> 00:17:17,290 for simplicity. 254 255 00:17:17,320 --> 00:17:23,020 So if you have multiple objects that get instantiated in the player, if you put it up to the player 255 256 00:17:23,020 --> 00:17:25,720 level, then it's easier to customize everything inside. 256 257 00:17:25,750 --> 00:17:29,210 Next, we also specify the color of the project that lands. 257 258 00:17:29,230 --> 00:17:35,290 Since we know this functionality is just for the player we can hardcoded to green team color because 258 259 00:17:35,290 --> 00:17:36,410 the player is green. 259 260 00:17:36,430 --> 00:17:41,260 And lastly, we get the player body, which is the kinematic object. 260 261 00:17:41,260 --> 00:17:47,110 And this is important because we want to avoid the collision from the projectile to the actual player. 261 262 00:17:47,170 --> 00:17:52,180 So by checking for the collisions with the parent and removing them from the beginning. 262 263 00:17:53,300 --> 00:18:00,770 Lastly, in this function, we do a smoke and a muzzle effect and those two are just the visual effects 263 264 00:18:01,370 --> 00:18:05,750 and they spawn at the current fire point and the current fire point origin. 264 265 00:18:05,840 --> 00:18:11,270 So basically nothing special, just the VFX manager handling some nice VFX for us. 265 266 00:18:12,710 --> 00:18:16,910 Next we have the start cooling down and the start cooling down. 266 267 00:18:16,940 --> 00:18:20,150 Basically a variable that tells, okay, now it's cooling down. 267 268 00:18:21,290 --> 00:18:28,070 Then we do a random number generator and this is just for to make it a little different every single 268 269 00:18:28,070 --> 00:18:28,420 time. 269 270 00:18:28,430 --> 00:18:37,970 So this actual wait time doesn't matter because we specify the cooldown from 0.30 5 seconds to 0.70 270 271 00:18:37,970 --> 00:18:43,160 5 seconds and they do a random between them and then we start to call them with that value in place. 271 272 00:18:43,190 --> 00:18:46,070 Of course, we also play the animation turret fire. 272 273 00:18:46,340 --> 00:18:48,360 This could happen at any point. 273 274 00:18:48,380 --> 00:18:52,460 Of course not before this, but here should be also fine to be played. 274 275 00:18:53,270 --> 00:18:58,340 And basically these are the functionalities that make up the weapon system handling the shooting for 275 276 00:18:58,340 --> 00:18:58,750 the player. 276 277 00:18:58,760 --> 00:19:03,470 Now that we know how the targeting and the firing works, let's have a look at how the player moves. 277 278 00:19:03,500 --> 00:19:06,350 To do this, we need to head over to the player mover. 278 279 00:19:06,350 --> 00:19:11,930 And this one is a little big, but don't worry because it's very nicely separated. 279 280 00:19:11,990 --> 00:19:16,630 This will be easily accessible for everyone interested in finding out more how the player moves. 280 281 00:19:16,640 --> 00:19:22,100 But before we dive deep into it, we need to understand what are the exact functionalities of this strip? 281 282 00:19:22,110 --> 00:19:27,170 First it moves the tank up, down, left and right, and please note that these are no top down, left 282 283 00:19:27,170 --> 00:19:28,160 or right for the tank. 283 284 00:19:28,160 --> 00:19:34,190 But from the perspective of 45 degrees, you will understand what this means a little later when we 284 285 00:19:34,190 --> 00:19:35,150 actually see the code. 285 286 00:19:35,150 --> 00:19:36,860 It also applies the gravity. 286 287 00:19:36,860 --> 00:19:42,590 In this case, it's not really necessary because the whole thing is flat, but it does apply gravity. 287 288 00:19:42,590 --> 00:19:47,990 So in case your terrain has hills or valleys, it will work as good as on the flat one. 288 289 00:19:48,020 --> 00:19:53,470 It also what is the turret towards the most intersection the world from the most targeting system and 289 290 00:19:53,510 --> 00:19:57,170 also applies some nice rotations when the tank fires. 290 291 00:19:57,170 --> 00:20:02,480 They're not important functionality wise, but they're important visual wise for the player to actually 291 292 00:20:02,480 --> 00:20:05,260 feel the power when the tank actually fires. 292 293 00:20:05,260 --> 00:20:11,510 So here we just get some parameters in the ready, but everything gets processed in the physics process 293 294 00:20:11,510 --> 00:20:18,290 and it's nicely put in different functions and we'll go into each one of them and see how it works. 294 295 00:20:18,890 --> 00:20:23,090 So first we need to process that direction and get it into this vector. 295 296 00:20:24,080 --> 00:20:27,260 And the direction is basically where the tank is headed. 296 297 00:20:27,260 --> 00:20:32,750 If the player presses one of the following keys, move up, down, left or right specified in the player 297 298 00:20:32,750 --> 00:20:34,070 input in the configuration. 298 299 00:20:34,070 --> 00:20:41,150 So here the tank doesn't move forward back from its own position, but rather if we go to the demo scene 299 300 00:20:41,150 --> 00:20:45,950 and we go to the camera, you can see that here is the tank. 300 301 00:20:46,610 --> 00:20:51,170 So it moves up from the screen, down from the screen, left and right. 301 302 00:20:51,170 --> 00:20:54,410 And these adjustments are actually made in code like this. 302 303 00:20:54,410 --> 00:21:01,700 So for example, if we move up, it's a combination between vector left and vector back divided by two. 303 304 00:21:01,700 --> 00:21:07,850 What gets returned by this process direction is a normalized vector, and that means the vector fling 304 305 00:21:07,850 --> 00:21:10,670 F1 specifying the direction or zero. 305 306 00:21:10,790 --> 00:21:16,640 If the player doesn't press any key where the tank should move next, we need to process the turret 306 307 00:21:16,850 --> 00:21:21,140 and this one does the turret rotation towards the target position. 307 308 00:21:22,470 --> 00:21:24,390 Let's look how this happens. 308 309 00:21:25,170 --> 00:21:32,550 So first we get the target position and as I mentioned, we get the most target and target. 309 310 00:21:32,970 --> 00:21:39,330 And is this one we actually could have gotten it from the code since we have look at the position. 310 311 00:21:39,750 --> 00:21:45,420 So instead of getting the target, we could just get the most target and value look at position. 311 312 00:21:46,230 --> 00:21:47,520 And this is actually better. 312 313 00:21:48,900 --> 00:21:49,440 So I'm going to. 313 314 00:21:50,620 --> 00:21:51,610 Fix this right now. 314 315 00:21:57,950 --> 00:21:59,120 And why is this better? 315 316 00:21:59,150 --> 00:22:02,570 Well, it's because this is mostly for debugging purposes. 316 317 00:22:02,570 --> 00:22:08,060 And if you say, okay, now I'm removing the debug stuff and this gets removed, then this won't work 317 318 00:22:08,060 --> 00:22:08,480 anymore. 318 319 00:22:08,510 --> 00:22:14,570 So it's very important to make it work without the debug as well as with the debug functionality. 319 320 00:22:14,580 --> 00:22:16,940 We need to preserve the scale of the turret. 320 321 00:22:17,390 --> 00:22:24,050 And this is important because all of the transforms that means the position, the rotation and the scale 321 322 00:22:24,110 --> 00:22:30,380 do happen when using different functions on transform, and sometimes the scale might also get messed 322 323 00:22:30,380 --> 00:22:30,590 up. 323 324 00:22:30,600 --> 00:22:34,150 So we need to preserve it and then reapply it a little later. 324 325 00:22:34,160 --> 00:22:37,760 So first we preserve it and then we generate the new transform. 325 326 00:22:37,760 --> 00:22:44,090 So it's not actually we don't use the look that we use looking at which will actually give the new transform 326 327 00:22:44,090 --> 00:22:45,440 to the target position. 327 328 00:22:45,530 --> 00:22:51,800 And this is important because I'm using this interpolate we have, which makes the turret move slowly 328 329 00:22:51,800 --> 00:22:57,850 or smoothly towards the final rotation instead of directly moving to that particular position. 329 330 00:22:57,860 --> 00:23:00,110 And this gives a nice feel for the player. 330 331 00:23:00,140 --> 00:23:02,840 Once this is finished, of course, we reapplied the skill. 331 332 00:23:03,860 --> 00:23:10,910 And also unwanted rotations, because, for example, if we remove one of these and we point close to 332 333 00:23:10,910 --> 00:23:13,760 the tank, the turtle also points down. 333 334 00:23:13,760 --> 00:23:15,300 So we might avoid this. 334 335 00:23:15,320 --> 00:23:21,950 But in case your game has heels and the third needs to rotate up or down, you might want to remove 335 336 00:23:21,950 --> 00:23:28,820 these rotations, or at least the one that handles up and down movement so that the turret can properly 336 337 00:23:28,820 --> 00:23:29,300 rotate. 337 338 00:23:29,300 --> 00:23:30,890 The other one will tilt the turret. 338 339 00:23:30,890 --> 00:23:34,250 So it should always be zero because the turret cannot possibly tilt. 339 340 00:23:34,280 --> 00:23:35,410 Okay, Leslie, here. 340 341 00:23:36,080 --> 00:23:43,940 Once we set up the look at position, as I mentioned, in the tank mesh, we have the tank third position, 341 342 00:23:43,940 --> 00:23:46,850 which needs to be synchronized as the final third position. 342 343 00:23:46,850 --> 00:23:48,560 So we need to set that in place. 343 344 00:23:48,710 --> 00:23:50,360 This is the final third position. 344 345 00:23:50,810 --> 00:23:57,470 But on top of this, we also have getting the turret forward vector which is this long line and multiply 345 346 00:23:57,470 --> 00:24:03,920 this by the turret animation forward and this is the value that gets animated by the animation player 346 347 00:24:04,400 --> 00:24:06,920 and originally it's just zero. 347 348 00:24:07,400 --> 00:24:11,030 So all of this is not used. 348 349 00:24:11,030 --> 00:24:17,150 So the turret gets positioned right on top of the tank body, but when the turret actually fires, then 349 350 00:24:17,150 --> 00:24:18,860 the small animation gets played. 350 351 00:24:18,860 --> 00:24:24,260 So this value changes from 0 to 1, so the turret slightly moves back and forth. 351 352 00:24:24,260 --> 00:24:30,590 So if we quickly play it, you see that the turret doesn't doesn't move forward or back, but if we 352 353 00:24:30,890 --> 00:24:34,340 fire, the turret starts moving forward and back. 353 354 00:24:34,340 --> 00:24:37,370 So this happens because of this line. 354 355 00:24:37,520 --> 00:24:41,750 So now that we have the turret rotation, we can move to the tank. 355 356 00:24:42,900 --> 00:24:43,740 Rotation as well. 356 357 00:24:44,490 --> 00:24:45,940 So the tank rotation. 357 358 00:24:46,050 --> 00:24:47,130 What does it do? 358 359 00:24:47,160 --> 00:24:50,160 It basically rotates the tanks, buddy. 359 360 00:24:50,280 --> 00:24:51,690 So not the whole thing. 360 361 00:24:51,780 --> 00:24:53,420 It just rotates the tank mesh. 361 362 00:24:53,430 --> 00:24:58,890 And this part just the tank by the from the tank mesh because as I said, the turret rotates separately 362 363 00:24:58,890 --> 00:25:02,700 and we don't want to get involved in the player body because some other systems are here. 363 364 00:25:02,850 --> 00:25:05,340 So when does this rotation happen? 364 365 00:25:05,610 --> 00:25:12,830 Of course, we need to make sure that the direction vector is actually a length of greater than zero, 365 366 00:25:12,840 --> 00:25:16,820 because if it's zero, then that means the player didn't press any key. 366 367 00:25:16,830 --> 00:25:22,770 And if a key was pressed, then the direction is either up or down, left or right relative to the tank. 367 368 00:25:23,310 --> 00:25:29,700 And the player body needs to look at that new position and we do the same as with the turret. 368 369 00:25:29,700 --> 00:25:36,120 So we use the looking at to generate the new transform and then we do nice interpolation of that. 369 370 00:25:36,810 --> 00:25:40,200 We have a 2.5 multiplied by Delta. 370 371 00:25:40,230 --> 00:25:43,000 This will assure a nice smooth rotation. 371 372 00:25:43,020 --> 00:25:46,530 Of course you can change this value to make it rotate faster or slower. 372 373 00:25:46,650 --> 00:25:52,170 Of course, to reset the zero rotation to make sure that the tank doesn't rotate up or down as well. 373 374 00:25:52,200 --> 00:25:57,360 Though if would play this, if you look closely at the tank body, if I press up. 374 375 00:25:58,880 --> 00:26:00,320 It doesn't move directly. 375 376 00:26:00,620 --> 00:26:01,400 It moves. 376 377 00:26:02,780 --> 00:26:05,900 It moves with a certain rotation speed. 377 378 00:26:07,850 --> 00:26:09,800 You see how the body moves? 378 379 00:26:10,400 --> 00:26:12,920 It moves so smoothly because of that interpolation. 379 380 00:26:13,400 --> 00:26:18,890 So if you change the value from 2.5 to another one, it will move either slow or fast based on that. 380 381 00:26:20,960 --> 00:26:25,070 So this this doesn't actually move the player. 381 382 00:26:25,100 --> 00:26:27,650 It just rotates the tank, buddy. 382 383 00:26:28,100 --> 00:26:30,890 The player movement happens in the next function. 383 384 00:26:32,350 --> 00:26:39,190 So here, if we go back, this was the tank by the rotation and the move tank is actually what moves 384 385 00:26:39,190 --> 00:26:39,700 the tank. 385 386 00:26:40,900 --> 00:26:42,850 So here, of course, you know the drill. 386 387 00:26:43,000 --> 00:26:49,360 If the lack of direction is greater than zero, then this means we actually have movement and this means 387 388 00:26:49,360 --> 00:26:50,830 we actually have a velocity. 388 389 00:26:50,830 --> 00:26:57,370 And I don't want the velocity to be instantaneously fast or slow. 389 390 00:26:57,790 --> 00:27:01,090 So for this actually opted for acceleration and friction. 390 391 00:27:01,150 --> 00:27:05,790 So what it does it linearly interpolate what the interpolation does. 391 392 00:27:05,800 --> 00:27:09,130 It takes the current velocity value, which in this case should be zero. 392 393 00:27:09,940 --> 00:27:17,800 And the maximum speed, the direction, times speed and the acceleration is what we are multiplying 393 394 00:27:17,800 --> 00:27:21,530 with at every frame to get that velocity to that point. 394 395 00:27:21,550 --> 00:27:27,330 So basically with this, the tank will accelerate to its maximum speed, which is the speed. 395 396 00:27:27,370 --> 00:27:30,800 If there is no quick press, then it will decelerate with the friction. 396 397 00:27:30,820 --> 00:27:35,380 Of course you could have used acceleration, but that would have been weird because as you know, a 397 398 00:27:35,380 --> 00:27:40,690 car might accelerate at different rate as it slows down with the friction. 398 399 00:27:41,320 --> 00:27:48,010 Of course, velocity on the y axis is always -15 or whatever gravity you want to put into this. 399 400 00:27:48,190 --> 00:27:51,220 And lastly, we use the moving slide functionality from Godot. 400 401 00:27:51,220 --> 00:27:54,370 And here we specify the velocity that we just calculated. 401 402 00:27:54,580 --> 00:27:56,170 So this is just the vector three. 402 403 00:27:56,590 --> 00:28:03,040 We have its x and Z components based on the direction and the Y component based on the gravity. 403 404 00:28:03,580 --> 00:28:05,350 And also we need the up vector here. 404 405 00:28:05,950 --> 00:28:08,020 So this will handle the tank movement. 405 406 00:28:09,770 --> 00:28:12,790 And lastly, we have the preposition collision shape. 406 407 00:28:12,800 --> 00:28:20,090 And what this does is actually move and rotate the collision shape to fit the new player position. 407 408 00:28:20,300 --> 00:28:21,350 Why is this relevant? 408 409 00:28:21,380 --> 00:28:23,570 Well, let's see if I comment this line. 409 410 00:28:24,480 --> 00:28:27,510 And they use debug visible collision shapes. 410 411 00:28:28,170 --> 00:28:32,420 Press F5 And as you see, the collision shape is okay right now. 411 412 00:28:32,430 --> 00:28:35,810 But if I move it like this, oh, the collision shape is not in work. 412 413 00:28:36,300 --> 00:28:41,610 So if we go for object, you see that the tank goes through buildings because the collision shape is 413 414 00:28:41,610 --> 00:28:42,390 basically wrong. 414 415 00:28:43,440 --> 00:28:51,990 So if I d comment this back and now we can see that the collision shape nicely moves with the tank. 415 416 00:28:51,990 --> 00:28:54,810 So this is the behavior that we are looking for. 416 417 00:28:54,840 --> 00:28:56,910 So how does the reposition collision shape work? 417 418 00:28:57,540 --> 00:29:03,900 Well, we simply put the new origin of the collision shape to the player tank by the origin, and then 418 419 00:29:03,900 --> 00:29:07,290 we move it slightly on the forward vector. 419 420 00:29:07,860 --> 00:29:10,760 So please know that the fore vector is this with minus. 420 421 00:29:10,770 --> 00:29:13,920 So I'm just putting the minus here in this case. 421 422 00:29:14,850 --> 00:29:16,410 And this is not divide. 422 423 00:29:16,440 --> 00:29:25,320 This is just to go to the next line, because we add this also on the Y axis, because otherwise the 423 424 00:29:25,320 --> 00:29:27,510 collision will go for the floor and we need to be careful. 424 425 00:29:27,510 --> 00:29:28,230 It doesn't do that. 425 426 00:29:28,800 --> 00:29:30,840 We also need to sync the rotation. 426 427 00:29:30,990 --> 00:29:36,620 So this is the slide for this is what makes the collision shape synchronized correctly with the tank 427 428 00:29:36,630 --> 00:29:37,020 body. 428 429 00:29:37,050 --> 00:29:43,500 And lastly, we do have the helper functionality which checks if that is on the on the tank side or 429 430 00:29:43,500 --> 00:29:43,920 the other. 430 431 00:29:45,150 --> 00:29:48,930 And this was responsible for the. 431 432 00:29:50,040 --> 00:29:51,840 The tank body rotation. 432 433 00:29:52,830 --> 00:29:55,650 So this is actually for visual purposes. 433 434 00:29:55,650 --> 00:29:58,320 This is why I haven't been into this before. 434 435 00:29:59,070 --> 00:30:02,430 But what this does, it checks if it's on one side. 435 436 00:30:02,640 --> 00:30:05,280 So this is the X or minus X. 436 437 00:30:05,490 --> 00:30:07,020 So basically left or right side. 437 438 00:30:07,920 --> 00:30:15,210 And if it's one or the other, then it gets thanked by the rotate, which is also a value that gets 438 439 00:30:15,210 --> 00:30:19,860 changed by the animate there when the firing sequence happens and the trot is the tank, by the way, 439 440 00:30:19,860 --> 00:30:22,050 like this or like this. 440 441 00:30:23,380 --> 00:30:24,970 So how does this work quickly? 441 442 00:30:25,000 --> 00:30:25,390 Well. 442 443 00:30:26,540 --> 00:30:29,770 It's a little complex, but I'm going to quickly show it. 443 444 00:30:29,780 --> 00:30:37,550 So first it takes the thing by the opposition and then we get the target, which is the tank turret 444 445 00:30:38,030 --> 00:30:44,000 position and then we get the forward vector of the tank turret. 445 446 00:30:44,000 --> 00:30:48,010 So basically this is where the tank is pointing towards. 446 447 00:30:48,020 --> 00:30:54,740 So now we have a position forward from the tank turret and the current position and this will give us 447 448 00:30:54,740 --> 00:30:55,850 the reference vector. 448 449 00:30:56,330 --> 00:31:03,140 So basically this is just the vector from the tank origin to where the turret is pointing towards multiplied 449 450 00:31:03,140 --> 00:31:03,560 five. 450 451 00:31:04,770 --> 00:31:10,020 And of course, you need to normalize this and the phrase the DOT product and this is a nice functionality 451 452 00:31:10,020 --> 00:31:11,070 for Will because. 452 453 00:31:13,190 --> 00:31:19,340 The DOT product will be zero for a straight angle and greater than zero for angles, narrower than 90 453 454 00:31:19,340 --> 00:31:22,970 degrees and lower for wider angles. 454 455 00:31:23,690 --> 00:31:33,740 So we can check this dot product result of the difference vector to see if it if it's between an angle 455 456 00:31:33,740 --> 00:31:34,250 or not. 456 457 00:31:34,790 --> 00:31:41,900 And what this does in and in practice is that, for example, the angle now is a position that we want. 457 458 00:31:42,230 --> 00:31:47,480 But as we move inside, you'll see, oh, the animation stopped. 458 459 00:31:47,480 --> 00:31:50,900 So here it's where the angle for this side stopped. 459 460 00:31:52,090 --> 00:31:54,160 And then if I move. 460 461 00:31:54,460 --> 00:31:55,210 If I move. 461 462 00:31:58,430 --> 00:31:58,720 Now. 462 463 00:31:58,840 --> 00:31:59,970 Now, the animation started. 463 464 00:32:00,000 --> 00:32:00,560 So this is. 464 465 00:32:02,380 --> 00:32:04,800 This is basically the value that you are calculating. 465 466 00:32:04,810 --> 00:32:06,040 So this one is the value. 466 467 00:32:07,270 --> 00:32:16,030 And if the normal that the product, the value of this one is within the range, that it will it will 467 468 00:32:17,200 --> 00:32:18,570 give us the result we wanted. 468 469 00:32:18,580 --> 00:32:20,320 If not, nothing will happen. 469 470 00:32:20,950 --> 00:32:23,230 So basically this is what this function does as well. 470 471 00:32:23,440 --> 00:32:25,270 So this is the player functionality. 471 472 00:32:25,270 --> 00:32:26,470 I hope you liked it. 472 473 00:32:27,160 --> 00:32:31,390 It's a little big and some of it is just for polishing. 473 474 00:32:31,390 --> 00:32:33,370 So it's not for functionality. 474 475 00:32:33,370 --> 00:32:38,830 But do remember that in finalized game products this is super important. 475 476 00:32:38,830 --> 00:32:42,550 So make sure that your game has visual effects like these. 476 477 00:32:42,760 --> 00:32:44,260 This is it for this video. 50611

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.