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
0 Welcome to the communicator system. 1
This system is responsible for propagating knowledge from one AI agent to another. 2
In this particular case, if one tank acquires the target, it will then try to inform others about 3
it. 4
Let's find out how this all works. 5
The communicator is made out of two parts. 6
One of them is the main system that is attached to all AI agents. 7
You can find this system on every AI instance, child to the main kinematic body because it uses the collision. 8
The other is the signal, which is similar to a projectile, but it travels directly to another instance 9
and when it arrives, it's meant to inform that AI instance that it has a new target. 10
Let's start with the main communicator component. 11
Here we can find the following parts. 12
First, you have the area collision, which will keep track of all other AI agents that are in the vicinity 13
of this one. 14
To not be able to communicate faraway distances. 15
Of course you can change this by changing the collision sphere shape to different sizes. 16
So this particular instance would communicate farther away or on shorter ranges. 17
The other two parts are two timers: the ClearSignalListTimer and the CommunicateTimer. 18
The communicate timer is actually triggered so that the communication doesn't happen all the time, 19
but with 2 seconds delay in between them. 20
And of course we don't want to send to the same tank the signal twice. 21
So we keep track of the signal list and at some point we clear it up because the tank that received a signal 22
from us might have lost the target and is good to be able to communicate with it again, but at some 23
point later in time. 24
Now let's look at the communicator script and see how this works. 25
First, I want to highlight the following variables. 26
The signal prefab, which is actually you can see here, it's the signal that we use as the projectile. 27
This will get instantiated when we need to communicate between different AI instances. 28
We also have the maximum communication number. 29
Basically, once we send the signal out to three different other AI instances, we stop this communicator 30
from working. 31
This is do not overpower the system and let the whole map come after us. 32
Next, we have the nearby list, which will be updated by the area collision on_body_entered and 33
on_body_left. 34
This will get updated with more or less AIs that are in our nearby field. 35
The signaled_list is a list of tanks that already have received communication from this one. 36
We do not want to send the same thing twice. 37
The current_communication is actually a counter that keeps track of how many AI agents have we signaled to, 38
and this will be used to compare to the maximum communication to stop once we reach the limit. 39
And of course you can change this to communicate to more or less AIs depending of your balancing 40
of the game. 41
In the initialize function we get the tank object that is the parent of this and we also will need the 42
target handler. In the restart, 43
we reset basically the communication so that we can communicate to three AIs in this case. And also 44
we clear the signaled_list so that we can communicate with the same three AIs that we want. 45
The main functionality is the throw_signal, but before 46
we go into this 47
I want to quickly point out how the nearby list gets updated. 48
We have the area collision and in the node here we have body_entered and body_exited. 49
Here these two are actually signals that are hooked up with these two functions. 50
And here we get the type of the body that has entered or left and if it's enemy and it's not in the 51
nearby list already, and of course it's not the same one. 52
We want to prevent collision to itself because we don't want this tank to issue communications to itself. 53
Then we append it to the nearby list. 54
Alternatively, if this tank exited, then we actually remove it from the nearby list. 55
Basically, this is how we get a nearby list 56
working every frame. throw_signal() is not actually called by any other script, but by using this timer, 57
which as I mentioned, is in the on_communicate_timer. 58
This is also a signal that's hooked up through the Godot system. 59
Once this reaches zero, first we need to make sure that we still have a valid target for this particular 60
tank. 61
So in this case, if the target exists and is the instance valid, and then if we have reached the maximum 62
communication number, we need to stop the communicate timer and of course return and otherwise we haven't 63
reached it yet and we can actually throw a new signal. 64
Now let's look at the throw_signal functionality. And here we need to do the following: 65
First, we need to check if the nearby list has some tanks around. 66
If we don't have anyone around, then we cannot communicate with someone. 67
We return. 68
Basically, this just stops the execution of this function here. 69
Then we have the other enemy which we will get from the nearby list, and this is actually generated through 70
a random number. 71
So we get the random index number. 72
We also need to check if the other enemy still exists and the instance is still valid, and then if 73
the other enemy doesn't have already the same target. 74
Because if it does have the target. 75
Then sending a signal to it would be useless. 76
We don't want to have the same enemy signaled twice, so we check it in the signaled_list. 77
But if the selected enemy passes all of these checks, then this means we can properly issue a new signal. 78
We increase the current communication number. 79
We append this other enemy to the signaled_list. 80
Lastly, we create a new signal, and the first two steps are, of course, instantiate the signal and 81
add it to the root scene node and then set up the position as well as the rotation of the signal. 82
And lastly, trigger the start functionality which will receive the other enemy and what target the 83
other enemy should receive. 84
The last callback that we need to mention here is on_clear_signal_timeout 85
. 86
This just clears the signaled_list to be able to inform the enemies that already have been informed by 87
this particular one. 88
The other part of the communicator is the actual signal and we can check its code right now. 89
And basically here it looks very, very similar to a projectile. 90
Besides the start which actually receives the other enemy and the target we actually wait for is 91
enabled because we don't want to start moving this while it's not at the correct position. 92
We create the direction vector and then we normalize it and we move this particular object towards the 93
position using the speed and delta. 94
The other part of this is actually calculating the distance between this current signal and the enemy. 95
And if it's below one, it means that it has reached the intended target, and if it has the function 96
on signal hit, then it will call it. 97
If it's not, then might be a mistake or might have hit something else. 98
But this should not be the case. 99
And then the signal will actually be removed. 100
This happens with this function. 101
There is also one particular case that the signal might handle. 102
So if we send the signal to a particular enemy and that enemy gets destroyed before the signal reaches 103
it. 104
In this case, this won't work anymore. 105
So we need to have also a lifespan that actually is 5 seconds and it will automatically start. 106
So if the signal either reaches the enemy or has elapsed 5 seconds after each instantiation, then it 107
will get destroyed. And for the signal hit on the enemy. 108
If we go back to the enemy script, then this is the function we are looking at. 109
This was also discussed in the main enemy video, but quickly, just a refresh. 110
It gets to the target and if the target is still valid, then it will set the target externally to the 111
target handler. 112
So this new enemy will get informed about this target via the signal. 113
This is it for the communicator. 114
I hope you liked it. 115
And leave a comment here and tell me. 116
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.