It's been 30 years and I finally understand. Thank you!
@kostanislaw11 ай бұрын
Лучший урок по стейтам, что я видел. Не только дал удобную ФСМ, но ещё и очень просто объяснил как всё это работает и зачем нужна каждая строчка. Блин, если бы все на ютубе объясняли как ты - я бы уже закончил свою игру. Спасибо!
@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 Жыл бұрын
Thank you, means a lot coming from a fellow dev!
@kloa421911 ай бұрын
I'm nearly done with porting this to Godot 3, thank you for explaining it clearly.
@kloa421911 ай бұрын
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)
@kloa421911 ай бұрын
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
@kloa421911 ай бұрын
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 Жыл бұрын
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
@athosdev41812 ай бұрын
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 Жыл бұрын
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 Жыл бұрын
Thank you for the kind words. More videos are coming!
@fuzzy-025 ай бұрын
That punch animation was personal
@curtiss578110 ай бұрын
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.
@Rawbherb3 ай бұрын
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!
@ForlornU3 ай бұрын
Hey as long as it works that's what matters!
@offlinemoe6 ай бұрын
Just found your channel and I fell in love with it
@hensola7 ай бұрын
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.
@Altaryum7 ай бұрын
Thanks for this very comprehensive tutorial about FSM. 🤗
@PaintedCz Жыл бұрын
This is fantastic! Thank you so much!
@Lily-kv3rb7 ай бұрын
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?
@cheesymcnuggets11 ай бұрын
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...
@kloa421911 ай бұрын
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.
@ForlornU10 ай бұрын
"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Ай бұрын
Good you fucking explained what inherited means and how to do it, im sooo fucking glad
@ykyjohn8 ай бұрын
Where/When the state_transition is emitted?
@PaperMouseGames11 ай бұрын
Fantastic video! Very high quality and helpful, thank you!
@panwladca88007 ай бұрын
Thank you for your hard work 😊
@fuzzy-025 ай бұрын
Any tips on how to combine this with composition (stuff like making components and composing entities from them, like VelocityComponent, HealthComponent, WanderAroundComponent, etc)
@vladyerus11 ай бұрын
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 .
@ForlornU11 ай бұрын
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-q1o3 ай бұрын
which code is connected to which?
@fuzzy-025 ай бұрын
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
@kloa421911 ай бұрын
How did you animate your video btw?
@ForlornU10 ай бұрын
I use Davinci resolve for editing, the coding animations are done in good 'ol powerpoint!
@cioelle5 ай бұрын
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
@ForlornU5 ай бұрын
Noted, sorry I didn't explain that more clearly! Glad it was still helpful :)
@boxboy9000-f7r5 ай бұрын
it keeps saying could not find type state in the current scope!
@1tsKayne9 ай бұрын
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-q1o3 ай бұрын
so i am using godot 4.2 can it work platformer
@ForlornU3 ай бұрын
Grab the 1.4 release for Godot 4.2. Yes you can make it into a platformer, just add gravity basically :)
@SiddhantaGhosh-q1o3 ай бұрын
when i downlorded it i shows godot 4.3
@ForlornU3 ай бұрын
This is 4.2 Compatible, but I would also suggest just upgrading :) : github.com/ForlornU/TopdownStarter/tree/1.4
@DariusK-f5e3 ай бұрын
:( State_Machine.gd:16 - Parse Error: Cannot call non-static function "Enter()" on the class "State" directly. Make an instance instead.
@ForlornU3 ай бұрын
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?
@pand2aren3 ай бұрын
@@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 Жыл бұрын
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.
@kloa421911 ай бұрын
You can do it with enums in Godot. It just feels messy in comparison to the node method
@Konslufius5 ай бұрын
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)
@truenincillo80511 ай бұрын
Tutorial swim in 2d platform game godot 4 please😣
@HurricaneSA11 ай бұрын
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.
@ForlornU10 ай бұрын
Indeed it was getting out of hand, resolved in latest version!
@MTweedC48 ай бұрын
😂 good sport
@user-db2uj9vc7sАй бұрын
An standard naming convention is very good for team work, but for a solo small project it really is not that deep
@GenericInternetter11 ай бұрын
"press enter to leave" huh?
@ForlornU11 ай бұрын
That does sound strange when you point it out 😅
@PocketDeerBoy7 ай бұрын
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
@theseangle6 ай бұрын
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]`
@mrserlysir23 күн бұрын
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
@bernardbrookshire71716 ай бұрын
not helping
@bsdrago11 ай бұрын
what about unity? =)
@templeoftaste3206 ай бұрын
Useless, you left out the most important part about how to actually trigger a state transition from the idle state class