Finite State Machines in Godot | Godot Starter Kit FSM

  Рет қаралды 38,891

ForlornU

ForlornU

Күн бұрын

Пікірлер: 64
@anthonygill718
@anthonygill718 5 күн бұрын
It's been 30 years and I finally understand. Thank you!
@kostanislaw
@kostanislaw 11 ай бұрын
Лучший урок по стейтам, что я видел. Не только дал удобную ФСМ, но ещё и очень просто объяснил как всё это работает и зачем нужна каждая строчка. Блин, если бы все на ютубе объясняли как ты - я бы уже закончил свою игру. Спасибо!
@philldev
@philldev Жыл бұрын
This is a very useful video for all beginners, not just godot users! It explains exactly what a FSM is and how it should work, not to mention it is well edited and easy to understand. Good job, keep up the good work :)
@ForlornU
@ForlornU Жыл бұрын
Thank you, means a lot coming from a fellow dev!
@kloa4219
@kloa4219 11 ай бұрын
I'm nearly done with porting this to Godot 3, thank you for explaining it clearly.
@kloa4219
@kloa4219 11 ай бұрын
Finite State Machine extends Node class_name FiniteStateMachine var states : Dictionary = {} export var initial_state = NodePath() onready var initstate:State = get_node(initial_state) var current_state:State var change_state:State func _ready(): for child in self.get_children(): if child is State: states[child.name.to_lower()] = child child.connect("state_transition", self,"change_state") if initial_state: initstate.Enter() current_state = initstate func change_state(source_state:State, new_state_name:String): #redundancy checks if source_state != current_state: print("Invalid change_state trying from: " + source_state.name + "but current in: " + current_state.name) return var new_state = states.get(new_state_name.to_lower()) if !new_state: print("New state is empty") return #only relevant lines if current_state: current_state.Exit() new_state.Enter() current_state =new_state func force_change_state(new_state:State): var newState = states.get(new_state.name.to_lower()) if !newState: print(str(new_state) + " does not exist in the dictionary of states") return if current_state ==newState: print("State is same, aborting") return if current_state: current_state.call("Exit") current_state=newState newState.Enter() func _process(delta): if current_state: current_state.Update(delta) func _physics_process(delta): if current_state: current_state.Update(delta)
@kloa4219
@kloa4219 11 ай бұрын
Player_Idle State extends State class_name Player_Idle export var sprite = NodePath() onready var _sprite :AnimatedSprite = get_node(sprite) #gets FSM node onready var fsm = get_parent() #onready var fsm = $".." onready var moving = $"../Moving" func Enter(): #_sprite.play("Idle") pass func Exit(): pass func Update(_delta:float): if (Input.get_vector("move_left","move_right","move_forward","move_backward")): print("moving") #Transition to move state fsm.change_state(self, "Moving") pass if (Input.is_action_just_pressed("attack")): #transition to attack state pass pass
@kloa4219
@kloa4219 11 ай бұрын
extends Node class_name State signal state_transition func Enter(): pass func Exit(): pass func Update(_delta:float): pass func Physics_Update(_delta:float): pass
@locke_d
@locke_d Жыл бұрын
tysm for this tutorial, ngl the code here is like identical to a tutorial about the same subject from Bitlytic (not sure if that's intentional or a happy accident) but like, you actually explain it in a thorough and easy to understand way? Bitlytic skims over so much important info for beginners but you hit the nail right on the head with the explanations, super comprehensive and easy to follow, tysm again king ily
@athosdev4181
@athosdev4181 2 ай бұрын
they're implementing the same thing, its all finite state machine in its core, so the logic will look really similar if not the same.
@armored_gore
@armored_gore Жыл бұрын
You are a godsend! Explanations were short concise and easily understandable. Thank you from the bottom of my heart! I can't wait for more!
@ForlornU
@ForlornU Жыл бұрын
Thank you for the kind words. More videos are coming!
@fuzzy-02
@fuzzy-02 5 ай бұрын
That punch animation was personal
@curtiss5781
@curtiss5781 10 ай бұрын
I had a project where I tried a sort of state machine but used timed animations that would trigger follow up states. I ran into issues when trying to do a forced state while animations were still running. Im pretty sure a more defined approach like what you have here would have sorted out my issues, being able to end animation delegates in the current state Exit method before killing the object. Cool explanation, thanks.
@Rawbherb
@Rawbherb 3 ай бұрын
This looks like a very organized way to do it. I just throw all of the states in a switch function in my player’s script, and each state gets its own function, and then each state’s function has logic for the other states it can switch to… I like this idea though!
@ForlornU
@ForlornU 3 ай бұрын
Hey as long as it works that's what matters!
@offlinemoe
@offlinemoe 6 ай бұрын
Just found your channel and I fell in love with it
@hensola
@hensola 7 ай бұрын
Lovely intro on how FSM work, as well as separating them all out to a manager function. I believe this is how Godot is meant to be programmed.
@Altaryum
@Altaryum 7 ай бұрын
Thanks for this very comprehensive tutorial about FSM. 🤗
@PaintedCz
@PaintedCz Жыл бұрын
This is fantastic! Thank you so much!
@Lily-kv3rb
@Lily-kv3rb 7 ай бұрын
I've been watching through a couple of different videos after finishing my player movement system in my first game and decided to switch it over to a state machine, since I plan on adding even more movement mechanics later on and I want to make it easier on myself. This is the first video I've found that explains things in such detail, so thank you! However, in every video I've watched and tried to follow along, I keep getting stuck on specific tidbits that I can't seem to find an answer to either in the video, or on specific searches on Reddit/Google/Etc. Where would be the best resource for figuring out solutions to problems like "In my Finite State Machine script, there are 'Could not parse global class "State" from "res"//Scripts/PlayerState.gd" over every mention of the variable 'initial_state'. How do I fix this?". I want to find a community or resource where I can easily look up these errors and find out why its not working. And if the reason I can't figure this out is due to a lack of very basic knowledge of GDScript, where should I start learning that basic knowledge?
@cheesymcnuggets
@cheesymcnuggets 11 ай бұрын
I don't think I actually need a state machine but i want to learn them, this is like the third video I've watched on them and they haven't become any less intimidating. Question about your force state function, how exactly can it break your game? Aren't exit functions meant to prevent the state machine from breaking or have I misunderstood their purpose? Oh wait the problem is with decentralised state machines, right? Since each state is only accounting for it's own transitions and trying to transition to something it doesn't know how to could break things? I don't know...
@kloa4219
@kloa4219 11 ай бұрын
Think of state machines as applying a script to each game mechanic. It isn't important for small projects but it makes doing big projects like RPGs or fighting games easier.
@ForlornU
@ForlornU 10 ай бұрын
"Break your game" was me being a bit dramatic. Creating a system of transitions only to then override them with force can lead to unexpected behaviour I guess. I don't want to make a tutorial where I use a 'force-change' function to ignore what I am trying to teach in the video
@jacknight3690
@jacknight3690 Ай бұрын
Good you fucking explained what inherited means and how to do it, im sooo fucking glad
@ykyjohn
@ykyjohn 8 ай бұрын
Where/When the state_transition is emitted?
@PaperMouseGames
@PaperMouseGames 11 ай бұрын
Fantastic video! Very high quality and helpful, thank you!
@panwladca8800
@panwladca8800 7 ай бұрын
Thank you for your hard work 😊
@fuzzy-02
@fuzzy-02 5 ай бұрын
Any tips on how to combine this with composition (stuff like making components and composing entities from them, like VelocityComponent, HealthComponent, WanderAroundComponent, etc)
@vladyerus
@vladyerus 11 ай бұрын
This video helped me more than most to figure out state machines. thank you. Do you know if this code allows for switching scenes? For example i have a state called Driving (my character goes invisible, stops processing, etc) and i take control of another characterbody2d which has its own set of states .
@ForlornU
@ForlornU 11 ай бұрын
Absolutely. An interaction script activates the vehicle and tells the fsm to transition to driving state which 'deactivates' the player. A player state should not be responsible for anything outsider the player i think 👍
@SiddhantaGhosh-q1o
@SiddhantaGhosh-q1o 3 ай бұрын
which code is connected to which?
@fuzzy-02
@fuzzy-02 5 ай бұрын
Is this the same as Finite State Automata? Where you have a Deterministic Finite Automaton, DFA, a Non Deterministic one, NFA, an Epsion Non Deterministic one, e-NFA, and you work on reducing whatever automata you have into a minimal deterministic one? I took this as part of an introductory course to compilers and it seems awfully similar
@kloa4219
@kloa4219 11 ай бұрын
How did you animate your video btw?
@ForlornU
@ForlornU 10 ай бұрын
I use Davinci resolve for editing, the coding animations are done in good 'ol powerpoint!
@cioelle
@cioelle 5 ай бұрын
amazing video, but i feel it's definitely important to show and explain how to use state_transition and explain what it does, and how it connects the scripts. great otherwise though, i needed someone to explain FSM to me like i'm 5 lmao
@ForlornU
@ForlornU 5 ай бұрын
Noted, sorry I didn't explain that more clearly! Glad it was still helpful :)
@boxboy9000-f7r
@boxboy9000-f7r 5 ай бұрын
it keeps saying could not find type state in the current scope!
@1tsKayne
@1tsKayne 9 ай бұрын
i dont know how i should transition the state for my enemy. so it detects when the player entered his territory and then it should switch to chase state. What do I have to put in there? # In the Idle State: func _on_view_area_body_entered(body): if body.is_in_group("Player"): FiniteStateMachine.change_state(State, "BaseNPCChaseState") doesnt work
@SiddhantaGhosh-q1o
@SiddhantaGhosh-q1o 3 ай бұрын
so i am using godot 4.2 can it work platformer
@ForlornU
@ForlornU 3 ай бұрын
Grab the 1.4 release for Godot 4.2. Yes you can make it into a platformer, just add gravity basically :)
@SiddhantaGhosh-q1o
@SiddhantaGhosh-q1o 3 ай бұрын
when i downlorded it i shows godot 4.3
@ForlornU
@ForlornU 3 ай бұрын
This is 4.2 Compatible, but I would also suggest just upgrading :) : github.com/ForlornU/TopdownStarter/tree/1.4
@DariusK-f5e
@DariusK-f5e 3 ай бұрын
:( State_Machine.gd:16 - Parse Error: Cannot call non-static function "Enter()" on the class "State" directly. Make an instance instead.
@ForlornU
@ForlornU 3 ай бұрын
It's telling you to call the 'Enter()' function on one of the states, not the 'State' superclass itself. Are you trying to make new states?
@pand2aren
@pand2aren 3 ай бұрын
@@ForlornU sorry for lack of context in my comment, it throws me error in 2:58 part in statemachine main script in func _ready > initial.state.Enter() i guess i missed something.
@markaven5249
@markaven5249 Жыл бұрын
I don't know why but state machines seem so much more difficult and less straightforward than in C, C++, or C#. It must be the whole dynamic programming thing. In C like languages, I'd just create a state and subState enum, subState would have Init, Run, End and state would have animation names, then just create one long script for everything. Signals are just Events and Callbacks but they call them signals. I guess these days this isn't a modern style of programming, but I'd have as few scripts as possible as well.
@kloa4219
@kloa4219 11 ай бұрын
You can do it with enums in Godot. It just feels messy in comparison to the node method
@Konslufius
@Konslufius 5 ай бұрын
I'm sry I understand how a statemachine works in theory, but I can not make sense of this line: child.state_transition.connect(change_state)
@truenincillo805
@truenincillo805 11 ай бұрын
Tutorial swim in 2d platform game godot 4 please😣
@HurricaneSA
@HurricaneSA 11 ай бұрын
Please for the love of my sanity can you choose a notation and stick with it? Changing between snake and camel notation randomly is making my brain hurt.
@ForlornU
@ForlornU 10 ай бұрын
Indeed it was getting out of hand, resolved in latest version!
@MTweedC4
@MTweedC4 8 ай бұрын
😂 good sport
@user-db2uj9vc7s
@user-db2uj9vc7s Ай бұрын
An standard naming convention is very good for team work, but for a solo small project it really is not that deep
@GenericInternetter
@GenericInternetter 11 ай бұрын
"press enter to leave" huh?
@ForlornU
@ForlornU 11 ай бұрын
That does sound strange when you point it out 😅
@PocketDeerBoy
@PocketDeerBoy 7 ай бұрын
I feel like you sort of skipped over the part where you explain how states communicate with each other? I looked through the github to try to understand the code better and there's this line from the Idle state: state_transition.emit(self, "Moving") that was never explained. I'm sorry, I'm very new to coding and I wanted to figure out state machines, but I'm not sure how this piece of code works and how it's picked up by other codes. My guy is still not walking
@theseangle
@theseangle 6 ай бұрын
state_transition is the signal that is defined in the IdleState's script. This line emits the signal of a transition from IdleState to MovingState to the state machine class. The state machine has `current_state.state_transition.connect(handle_transition)`. It makes the FSM subscribe to the transition event that is emitted from the current state. On that event, it calls the `handle_transition` function which is defined in the FSM. It has two arguments: previous_state and new_state. Both of them correspond to the two arguments `self` and `Moving` respectively from the IdleState's script. "Moving" is the name of the MovingState node, which plays as the accessor for the MovingState. It's used in the `handle_transition` function to get the state node by the string, like `current_state = get_children()[new_state]`
@mrserlysir
@mrserlysir 23 күн бұрын
why show a unity state machine while doing a godot tutorial? Well, I guess this could have been before godot released the new Animation Tree Node
@bernardbrookshire7171
@bernardbrookshire7171 6 ай бұрын
not helping
@bsdrago
@bsdrago 11 ай бұрын
what about unity? =)
@templeoftaste320
@templeoftaste320 6 ай бұрын
Useless, you left out the most important part about how to actually trigger a state transition from the idle state class
Starter state machines in Godot 4
10:58
The Shaggy Dev
Рет қаралды 71 М.
Godot Scripts I add to Every Game
12:34
Aarimous
Рет қаралды 56 М.
It works #beatbox #tiktok
00:34
BeatboxJCOP
Рет қаралды 41 МЛН
Can I Learn Raylib In Just 48 Hours?
1:29:46
ForlornU
Рет қаралды 943
How to use Classes in Godot! - Intermediate Tutorial
8:46
How Do Game Devs NOT Overscope??
9:04
Green Light Dev
Рет қаралды 10 М.
Creating SMART enemies from scratch! | Devlog
5:40
Challacade
Рет қаралды 373 М.
Code Class - Build your own State Machines!
36:42
AdamCYounis
Рет қаралды 58 М.
Finite State Machines - Godot 4 Tutorial (Intermediate)
35:51
Heartbeast
Рет қаралды 73 М.
Everything You Need To Start Making Games (As A Beginner)
16:11
Juniper Dev
Рет қаралды 108 М.
Godot 4 Precision Platformer - state machine and movement
1:45:14
PracticalNPC
Рет қаралды 20 М.