For Godot 4 users: export (int) var speed = 100 ----> @export var speed = 100 as int move_and_slide() no longer accepts the Vector2 argument in its brackets. Instead you now set the velocity variable and then call move_and_slide() on the next line. velocity = move_direction * speed move_and_slide()
Thanks again for the updates! One small note: In Godot 4, you can now explicitly type your export variable. So the line should actually be: @export var speed: int = 100 Using the type operator (":" or ":=") is much better than using the "as" operator. Everything you wrote is correct though!
A kind tip for Godot 3.5 users: you can use the code as follow to replace the redundant "if Input.is_action_pressed" codes. This is a new powerful feature:) movement_direction.x = Input.get_axis("ui_left", "ui_right") movement_direction.y = Input.get_axis("ui_up", "ui_down")
I did by myself the Dodge the Creeps some time ago and got pretty discouraged since I really didn't understand what was going on, but I've just started this series and so far I've found it amazing! You go into great detail at each step, and so far everything has been clear. Definitely will continue with this and more of your tutorials!
Just a note, and I’m sure u know, but for others watching, move_and_slide should be used in _physics_process(), so it can use the correct delta for calculations, otherwise things can jump around in weird ways
You're totally correct, thanks for mentioning this! Doing this in _process was just an accidental brain fart when I first made this series, but we correct it in a later video 🙂 thanks for leaving that note here for others, though.
Thanks for sharing this! Getting player input is so simple with "get_vector(...)", and I wish it was around when I first made this video. This solution will work both in Godot 4.x and those who are still following this in Godot 3.x! (If you do this in 3.x though, velocity will still be a separate variable like you see in the video, rather than a built-in property like in 4.x)
Wanted to make some simple games for a while and your series actually got me to install something and do it so thanks :D, I'm a web dev so hopefully some things are transferable there.
That's awesome, so glad to hear! I had a similar journey from React + TS dev to starting with Godot, and found it really helpful - React's component structure is very similar to Godot's scene tree in a lot of ways, so hopefully you'll be able to find a lot of overlap. Best of luck learning game dev!
@@jmbiv_dev Thanks, so far planning on powering through a few tutorial series and was thinking of attempting to make some boss fights as a next step afterwards, figured they are small projects that could get increasingly harder. Does that sound like a good way to get started?
Thanks! It's the One Dark theme (first popularized by the Atom editor). You can get it for Godot at this link: github.com/Calinou/godot-syntax-themes - also worth noting that I set my engine theme to Arc, rather than default, to make the blue a bit more muted and match the One Dark script theme a bit better.
Great video. Is there any way the game character will smoothly rotate towards the direction it moves to? No mouse is used in this case. Only keyboard keys.
Thank you! And yes, definitely. You can use a linear interpolation to get a smoothed rotation over time. We're actually going to be looking at this in the video coming out this Saturday (episode 9) but in the meantime you can look-up how to use the lerp() function in Godot to achieve what you're looking for.
Thanks for the feedback! About halfway through this series I bumped up the font size and will continue to keep things a bit more zoomed in for future videos, so hopefully it's a bit easier to see.
Question: @13:47 you talk about move_and_slide returning a value. could you programmatically show how you code this and use it ? and why would you care what the return value is? also.. i am using godot 3.2.2. when im keying in move_and_slide another option pops up move_and_slide_with_snap() why and when would we use this option ? thanks... BTW your teaching skills is pretty good. so far im 100% understanding and retaining all the information your showing.
Hey Troy, sorry for the delayed reply, I was on vacation for the last week. Thanks for the support and for watching the videos. Those are good questions - here are some quick answers, and let me know if you still have questions after. As for the move_and_slide return value, sometimes the velocity you pass into move_and_slide is not how your character actually moves. For example, say your character is running into a wall - you may calculate a velocity, but when you call move_and_slide it will return a velocity of 0 since your character can't actually move into the wall. This actual velocity is what move_and_slide returns, so you can use it to check and make where and how quickly your character is moving. Does that make sense? Regarding move_and_slide_with_snap, it's a modification of the move_and_slide function that makes sure your character snaps to the ground below. You pass in a vector to determine where the ground is, and as long as that vector makes contact with the ground, your character will be attached to that surface (so if you have a jump mechanic, for example, it won't work by default with this method). I've never really had much use for it, but you can read more about it here: docs.godotengine.org/en/stable/tutorials/physics/using_kinematic_body_2d.html#move-and-slide-with-snap
Hello there, your tutorials are great! Especially the fact that you are explaining that much makes it a whole lot easier to understand what is going on for a beginner in programming like me. Thank you for your time and effort that you put into this videos! Because I really can't figure it out myself I have to ask you this, maybe others struggle with it as well: Is there any possibility I can use the code of the gd-script which is created so far and let the character turn/face simply into the direction it is moving, so that no mouse is needed? Have a nice day and thanks in advance, keep on the great work :)
Thanks so much! Glad they’ve been helpful. As for your question, definitely! You should be able to just set the global rotation to be the same vector you use as your movement vector - something like global_rotation = movement.angle()
@@jmbiv_dev @jmbiv Thank you for the tip, it worked out fine. The player moves in 8 dir, the sprite turns into the direction of the movement. simply added the line into the code: movement_direction = movement_direction.normalized() move_and_slide(movement_direction * speed) global_rotation = movement_direction.angle() Only problem left: The player does not stay faced to the direction it moved the last but turns back to the right everytime. To keep the "look_at" command I created sort of lock-on for the player: if Input.is_action_pressed("lock_on"): look_at(get_global_mouse_position()) Note: This only works as long as the button is pressed; by releasing it, the player returns to 8 dir movement. By this the player moves again in the way intended in this video, which seems pretty convenient to me while in a fight or focussing onto a special point/object/etc., while walking around with 8 dir movement may be a bit more relaxed. Btw, do you have a tutorial on locking onto an enemy? Greetings and thanks again :)
@@jackmakmorn Awesome, glad to hear you were able to get it working! I don't have a specific tutorial to locking on to an enemy, but you can do something similar by doing look_at() and then passing in the vector to that enemy, which you can get by doing something like (enemy.global_position - global_position). We do a really similar thing (where the enemy locks on to the player) in tutorials 8, 9, and 10 I believe - whichever one is "Allies and Enemies" or something similar, so you might want to reference that for further help.
@@jmbiv_dev Haha, ok cool, I just stopped after Part 9 because the Enemies are acting a bit different as intended - so I will check out part 10 anyways 😀 I am sorry to bother you again with the playercontrol 8 dir, but I wasn't able to make it out earlier with other tutorials and didn't get it yet; how do I tell the player to keep facing to the last direction he moved? 8 dir seems to me like one of the most complicated things in Godot 😐
Heyo, I haven't finished the series (not even close), but is there any way to make it so the player doesn't have infinite inertia so they can properly interact with rigid bodies?
Great question! I've actually never really tried to have Kinematic and Rigid bodies interact with each other in Godot - I know you can make it happen, but not sure if it just works by default or whatever. If you don't really need rigid bodies and just want to add inertia, you can always add those properties and create your own simple momentum system with a kinematic body, but depends on your game. Hope that's a helpful start, and feel free to ask questions in Discord if you're having trouble making it work!
well, i did this and it works: movement_direction = movement_direction.normalized() velocity = movement_direction * speed move_and_slide() well. it dint work at first, took me like 20 minutes of tutorials and googling, but then i noticed, that i forgot to change the user input names... so I had "up" there 4 times from the copy and paste...
For anyone else who sees this and has the same question, in Godot 4.x you don't pass in velocity as a parameter to move_and_slide(). Instead, you just set the velocity property in your code, and move_and_slide() uses that property under-the-hood. The comment here by @wastedlife4842 has the correct syntax!
Hi! I'm following along with this tutorial, and everything technically works. But after adding in the look_at(get_global_mouse_position()) line, my sprite's rotation is not as tight as what I see in the video. There's a good inch between the sprite and the mouse at all times, and my sprite is doing these big and sweeping circles instead of just a simple rotation. Any idea why my sprite would be doing this? Also, out of curiosity, is it possible to just have the sprite follow the mouse and cut out the WASD keys altogether? Thanks in advance!
Usually you see a rotation effect like the one you describe when you're not actually rotating your sprite around its center. There could be a couple reasons for this: 1. Your sprite doesn't have the "centered" box checked under the offset section 2. Your sprite's center is very far from your KinematicBody2D's center (the KinematicBody should be the parent of your sprite). In my own version I have them very slightly separated, but it's not really noticeable. The key here is that we're rotating the entire KinematicBody, not just the sprite, so if there's a lot of distance between the center of both of them, it's going to look a bit weird. Check both of those things and see if it makes a difference. If not, feel free to hop into the Discord server and I can help you more there. As far as just having the sprite follow the mouse, definitely possible! You would have to set movement_direction to be the vector from the player to the mouse (so, something like "movement_direction = get_global_mouse_position - global_position"), and then set this vector as your "movement_direction" vector, and the code should just work (since we're already normalizing movement_direction and multiplying it by the speed)
Definitely! Some things that come to mind that might be the issue: 1. Make sure that your "if" statements are all "if" statements, without any "else" or "elif"s 2. Make sure you don't "return" in any of your "if" statements 3. Make sure in your input settings that you assigned the right key to all four inputs - maybe only the D/Right key actually got saved? If those don't work, feel free to add more context here or you can join the community discord (link in the description) and upload a picture of your code there and I can help further!
@@jmbiv_dev Hey! Thank you for the response. Unfortunately i couldnt make it work. I posted a screenshot of the code in discord like you said, i hope you can take a look at it. Im sorry but im new in the coding world and i dont understand it :p
What node is the script attached to? "move_and_slide" only exists on KinematicBody2D and KinematicBody3D nodes, so if you try to call it from another node, that would be why you see that error.
We’ll need a bit more info to help you figure out what’s wrong. Can you try going through the steps in the video again? If it still isn’t working, join our discord server and we can help you out there.
that input map is one the only things that annoys me about godot, I think they should offer the user an option to create a basic standard set and use that on each project, Ive watched alot of godot tutors to try to learn stuff, and one of the things they do is create a new input map, I cant understand why, its just a string reference?? so using "ui_left" is fine, just add the WASD keys to those ui references,, anyways, godot needs to be updated to allow a basic saved settings for the user, then not every project has to be reset, everytime.
You raise a good point about the input map! You almost always end-up defining the same custom input bindings each new project. You can import them from another project by coping lines from your project.godot file, but it would be really nice to have an in-editor way to do this. That said, I would avoid adding WASD to your "ui_direction" inputs. I wish this was more well-known or other tutorials mentioned this more, but Godot uses those inputs automatically to handle UI navigation, so tabbing or moving around your UI (any Control node or its inherited nodes) works by default. Because of this, if you add something like WASD to your UI inputs, you could accidentally mess up your UI navigation if somehow your UI captures an input that was meant to move the player, but instead navigates focus to another UI element. You really don't want that, and more importantly - people who use screen readers and UI accessbility features really depend on having clean and good UI navigation. All that to say, you raise a good point, but there's a reason that most people create separate input maps for movement/attacking/clicking/etc. You really only want UI navigation inputs to be used in your "ui_direction," and anything else needs its own new input map. Even though it can be a minor annoyance, this is actually one of the most powerful features of Godot in that you can easily use the same "attack" input, for example, and bind it to a mouse click, the right trigger on a controller, or a tap on a phone. Godot lets you use the same input map for multiple platforms, which really helps from a code perspective. Anyway, just wanted to give some helpful clarification since the importance of the UI input binds doesn't get talked about too much. Hope that helps!
I copied your script but why does my character move so slow compared to yours? I got the exact same speed you use. Edit Nevermind, it works. I have my main node and player node seperated. when I ran from the player node the speed var worked but from main it wasn't working. For some reason, it's working now in main
Hi, Since Godot has "ui_left", "ui_right", "ui_up", "ui_down"" as default inputs. Would you say to use "left, right, up, down" to make it simpler to reference or just for player movement, in case you might use seperate controls for Player and UI perhaps do to analog vs digital, etc. type of variations? Thanks
Great question! I intentionally separate regular controls and UI input controls. There are a few reasons for this, but one main reason is accessibility. Your "ui_left" and "left" controls might both have the left arrow key as an input, for example, but you will probably have some extra UI controls for accessibility. Additionally, Godot includes the default "ui_direction" inputs because it's UI system uses those inputs by default to include built-in accessibility navigation of UI controls. So, all that to say, it isn't necessary to separate them, but I think it's a good idea to separate them and it's a decision I intentionally make.
Yes, for sure! I've got another tutorial about using melee weapons you can find here: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-dBvfwLxoY3I.html To actually implement this melee system into the top-down shooter game shouldn't be too hard; instead of creating guns and bullets, you can just create a sword or melee weapon of your choice, and go from there. If you need any help getting it to work you can hop into our discord and we'll be happy to help!