All language subtitles for 2. Implementing a FSM in Godot

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:06,780 Now that we have covered the basics of the finite state machine, let's look how one can be implemented 1 2 00:00:06,780 --> 00:00:07,960 using GDScript. 2 3 00:00:08,010 --> 00:00:11,370 There are many ways to implement the finite state machine. 3 4 00:00:11,370 --> 00:00:13,260 This is but only one of them. 4 5 00:00:13,290 --> 00:00:20,340 We will use two type of scripts the main finite state machine, which is responsible for changing states 5 6 00:00:20,340 --> 00:00:26,510 and running them, but also keeping track of the values in a small database and the others, which are 6 7 00:00:26,520 --> 00:00:28,440 the actual state implementations. 7 8 00:00:28,470 --> 00:00:34,440 Let's look first at the finite state machine. And I've already created this structure, so we will go 8 9 00:00:34,440 --> 00:00:39,050 inside the custom finite state machine and start working with it. 9 10 00:00:39,060 --> 00:00:39,870 And of course. 10 11 00:00:42,620 --> 00:00:48,530 The first thing that we need to do is create the basic structure. 11 12 00:01:00,600 --> 00:01:08,540 We will use the entry_state that can be configured in the inspector of this state machine to know exactly 12 13 00:01:08,750 --> 00:01:11,060 which state should be run first. 13 14 00:01:14,650 --> 00:01:20,500 The current_state is the variable which holds the current state that is actually running. 14 15 00:01:22,660 --> 00:01:30,760 The database keeps our values when we need to access particular information about this state machine. 15 16 00:01:31,150 --> 00:01:37,210 And we also need the state list, which is also a dictionary. In the _ready function 16 17 00:01:37,600 --> 00:01:39,980 we will need to do a couple of different things. 17 18 00:01:40,180 --> 00:01:43,510 The first: we will parse all the children. 18 19 00:01:43,510 --> 00:01:48,030 So as you can see here, we have three states and we need to get all of them. 19 20 00:01:48,040 --> 00:01:51,490 And for this we can parse all the children. 20 21 00:01:54,150 --> 00:01:54,720 And... 21 22 00:01:57,310 --> 00:02:03,400 First we will initialize the children's finite state machine with this one. 22 23 00:02:04,360 --> 00:02:10,240 And of course, we need to add the state list of the state name and the state. 23 24 00:02:10,570 --> 00:02:17,740 This will basically create the key-pair value of the state name and the state in this finite state machine. 24 25 00:02:18,190 --> 00:02:23,050 This will be useful, for example, when we are going to change state 25 26 00:02:25,550 --> 00:02:29,510 from the entry_state. Because the entry_state is a string. 26 27 00:02:30,050 --> 00:02:35,380 So it's not an actual state object, but this one is a state object. 27 28 00:02:35,390 --> 00:02:43,910 And by having this dictionary, we can actually convert string names to actual state objects. 28 29 00:02:44,390 --> 00:02:49,850 Now let's proceed and implement the changed state function because we currently don't have it. 29 30 00:02:55,270 --> 00:03:00,760 And here we need the new state, which would be the new state where we will head into. 30 31 00:03:01,780 --> 00:03:10,060 And if the current_state is not null, then that means that the current_state currently has something 31 32 00:03:10,060 --> 00:03:10,540 in there. 32 33 00:03:14,460 --> 00:03:21,590 Of course, we always need to check to see if the current state is a legit state. 33 34 00:03:21,600 --> 00:03:31,200 And for this we will use the exit_state() because we will call for every single state the enter_state(), exit_state() 34 35 00:03:31,200 --> 00:03:32,820 and update_state(). 35 36 00:03:33,120 --> 00:03:38,640 So in this case, if the current state has an exit_state() (function), then of course we will need to call this 36 37 00:03:40,150 --> 00:03:49,420 function. And be mindful that if the current state did not have this exit_state() method, then this will give 37 38 00:03:49,420 --> 00:03:50,260 an error without 38 39 00:03:50,290 --> 00:03:54,430 this if. So, it's important to put this check before. Next, 39 40 00:03:54,430 --> 00:04:02,170 we need to check if the state list actually registered a state with the name that we want to change 40 41 00:04:02,170 --> 00:04:02,470 with. 41 42 00:04:03,130 --> 00:04:05,590 So if the state list does not have. 42 43 00:04:09,900 --> 00:04:14,490 So to say, does not have, we can just negate the has(). 43 44 00:04:14,880 --> 00:04:19,470 So instead of this which will return true, if it does have the state, then it will it will make 44 45 00:04:19,470 --> 00:04:22,320 it false if it does have the state => return. 45 46 00:04:22,620 --> 00:04:29,590 This is really important because we cannot change to a state that is invalid because it doesn't exist. 46 47 00:04:29,610 --> 00:04:32,040 Now that we know for sure that the state exists. 47 48 00:04:32,250 --> 00:04:37,080 We can say current state equals state list new state. 48 49 00:04:37,710 --> 00:04:45,300 And since this is a string, it is important to make sure this check happens because otherwise this 49 50 00:04:45,300 --> 00:04:46,740 query will give an error. 50 51 00:04:47,040 --> 00:04:48,180 This is also for check. 51 52 00:04:48,180 --> 00:04:51,330 But if the current state has method. 52 53 00:04:52,830 --> 00:04:54,120 enter_state() 53 54 00:04:54,510 --> 00:04:56,490 Then, of course, we need to call it. 54 55 00:04:59,760 --> 00:05:05,190 The enter_state() and exit_state() are always called when a state gets changed. 55 56 00:05:05,220 --> 00:05:09,720 This is important for one-time functions that need to run in that particular state. 56 57 00:05:09,780 --> 00:05:12,120 Now let's move on with the process. 57 58 00:05:12,900 --> 00:05:18,450 So in the _process() part, what we need to do is we need to check if there is a current state. 58 59 00:05:19,020 --> 00:05:20,070 And if it's not. 59 60 00:05:21,240 --> 00:05:25,290 We will call return because we don't want to process this any longer. 60 61 00:05:25,590 --> 00:05:31,920 Of course, what we could have done instead would have been if the current state is not null and then 61 62 00:05:31,920 --> 00:05:33,090 write our code here. 62 63 00:05:33,120 --> 00:05:40,590 But the problem by doing this is that we will have more indentation as we go with this kind of structure. 63 64 00:05:40,620 --> 00:05:47,160 So instead what we do is just check if it's null and then return to keep the indentation level. 64 65 00:05:47,400 --> 00:05:54,120 So to keep this indentation as close to the left as possible. This will create a nice code structure 65 66 00:05:54,210 --> 00:05:54,990 in the long run. 66 67 00:05:55,080 --> 00:06:00,900 And here, of course, we will call current_state because we know it exists and if it has the method. 67 68 00:06:04,200 --> 00:06:04,650 process() 68 69 00:06:04,890 --> 00:06:06,660 And be mindful here 69 70 00:06:06,870 --> 00:06:11,850 this process is a little different from this one because this gets automatically called by Godot, 70 71 00:06:11,850 --> 00:06:18,540 and we need a custom one because we would need to call it here and we need to make sure that it only 71 72 00:06:18,540 --> 00:06:19,370 gets called here. 72 73 00:06:19,380 --> 00:06:24,270 So I'm just copy-pasting this because it's much easier. And I'm going to put in the delta. 73 74 00:06:24,360 --> 00:06:28,380 Of course, I'll do exactly the same for the _physics_process(). 74 75 00:06:49,690 --> 00:06:53,020 It's important to copy paste this to make sure that there's no error. 75 76 00:06:54,700 --> 00:06:56,860 Why is it important to have _process() and _physics_process() 76 77 00:06:56,860 --> 00:07:00,150 because some functions only work in _physics_process(). 77 78 00:07:00,160 --> 00:07:04,270 So it's important to have both of these supported in our state machine. 78 79 00:07:04,330 --> 00:07:06,500 Of course, we already have the change_state(). 79 80 00:07:06,520 --> 00:07:16,270 What we need to do here is create two more options, and that is set_value(), which is a setter for 80 81 00:07:16,270 --> 00:07:18,190 the key-pair database we have. 81 82 00:07:18,190 --> 00:07:23,380 So value name and value. And "db" 82 83 00:07:23,380 --> 00:07:31,300 the database dictionary that we created, the value name will be equal value and next one will have 83 84 00:07:32,680 --> 00:07:38,500 get_value() which can just get the value name. 84 85 00:07:39,160 --> 00:07:46,780 And here we can say if the database has(value_name) first because we cannot query something that doesn't 85 86 00:07:46,780 --> 00:07:50,830 exist, then it will return to the database value name. 86 87 00:07:52,190 --> 00:08:00,290 This is important because our state machine will need to communicate with different states to know what 87 88 00:08:00,290 --> 00:08:02,180 is the current state of the whole system. 88 89 00:08:02,420 --> 00:08:04,280 For example, is the player retreating? 89 90 00:08:04,280 --> 00:08:07,180 Is the player attacking so and so forth. 90 91 00:08:07,190 --> 00:08:11,540 So we need to have a synchronized database for all of these states. 91 92 00:08:11,720 --> 00:08:14,960 Now let's move to a particular node implementation. 92 93 00:08:14,960 --> 00:08:18,260 And for this I will target the idle state. 93 94 00:08:26,780 --> 00:08:32,300 So first we would need to have a reference to the custom state machine that we just implemented. 94 95 00:08:32,810 --> 00:08:34,790 And now we need to make sure we have: 95 96 00:08:36,420 --> 00:08:37,170 enter_state() 96 97 00:08:43,810 --> 00:08:50,150 And as you remember, the enter_state() is called when a state gets changed. 97 98 00:08:50,170 --> 00:08:55,150 So this will be called when the idle state is changed. 98 99 00:08:55,780 --> 00:08:58,840 Now, we also need the exit_state(). 99 100 00:09:00,210 --> 00:09:06,150 Make sure that the names are exactly the ones used in the custom finite state machine. 100 101 00:09:06,150 --> 00:09:07,290 Otherwise it won't work. 101 102 00:09:12,420 --> 00:09:18,900 And here the process() is not with underscore, because this will be automatically called every single frame 102 103 00:09:19,140 --> 00:09:19,830 from Godot. 103 104 00:09:19,860 --> 00:09:25,680 And it's important because you have if you have multiple states, we don't want them to run without 104 105 00:09:25,680 --> 00:09:32,260 any control, but instead being able to control them through this process. 105 106 00:09:32,280 --> 00:09:36,690 So in order to make this happen, we need to make sure that this not with underscore. This is basically 106 107 00:09:36,690 --> 00:09:38,130 you can call it whatever you like. 107 108 00:09:38,130 --> 00:09:40,950 But I just called the process. Delta. 108 109 00:09:45,700 --> 00:09:46,480 And here. 109 110 00:09:47,780 --> 00:09:54,170 Before we actually do any process from the state, we need to check the conditions. 110 111 00:09:54,710 --> 00:10:03,890 And the conditions are really important because they will tell us if we need to go from this state to 111 112 00:10:04,220 --> 00:10:08,570 another one based on some values that are stored in the database. 112 113 00:10:09,320 --> 00:10:14,900 We will create these and the other states in the mini example for the finite state machine. 113 114 00:10:15,020 --> 00:10:16,610 Let's find out how to make them. 12043

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