Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
The anime topic is quite big to tackle this.
It's best to split it up in different functionalities.
In this video, we will look into the enemy scene structure as well as the main script powering all
the enemies.
Let's begin with the scene and if you check the main player functionality, you'll notice the resemblance.
We have a dynamic part, which is the tank and a static one, which is the systems and the final state
machine.
The then image one consists of the tanks kinematic body, while the static one, basically the one that
doesn't move, has all the systems that are responsible for various functionalities as well as the final
state machine controllers.
Looking inside the tank, we can find the actual 3D mesh, its collision shape that is required by the
kinematic body.
And we have two systems here, the communicator and the HP system that need to be here because they
are called when a collision happens and the collision happens with this kinematic body and this is why
we have them here, because it's easier to use and to have a similar structure with the player inside
the tank mesh.
We have two important functionalities that are extra.
Besides the 3D stuff in the tank turret, we have a five point or multiple five points basically from
this is what the actual instantiated projectile spawns from.
And in some cases, if the turret has multiple points that can spawn projectiles, we can have many
and the enemy script will actually cycle through every five points.
So that's really cool system.
And the other part is in the tank body, we have the tank third position.
This is very similar to the player's tank position and this will be used to synchronize the turret position
with the position where it should be on the tank.
But this is mostly useful when we will be animating the turret from the recoil animation.
Now let's continue with the systems.
And in the systems we have the following.
We have the sensor manager that handles all the tanks, sensors such as range field of view request.
We also have the tank mover which handles the movement of the tank using a specified list of 3D points.
We also have the target handler, which is basically another layer on top of the sensor manager to actually
manage the target and to check if one target is visible or not.
And we also have the cover handler, which handles the cover functionality of mostly the retreat finite
state machine, but also in the case of the defensive tank, the attack state.
And lastly, we have the final state machine states that are patrol, attack and retreat.
They both have their own unique scripts.
And we also have the state machine player which contains a unique state machine for each type of the
tank, aggressive, defensive and tactical.
Let's get into the main enemy script, which will be looking in this particular video.
And this script is big, but don't worry, most of it just initializes systems and changes color.
Let's look at how first we are greeted by a long list of export variables, and these variables actually
handle exposing these at the inspector level.
This is easier to use when iterating through various numbers or for people that don't know how to code
and are more towards game design.
These are important because you can customize all the tank instances using the same parameters.
Next, we do have some components, but in the ready function or the initialize function that is called
once the enemy gets instantiated.
We have a lot of stuff going on here.
There are a couple of things that I want to point out.
Both the enemies and the player have the metal tag type, either enemy or player.
We have some more initialization here, either down by using the dollar sign or by getting the no path.
So both of these are valid in Godot.
Here we initialize the color of the tank will go for it in a second.
And from this point forward we have a lot of systems.
So we have the final state machine, we have the tank mover, the HP system that sends our manager,
target handler and so on, so forth.
So most of these are very, very similar.
What is important, and I should mention, is that some of them do require more parameters or require
references to other systems and others require less information.
So in order to do this, I had two options.
The first one that I used initially was to have all the parameters specified in the Initialize function,
but that turned out to be not ideal because the parameters will increase or will decrease or will change
position and so on, so forth.
I found a better way to do it.
Basically the initialize of every system gets a dictionary.
We've keep our values and the key is the parameter.
While the value is the actual value of the parameter to know exactly what keys go where.
In each system I've created an enum called Params that contains what components this particular system
needs.
So for example, in the case of the sensor, we do have some variables like should use a field of view,
a should use request a reference to the parent or detection range and the tank object.
So here we have multiple things.
Either just some values or some other systems or even references to this particular script.
And of course, some are bigger, some are smaller, depending on what other systems they need to use.
Some systems such as the HP system or the target handler who have callbacks, for example, we hook
up to on damage taken and destroyed from the HP system.
Basically, these are functions that are called either when a projectile has been registered to hit
on this enemy, or even if the enemy was killed by having its HP less or equal to zero.
And there are some other callbacks that we can find here, but basically most of this is initialization
in the process function that happens every single frame.
We set our parameters for the final state machine.
And by the way, this is how we provide parameters to the final state machine.
We called set parameter and instead of having them written down, I've opted to use globals.
So Englobal's you'll find a list of all the parameters that can be used in the state machine.
This is also to avoid the mistakes of typing, of just having like a typo in nothing works anymore.
And also I have the states of a state machine go to here so that no longer need to hardcoded when we
actually want to reference a particular state.
And in this case it's the retreat and the retreat percentage is a number basically saying how much percentage
of the life should be remaining before we can actually trigger the retreat.
And I think for the aggressive UI, it's below 20%.
The start function is as important as the enemy instance first needs to get created initialized and
then to start actually executing the final state machine.
This function assures that the final state machine doesn't have is enabled parameter until everything
is ready to not create possible message.
So the state machine will actually don't do anything before this start is called because the enemy will
get instantiated at the 000 and we need to move it first to a different position.
And then from that on, start calculating what's the path to the patrol point or where the enemy is
actually in range of the specified position or not.
So this is critical to have this function.
The next two functions are about changing the color and here have the important things.
So first we create the material called highlight material and we call change material to the root node
of the tank mesh.
And this is actually a recursive function, which we'll see just in a second.
But basically what this does is goes through every element, every child of this one.
And if the child is a mesh instance, then it'll change its first material to this specified.
One, of course, after all of these meshes got the new material, then we can pick the color corresponding
to the theme.
Then we can apply that color to the highlight material.
And let's quickly check the change material.
He gets the current node and the material, and then it takes all the children.
So if you're going to the tank tank mesh, it gets the tank turret and the tank body.
Since those are not actually mesh instances but just specials, they go inside and here is that normal
mesh.
It actually will go inside of this one.
And then here is this one, which is the mesh in stores and it'll change the material for this particular
one.
So this is how this change material works.
And there is a small pack here because for this particular object, I've set up the material render
for the second position.
So it is actually a problem.
But in your use case you might just remove this and it should work just fine.
Of course, for every note we need to call back change material, but we have this particular child
node and this will actually stop executing once no child is found.
So basically, if it reaches, let's say, really deep down node like tank buddy after this was passed,
then it would get the child nodes.
This will be a list of zero elements and it will no longer call change material.
So basically this is how the change material recursive function works and it nicely changes everything.
An alternative to this would be just to change material for every single object that makes the mesh,
but that would have been a task that is actually time consuming because if the mesh changes in any way,
then we have to hardcoded every single mesh that's inside and make sure that we covered everything.
So basically this solves this problem.
The other two functions are called by the state machine player and they are the following.
An update is called at every single frame based on the state.
If it's patrol, attack or retreat, we actually call on update there.
So instead of process, which if we use process in all of these states, they will get called at the
same time.
So it would be like the tank patrols, attacks and retreats at the same time.
By using this, we actually make sure that an update gets called only when the state machine actually
plays the current state.
So this is really important.
In some cases, we don't actually run or need to run a particular state every frame to use its benefits.
We just need when on a state is entered or left and call specific initialize function or remove objects
or destroy objects if the state was left.
So on state machine enter, we have both sides of the transition.
The state that the transition is from to the state that where the transition is due and of course in
the from.
State will call only if that happens only once.
So it's used for the initializing stuff.
And on the other side we have on entry for states, for example, the farm state in the yeah, we actually
need to call it once and then change it to cooldown or reload state.
This is actually what's going to happen.
We don't need to use the update every frame.
The last parts of these scripts are actually callbacks of various systems that we used in the initialize.
So for example on damage taken is actually called by the HP system and it used to inform the target
handler system to set the target externally.
So basically if the current air instance doesn't detect the player because it's not in any sensor range,
but the player hits this target, then we don't want this to be a sitting duck and not retaliate in
any way.
So for this, we actually call on damage taken and we set up the target so it will follow the target
and seek to kill also by the HP system we have on destroyed, which needs to do a little cleanup.
We first need to clean up the patrol, which is basically the final state machine for patrolling purposes.
And this one hooks the waypoint system and we need to free that so that other tanks can be able to use
this particular waypoint system.
We also will instantiate an explosion.
This is a nice effect.
It's by the a VFX manager and we need to register the instance from the tank debug.
This is the tank debug that you can see on top left if you enable the debug mode.
Lastly, after all of this, we can safely remove the object because this object no longer has any references
to the scene on Target found is called by the target handler and this is responsible to inform the state
machine that the target was found.
So in the state machine we set this up to has target two.
True.
Alternatively, when the target is lost is also a signal received by the target handler and it will
inform the state machine that there is no longer any target or signal hit is called by the communicator
signal.
And this is basically just a small object that is instantiated by one tank that detected the player
and it's sent to a tank that hasn't detected the player yet.
So basically what this does is it receives the signal and if the target is still valid, like it's not
destroyed by other enemies, then the target handler will also acquire this target externally.
So this is used to communicate between different air systems.
If you want to know more about the communication, you should check the communication system video.
This is it for the main AI functionality.
Of course, this is the topmost script of all of this.
We have different systems that we need to go through and also the finite state machine states which
are basically finite state machines in their own particular rights.
Let me know what you think about this in the comment section down below and I'll see you in the next
one.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.