This is getting to be so much fun! Hope it's helpful for you guys 🔥 GET THE SOURCE FILES ►► www.patreon.com/StayAtHomeDev_ 👉🏼 FREE BASIC FPS SETUP SOURCE FILES ►► github.com/StayAtHomeDev-Git/FPS-Godot-Basic-Setup
I found a much better way to check if the player is moving get_real_velocity().length() This gets the actual velocity, not intended velocity. This works better because sometimes you want to move but you cant, like you're up against a wall or something
I just want to say to anyone that isn't sure if they want to implement this. Do it. If you're worried about time, It won't add almost any time to implement it if you do it early. It might take a bit if your code is getting confusing, but it will take you mush less time now than later when it's worse. And if you're wondering if it's really worth it, it is. It's much easier to implement new things and everything is much more organized. And if something breaks, it won't break everything else.
I was following your tutorial series up until the last video and decided a state machine was a great idea, so I implemented that last weekend :D Awesome to see your take on it and great tutorials so far!
Another way to pass the player reference programmatically is to get a single reference for it in the state machine then pass it down as a property to each state when iterating through children. Nice tutorial!
Just finished implementing a State Machine that works differently. States are children of the State Machine, then Actions and Transitions are children of States and Decision is child of Transitions. This way can split into reusable Actions and Decisions. And also swap StateMachines realtime for different phases
@@iglobrothers645 Instead of having all the code of actions and transitions inside one state script, I split into State, Actions, Transitions and Decisions. State and Transition scripts never change, just drop them to the nodes and set the True and False states for the Transitions. Each transition should have only one decision which will return True or False. Each state can have any number of Actions, which I like to make as simple as possible for reusability.
at the end my debug panel isnt updating my state, it's stuck on Idle but im not sure if my debug panel is the issue or if its my statemachine, how can i fix that?
@@tenofhearts99 I think the spazzing part, is the order of debug panel, since the video put 1, it causes spazzing you mention, I put it on 5, it's much better
Man these videos are the best I've ever seen for Godot 4! When I updated from 3.5 to 4 I couldn't figure out anything but these videos helped so much! Hahah also I was just wondering why I was getting the red overlay and figured out it was because I didn't save the state script! I was trying to fix it for like 15 minutes.😂👍
Question: I am getting the "Invalid call. Nonexistent function 'enter' in base 'Nil'." error whenever I try to run the scene. My working theory is that CURRENT_STATE is not set to anything by default, yet the same code seems to work in the video? Please advise.
Answer: I forgot to set "Current State" In the inspector to be set to idle by default. Never used that feature before this series so no wonder I didn't know what was wrong :P
Hi I know this video is not very recent, but could using a singleton for player variables affect other player character variables when using it for a multiplayer game?
Did you figure it out? At the top of your state script you should have this: class_name State extends Node after the first save with those two lines, the class called Stae should be accessible from every script.
Can you please help with the errors? The parameter "delta" is never used in the function "physics_update()". If this is intended, prefix it with an underscore: "_delta". UNUSED_PARAMETER state.gd:16
Anybody else having issues with class_name? In the "Attach Node Script" screen I don't see an option for class name. I put class_name in my script but when I inherit from state .gd it does not create the new class automatically. Do I have to enable class names in my project settings or something?
What I don't really get is why you use the Walking state script o check if you're supposed to go to Idle manually, and also from Idle to Walking. Why not check for movement in Walking and for standing still in Idle? Wouldn't that be why we did this in the first place?
The IdleState already knows that the player is standing still. The point of the update function in the State class scripts is to check for an exit condition from the current state. This way when you want to do something while in that state, you don't need to check in the conditions of the state are met since it's already assumed that the conditions to be in that state have already been met.
@@the-birbo After thinking about this for a few days and following the tutorial further I get why this works, but I also think there's ways that work better with how I think myself. thanks for your reply!
How make state for differents characters like team fortress 2 or overwatch and is it possible to not work on animation with state or it's already the case with the mesh and collision shape or it's not and 1 model with skeleton3D is needed
hey, great tutorials. They help a ton. One question, my state isn't changing when i move. I think my _update function isn't triggering in my states. Any ideas on how to fix it? edit: make sure you have an underscore before all calls on exit(), enter(), and update(), otherwise it calls the wrong function
I am currently experiencing my state machine not transitioning states whenever I move, my script and current project settings match this one. I hope somebody has a solution, or an explanation.
My state is not updating in the debug panel. I'm getting a bunch of error stating that delta is never used on the State.gd functions mostly and that "State does not exist" push warning so it looks like whatever state I'm trying to update to doesn't exist?
I was having the same problem with the in-game debug panel, so I put print(current_state.name) in the on_child_transition() function and it showed in the Godot output panel at the bottom that the state is updating properly, so it had to be a problem with the add_property() function in the debug script. Turns out I was missing the end of the function, so everything was just being added and not updated if it already exists. This is the bit I was missing after the "if !target:" chunk in the add_property() function elif visible: target.text = title + ": " + str(value) property_container.move_child(target, order)
If anyone gets the issue where it won't let you set anything to the default state in the inspector like I did. Restart Godot it was apparently just being buggy.
On the debug info, the state keep staying as idle if I move it. When I check the debugger, I got the warning about "State machine contains incompatible child node". I'm pretty sure I've followed the instructions, and the same people that got the problem here either got unknowingly fixed or still haven't receive any answer.
I'm receiving an "invalid Call. Nonexistent function 'connection' in base 'signal' error. It looks like something is wrong with my child.transition.connection(on_child_transition) line in the State_Machine script. Anyone experience this issue and have a solution or an idea where I went wrong? I've gone back through the video twice now and my scripts appear to match up with the tutorial
I'm sure you already figured it out, but in case someone else has that problem, make sure your IdlePlayerState and WalkingPlayerState scripts have "extends State" in them, then go to to your State script and make sure you spelled this signal correctly, then go to the line where you connect the state to the transition signal and make sure everything is spelled correctly. If this doesn't solve the issue, try saving and reloading the project.
Getting errors complaining about "delta" in the "_process(delta):" Reticle, in "physics_update(delta: float) -> void:" in state.gd, in " func update(delta):" in IdlePlayerState, and in func update(delta):" in WalkingPlayerState. why did this get triggered from the global?
@@patrikgranstrom7683 same, get these: W 0:00:00:0885 The parameter "delta" is never used in the function "_process()". If this is intended, prefix it with an underscore: "_delta". UNUSED_PARAMETER Reticle.gd:17 W 0:00:00:0893 The parameter "delta" is never used in the function "physics_update()". If this is intended, prefix it with an underscore: "_delta". UNUSED_PARAMETER state.gd:13 W 0:00:00:0895 The parameter "delta" is never used in the function "update()". If this is intended, prefix it with an underscore: "_delta". UNUSED_PARAMETER IdlePlayerState.gd:4 W 0:00:00:0897 The parameter "delta" is never used in the function "update()". If this is intended, prefix it with an underscore: "_delta". UNUSED_PARAMETER WalkingPlayerState.gd:5 in these Reticle.gd func _process(delta): adjust_reticle_lines() state.gd func physics_update(delta: float) -> void: pass IdePlayerState func update(delta): if Global.player.velocity.lenght() > 0.0: transition.emit("WalkingPlayerState") WalkingPlayerState func update(delta): if Global.player.velocity.lenght() == 0.0: transition.emit("IdlePlayerState") im kinda stuck..
Too little content. If you continue publishing your videos at this rate, it will be 2026 until your FPS is ready and your Godot videos are all out of date again.
I'm getting an "Invalid call. Nonexistent function 'exit' in base 'Node (IdlePlayerState)." when I walk forward, and the scene closes. I'm not sure why, I assume I missed something, or it's covered in the next video. Edit: I may have fixed the problem. At CURRENT_STATE.exit(), I put an underscore in front of exit and it works. -> CURRENT_STATE._exit().
make sure to add ".name" to the CURRENT_STATE in the debug.add_property script! EXAMPLE: #global script name here!!.debug.add_property("Current State", CURRENT_STATE.name, 4)
This is getting to be so much fun! Hope it's helpful for you guys
🔥 GET THE SOURCE FILES ►► www.patreon.com/StayAtHomeDev_
👉🏼 FREE BASIC FPS SETUP SOURCE FILES ►► github.com/StayAtHomeDev-Git/FPS-Godot-Basic-Setup
I found a much better way to check if the player is moving
get_real_velocity().length()
This gets the actual velocity, not intended velocity. This works better because sometimes you want to move but you cant, like you're up against a wall or something
I just want to say to anyone that isn't sure if they want to implement this.
Do it.
If you're worried about time, It won't add almost any time to implement it if you do it early. It might take a bit if your code is getting confusing, but it will take you mush less time now than later when it's worse.
And if you're wondering if it's really worth it, it is. It's much easier to implement new things and everything is much more organized. And if something breaks, it won't break everything else.
I was following your tutorial series up until the last video and decided a state machine was a great idea, so I implemented that last weekend :D Awesome to see your take on it and great tutorials so far!
Thanks! Going to be working with states for a bit to flesh out the movement. Then we get into some more fun stuff ;)
@@stayathomedev looking forward to it! Will you be extracting the movement code itself to the states?
I don’t get why your channel isnt at 100k yet. You make amazing content! ❤
Wow! Thanks!
Another way to pass the player reference programmatically is to get a single reference for it in the state machine then pass it down as a property to each state when iterating through children.
Nice tutorial!
I had a trouble with this part in bugged out version of Godot 4.1, in 4.3 it works as expected. Thank you for the tutorials.
Half way through, I'm loving the inclusion of some error handling! Another great video so far.
Glad to hear it!
This is amazing! I just fiunished my implementation for episode 6, now time to get my hands on StateMachines!! Thank you so much for this content!
Awesome! State Machines rock!
@@stayathomedev Sure they do!!
Just finished implementing a State Machine that works differently. States are children of the State Machine, then Actions and Transitions are children of States and Decision is child of Transitions. This way can split into reusable Actions and Decisions. And also swap StateMachines realtime for different phases
Mind explaining a bit more in depth on how this works / what exactly you mean?
@@iglobrothers645 Instead of having all the code of actions and transitions inside one state script, I split into State, Actions, Transitions and Decisions. State and Transition scripts never change, just drop them to the nodes and set the True and False states for the Transitions. Each transition should have only one decision which will return True or False. Each state can have any number of Actions, which I like to make as simple as possible for reusability.
at the end my debug panel isnt updating my state, it's stuck on Idle but im not sure if my debug panel is the issue or if its my statemachine, how can i fix that?
Mine is spazzing out and I can't read it
@@tenofhearts99 I think the spazzing part, is the order of debug panel, since the video put 1, it causes spazzing you mention, I put it on 5, it's much better
Hey my state isn't showing up in the debug panel, what do I do to fix this?
i was about to ask but i eventually fixed it, thanks for your tutorials
Man these videos are the best I've ever seen for Godot 4! When I updated from 3.5 to 4 I couldn't figure out anything but these videos helped so much!
Hahah also I was just wondering why I was getting the red overlay and figured out it was because I didn't save the state script! I was trying to fix it for like 15 minutes.😂👍
Question: I am getting the "Invalid call. Nonexistent function 'enter' in base 'Nil'." error whenever I try to run the scene. My working theory is that CURRENT_STATE is not set to anything by default, yet the same code seems to work in the video? Please advise.
Answer: I forgot to set "Current State" In the inspector to be set to idle by default. Never used that feature before this series so no wonder I didn't know what was wrong :P
@@TheSpeedyBoi thank you so much for taking the time to make this comment. I did not realize that I also missed that instruction as I was going.
This helped so much! Thank you, @@TheSpeedyBoi!
Hi I know this video is not very recent, but could using a singleton for player variables affect other player character variables when using it for a multiplayer game?
Damn Nice!!
Thanks!
ERR: could not find type "State" in the current scope, any ideas? everything seems to be laid out fine
Did you figure it out? At the top of your state script you should have this:
class_name State
extends Node
after the first save with those two lines, the class called Stae should be accessible from every script.
@@the-birbo sure did, thanks
I got an error in CURRENT_STATE.enter(). Invalid call. Nonexistent function enter in base Nil
Make sure you set your Current State in the script export variable in the inspector.
Can you please help with the errors? The parameter "delta" is never used in the function "physics_update()". If this is intended, prefix it with an underscore: "_delta".
UNUSED_PARAMETER
state.gd:16
thats odd, that's usually only a warning
you probably fixed it by now, but did adding the underscore fix it?
When I move the state machine and its child nodes to a different scene, the current player states stop showing. How can I fix this issue?
Anybody else having issues with class_name? In the "Attach Node Script" screen I don't see an option for class name. I put class_name in my script but when I inherit from state .gd it does not create the new class automatically. Do I have to enable class names in my project settings or something?
What I don't really get is why you use the Walking state script o check if you're supposed to go to Idle manually, and also from Idle to Walking. Why not check for movement in Walking and for standing still in Idle? Wouldn't that be why we did this in the first place?
The IdleState already knows that the player is standing still. The point of the update function in the State class scripts is to check for an exit condition from the current state. This way when you want to do something while in that state, you don't need to check in the conditions of the state are met since it's already assumed that the conditions to be in that state have already been met.
@@the-birbo After thinking about this for a few days and following the tutorial further I get why this works, but I also think there's ways that work better with how I think myself. thanks for your reply!
How make state for differents characters like team fortress 2 or overwatch and is it possible to not work on animation with state or it's already the case with the mesh and collision shape or it's not and 1 model with skeleton3D is needed
hey, great tutorials. They help a ton. One question, my state isn't changing when i move. I think my _update function isn't triggering in my states. Any ideas on how to fix it?
edit:
make sure you have an underscore before all calls on exit(), enter(), and update(), otherwise it calls the wrong function
I have one question: do I need to create state machine if I already have state flags in my player controller? (For example walking = true, etc.)
Flags can work for simple setups but a full machine will make it MUCH easier to organize your logic in the future.
5:45 wouldn't a static variable do the job too?
How come many Godot videos on state machines are creating their own state machines from scratch?
I am currently experiencing my state machine not transitioning states whenever I move, my script and current project settings match this one. I hope somebody has a solution, or an explanation.
oh, I forgot to connect the child transition signal. Be sure to do this or else stuff breaks!
Hey I'm having the same issue and I'm pretty sure I already connect the child transition. What else did you did?
*Is it the same state machine , like we have Finite state automata , in theory of computation?*
yes
My state is not updating in the debug panel. I'm getting a bunch of error stating that delta is never used on the State.gd functions mostly and that "State does not exist" push warning so it looks like whatever state I'm trying to update to doesn't exist?
Off top of my head...check the state names? State node names?
transition.emit("Insert NODE Name")
@@WasNeverBrandon Thank youuuuuuuuuu
I was having the same problem with the in-game debug panel, so I put print(current_state.name) in the on_child_transition() function and it showed in the Godot output panel at the bottom that the state is updating properly, so it had to be a problem with the add_property() function in the debug script. Turns out I was missing the end of the function, so everything was just being added and not updated if it already exists.
This is the bit I was missing after the "if !target:" chunk in the add_property() function
elif visible:
target.text = title + ": " + str(value)
property_container.move_child(target, order)
If anyone gets the issue where it won't let you set anything to the default state in the inspector like I did. Restart Godot it was apparently just being buggy.
On the debug info, the state keep staying as idle if I move it. When I check the debugger, I got the warning about "State machine contains incompatible child node". I'm pretty sure I've followed the instructions, and the same people that got the problem here either got unknowingly fixed or still haven't receive any answer.
Make sure all child nodes are using the State class
@@stayathomedev Yep I did making sure they are using the same State class
For some reasons the debugger says "this state does not exist"
Any idea where the error may be?
Check that it's a child of the state machine OR you set a default statr
I'm receiving an "invalid Call. Nonexistent function 'connection' in base 'signal' error. It looks like something is wrong with my child.transition.connection(on_child_transition) line in the State_Machine script. Anyone experience this issue and have a solution or an idea where I went wrong? I've gone back through the video twice now and my scripts appear to match up with the tutorial
I found my typo in this issue (should have been connect instead of connection) but I'm not seeing the CURRENTSTATE change in the debug panel
Same here, plzzz tell if u found something plzzzz
very cool
Identifier "transition" not declared in current scope. Help plz :)
I'm sure you already figured it out, but in case someone else has that problem, make sure your IdlePlayerState and WalkingPlayerState scripts have "extends State" in them, then go to to your State script and make sure you spelled this signal correctly, then go to the line where you connect the state to the transition signal and make sure everything is spelled correctly. If this doesn't solve the issue, try saving and reloading the project.
@@the-birbo yea, i was able to fix it. Now working on character design models. Thanks anyway.
Are those control nodes?
Basic Nodes
@@officialdreamplayz thanks bro you mean basic like 3D nodes or other nodes?
Getting errors complaining about "delta" in the "_process(delta):" Reticle, in "physics_update(delta: float) -> void:" in state.gd, in " func update(delta):" in IdlePlayerState, and in func update(delta):" in WalkingPlayerState. why did this get triggered from the global?
it says it wants an underscore but why?
@@patrikgranstrom7683 same, get these:
W 0:00:00:0885 The parameter "delta" is never used in the function "_process()". If this is intended, prefix it with an underscore: "_delta".
UNUSED_PARAMETER
Reticle.gd:17
W 0:00:00:0893 The parameter "delta" is never used in the function "physics_update()". If this is intended, prefix it with an underscore: "_delta".
UNUSED_PARAMETER
state.gd:13
W 0:00:00:0895 The parameter "delta" is never used in the function "update()". If this is intended, prefix it with an underscore: "_delta".
UNUSED_PARAMETER
IdlePlayerState.gd:4
W 0:00:00:0897 The parameter "delta" is never used in the function "update()". If this is intended, prefix it with an underscore: "_delta".
UNUSED_PARAMETER
WalkingPlayerState.gd:5
in these
Reticle.gd
func _process(delta):
adjust_reticle_lines()
state.gd
func physics_update(delta: float) -> void:
pass
IdePlayerState
func update(delta):
if Global.player.velocity.lenght() > 0.0:
transition.emit("WalkingPlayerState")
WalkingPlayerState
func update(delta):
if Global.player.velocity.lenght() == 0.0:
transition.emit("IdlePlayerState")
im kinda stuck..
Cool, I've always loved FSM and this is a good example. But debug breaks the hell out, creating endless labels, even if the code seems the same.
What's happening with the debug code?
Solved! I was using double points in the title, which messed up the find_child function
Awesome! Glad it worked out
I really don't understand why using nodes for states.
I think it is a Godot thing.
Bro i don't know but my state isn't changing
What's the problem?
@@stayathomedev My CURRENT STATE isn't changing in debug panel , it always stays Idle,
Does it change at all or just not in the debug?
Thanks for asking but fortunately I fixed it and still don't know what was wrong at that time
I really appreciate the series please keep going
@@glitcher4O4 what was your fixed? I have a similar issue
Hello that's look working for me, but i don't think really understant all this stuff
👍
Plzzzz help
lmao, my comment got deleted
What was it?
Too little content. If you continue publishing your videos at this rate, it will be 2026 until your FPS is ready and your Godot videos are all out of date again.
Its only a week between videos. Not even that long.
@@foureggsinafryingpan3870true, he's just hatin' for no reason
I'm getting an "Invalid call. Nonexistent function 'exit' in base 'Node (IdlePlayerState)." when I walk forward, and the scene closes. I'm not sure why, I assume I missed something, or it's covered in the next video.
Edit: I may have fixed the problem. At CURRENT_STATE.exit(), I put an underscore in front of exit and it works. -> CURRENT_STATE._exit().
What script do you have in the IdlePlayerState node?
@@stayathomedev The IdlePlayerState one.
@@stayathomedev Strangely, putting an underscore at .exit() seems to have fixed the problem.
Everything is working, but i'm getting "Player State: Idle_PlayerState: "
I wish it didnt show the node. idk why it's there
make sure to add ".name" to the CURRENT_STATE in the debug.add_property script!
EXAMPLE:
#global script name here!!.debug.add_property("Current State", CURRENT_STATE.name, 4)
I might not understand or have not done something, as I don't see my fps in the debug panel anymore. Help?