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.