is the scene built like in the video ? because i have a very weird camera glitch when i jump and sadly i cant clone the tscn file since i am not allowed to
Have been scratching my head on how to solve the issue with sliding on slopes, so this video came out at the perfect time. Great tutorials, keep it up!
This is awesome, just one thing can be optimized Change: if ground_check.is_colliding(): full_contact = true else: full_contact = false To: full_contact = ground_check.is_colliding()
With the capsule Height at 3 meters and the Radius at 1 (half a sphere of 1 meter each side) it means your character is 5 meters tall. You should use an Height of 1 and radius of 0.5 to have a character 2 meters tall. You can remove the sliding and slow movement on slopes by using the method move_and_slide_with_snap(velocity, snap, Vector3.UP, true, 4, deg2rad(45)). On the floor: snap = Vector3.DOWN * 0.1 When pressing jump: snap = Vector3() Also it will allow your character to stick on moving platforms/vehicles and you will save lines of code.
My design sticks to moving platforms and slopes as well, plus by having a dynamic gravity vector that takes slopes into account you eliminate the problem of your character moving slower when going up hills. Also my games only have giants in them ;)
well yh, but that's pretty much bcus no-one wants to be off-track. like when i'm using a tutorial for script in godot, i always write everything to a t
Hey, nice video! If my feedback is welcome I think that you should make the editor UI bigger so it is easier to see, right now all the fonts are super tiny in your video and old people like me have a bad time trying to read it haha (Editor > Editor Settings > Display Scale) Cheers :)
You are a genius. I spent hours on forums trying to find a workaround for stop_on_slopes not working with move_and_slide_with_snap and all sorts of things with little success, and here you just come along changing the gravity vector. I wish I would've seen this video earlier!
I like setting a jump height variable instead of jump force or speed or whatever. this way I don't need to keep trying different values for the jump speed and gravity that look good. Using a kinematics equation: jumpVelocity = sqrt(2 * gravity * jumpHeight) I hope this helps!
For those of you who are tired of ctrl+tab'ing from the game , in order to close it while debugging, add this: func _process(delta): if(Input.is_action_just_pressed("ui_cancel") and Input.MOUSE_MODE_CAPTURED): Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Now you'll be able to press "Esc" to get the mouse cursor back, and press the "x" thingy. Have a jolly good evening :D
For acceleration, I tend to use h_velocity.move_toward() instead of linear_interpolation(). It might require a different value for acceleration. The difference is that velocity changes linearly but with interpolation logarithmically (although closer to reality).
@@AgnisNeZvers It is okay, I later find out that the move_to() was older version of Godot function to behave like move() in newer Godot version. Edit: I got it wrong, move_to() and move() are no longer present in Godot 3.2.
This is hands down the best fps character controller I've seen for Godot thus far; especially since it solves the slope problem that *every other tutorial* has.
If you really need to slide on slopes for some reason, try using dot product between the groundCheck raycast and the floor normal, if the dot product is greater than some treshold, then the character just don't use that logic to stick to the floor and will start sliding. Great video
Aight, I'm off to check your library of videos cause I have some issues with emission strenght > 1 giving off some artefacts if I turn on glow in the world env... and I have glowing runes on walls, meaning, if you're far away, you're greeted with jpeg like artifacts, and I did sort of fix it after spending ( I'm not kidding ) the last 10 hours on that and a few other rather minor issues... and now I took a youtube break. Thanks for being here!
Gravity is integrated here as a speed (y -= gravity), but it should be integrated as an acceleration. That is, the acceleration is the derivative of speed, hence a change in speed. If you have a constant speed, the acceleration is basically 0 and free fall would feel less realistic. You have to make it so that the derivative of your speed is a constant - the gravity acceleration. It means that your speed should increase with 9.81 m/s every second in order to implement proper gravity acceleration. One way is to keep the speed in a variable and increase it every frame by delta time * acceleration (9.81). Then use this speed to add to a position. Now, the derivative of your speed is no longer 0, so you properly accelerate.
for people in godot 4, "move_and_slide()" doesnt use any arguments anymore, and only follows the "velocity" variable so all you have to do to make the character move in the newest version is just add "velocity = movement" above your "move_and_slide()"
@@deandacat358 the variable "movement" is declared at 4:53 but if you dont want to use that im guessing you could just use "direction * speed" as your movement variable (i did not test this method tho)
Just a tip - If you just do check for one value to branch with if & else just to change one bool, then do assign result of that check on the variable. Less lines and easier to read: full_contact = ground_check.is_colliding()
Me: "You know Garbaj has inspired me to also try out godot to make a shooter I should check for a tutorial on how to make an fps controller in it" Full circle I guess
There is a problem with this code when you walk down a slope, the player does mini jumps, you can solve it by replacing move_and_slide() with move_and_slide_with_snap (movement, gravity_vec, Vector3.UP)
for people using 3.4.4 and the player is going up intead of foward change to this if Input.is_action_pressed("ui_up"): direction -= transform.basis.y elif Input.is_action_pressed("ui_down"): direction += transform.basis.y
Instead of using the ifs in the movement input I get the action strengths of the buttons and add them together in 2 statements, one for left/right and one for up/down in my character controller, might that be a little better, I guess it doesnt really matter since it only runs once per frame anyway and a couple of if statements like that isn't really going to do much to hurt the fps in this case but my version is definitely a little more concise since it only takes up 2 lines and not 8 which is nice :)
This has the added benefit of seamlessly adding support for analog input. Keyboards are digital; the button is either pressed or not. Controllers, on the other hand, are often analog; this allows a smooth transition from walking to running by simply pressing the stick harder/farther.
Would you be interested in doing a video going over a FPS controller for a retro FPS game like quake or dusk? I've been working at it for a while now and still have some kinks in it.
I was listening to music when I first started playing this video, and the chorus started, so it was just: "In this Godot tutorial, I will be showing you how t-" *Japanese singing intensifies.*
You could have scripted the movements like this to make it compatible with an analog stick: direction = Vector3() direction.z = -Input.get_action_strength("move_forward") + Input.get_action_strength("move_backward") direction.x = -Input.get_action_strength("move_left") + Input.get_action_strength("move_right") direction = direction.normalized().rotated(Vector3.UP, rotation.y)
Hello! This is an awesome video! The explanation is crystal clear! I just have one question, can I put some animations to it? If yes, please make a video explaining how. thank you so much and more power! : )
I've found a better way to code movement, but i think it can be further improved. The key is using move_toward function, this way you can have acceleration, friction and max_speed without clamping: func move(delta): direction_vector = Vector3.ZERO var x_vector = camera.global_transform.basis.x * (InputForce("move_right") - InputForce("move_left")) var z_vector = camera.global_transform.basis.z * (InputForce("move_backward") - InputForce("move_forward")) direction_vector = x_vector + z_vector direction_vector = direction_vector.normalized() if direction_vector != Vector3.ZERO: velocity_vector = velocity_vector.move_toward((direction_vector) * max_speed, acceleration * delta) else: velocity_vector = velocity_vector.move_toward(Vector3.ZERO, friction * delta) move_and_slide_with_snap(velocity_vector, Vector3.DOWN, Vector3.UP, true)
I agree with this statement conceptually, but... This is something that can be caught in the optimization passes; don't make the mistake of optimizing prematurely, or you end up in some strange rabbit holes. I once spent a couple days trying to determine whether "for" loops or "while" loops were "optimal", before realizing that the compiler/engine usually optimizes all loops to the same machine code regardless, making which loop you use a choice of style rather than efficiency. That being said, "best practices" are certainly something to strive for... just don't drive yourself crazy about how efficient something is before you have the code actually functional.
Also, what solution do you have for moving platforms? I found that straight down gravity can work on slopes if disable stop_on_slope and have floor_max_angle correct AND continue adding gravity also when on a floor. But to work with moving platforms you shouldn't add gravity when on the floor (and probably need move_and_slide_with_snap).
Im in 3.1 and when i try to move my character the only key that works is the d key and all the other keys just dont respond, instead it stops the player completely, please help 😭
There is one problem here... If you hold down the jump button, the player does not touch the ground before relaunching again, it jumps from the end of raycast
Yo, mr Garbaj, sir, how would you handle small steps, like... with move_and_slide, even if something is 2 inches, it will promptly stop you in your tracks... and I was thinking of casting a ray using the velocity vector to get where I'm looking, but it's kinda hard to: 1) figure out it's the top of the collider that the ray hits 2) get the data out so I can "step" to the right height 3) how I'd step in the first place...
after i finished at 2:14 i tried to run it and yes i made a floor in another scene and chose that scene when played but my debug goes black when i run it please help!!!
curious, since you already assigned ground_check.is_colliding() to full_contact, why not just check for full_contact when determining if the player could jump instead of making yet another check for the raycast colliding?
yeah he has a basic csg tutorial, but if you want to make a nice map i suggest making your own models, learning custom collissions and how to optimize using portals and multi-mesh instancing
Hi Garbaj. I'm following your awesome tutorials and I'd like to thanks for them! I'm trying to implement crouching and jumping into this new updated FPS controller. Jumping, sprinting works fine, but cruching is kinda buggy. Seems like the Foot collision can be a problem? In Your first FPS controller version the crouching works fine, but here the camera moves just a little bit down (this is why I'm thinking the Foot is messing here). Do you have any suggestion please?
Questions I had during watching: How does direction get, which way you're facing? My guess would be, that rotate_y in _input() changes the transform.basis so you can rely on that. Also wondering: Why did you put the key pressed inputs into _physics? Putting it in _input would seem to be the more obvious place for me, but I guess there's a good reason for this.
Even though the player capsule looks the same from all sides, it has a distinct front and back side. For example, you can think of -transform.basis.z like a little arrow that always points out of the front of the player capsule (-z is forward in Godot). When you rotate the player capsule using rotate_y, transform.basis rotates along with it. Direction just copies the direction of that transform.basis arrow and says "thats the direction we want to move". As far as the input question, I believe we put the key inputs in physics process because it updates a fixed number of times per second which is important when dealing with thing involving physics (such as moving the player controller) whereas input does not. Not too sure about this one though
I found a problem with this engine. If you are standing underneath a low ceiling and you jump, then you stay stuck to the ceiling for a few seconds instead of bouncing off the ceiling and landing on the ground. How can this problem be solved?
@@garbaj I wrote this in the physics process function, but if I hit the ceiling now the game crashes and the error says _Invalid get index 'z' (on base: 'int")_. It then says the line that caused this was _movement.z = h_velocity.z + gravity_vec.z_ if is_on_ceiling(): gravity_vec = 0
@RYAN RIVERA Because $Camera looks for a node called "Camera" on the NewFPS, it doesn't see it though. It should be $Head/Camera or better just $Head instead.
7:45 for me it seems to work better with: if not is_on_floor(): gravity_vec += Vector3.DOWN * gravity * delta elif is_on_floor() and full_contact: gravity_vec = -get_floor_normal() * gravity else: gravity_vec = Vector3.DOWN * gravity * delta When I do the "else" statement your way and walk over the edge of a ramp my character seems to slightly fall in the "ramp normal" direction.
Dang, it took me half a day figuring out why my player wouldn't move. Forgot that if I move my fps controller to another project, I have to set the WASD inputs again.
The Godot documentation for InputMap ( docs.godotengine.org/en/stable/classes/class_inputmap.html ) has some functions that can help you assign the actions and keys via script, so you don't have to manually change the mappings for each project. Specifically, look for add_action() and action_add_event() - don't forget to use has_action() to avoid duplicating action names, and event_is_action() can help you avoid keybinding collisions (eg, you don't want to bind "Space" to both "jump" and "fire"). A good place to add actions/events is in the _ready() function.
Here's an example, adding the "move_forward" action and setting its key to "W": var key_event = InputEventKey.new() key_event.scancode = KEY_W InputMap.add_action("move_forward") InputMap.action_add_event("move_forward", key_event)
this doesn't seem to work if the body is moving very slowly. could you look into how to get characters to move up and down slopes while walking, as well as how to handle slopes meeting a flat surface? i find that my characters get stuck trying to go down slopes where the flat surface meets the slant, no matter how much I try to get the colliders to be pixel perfect
Hey I'm curious how you feel about other devs using your code in their games? Im a new game dev and I'm not sure what the etiquette is of using tutorial code in your own games? Do you expect people to get a general sense from your code and make something different or do you just not care at all? Thanks :)
The code is open sourced under a MIT license so people are free to do what they want with it unless otherwise specified. Hopefully my tutorials can help people learn gdscript so that one day they don't need to use tutorials to make their games
So after watching the video and doing everything shown, the code works. However, when running next to a wall with collisionshape, the character gets almost magnetized to the wall, presumably because of the bit where we make gravity perpendicular to the ground your standing on. But then I just copied the code on your github, and this problem was solved. What is the solution to that?
Hi Garbaj, awesome tutorial. Question for you. My Kinematicbody Mesh is basically invisible, how do I get the white capsule look to show. Even if I click on visibility, it shows a vague grey capsule shape that basically blots out the grey lines
Hmmm, Found the answer. I noticed I did not have the DefaultEnvironment.tres. I tried to set in project settings-Rendering Environment but it would stay even after clicking open. When i Opened it then clicked on the default color above it would finally stay.
I thought this was excellent but have a suggestion. Given that you're covering stuff for beginners (which is great), maybe you should have stopped to take a moment to explain the linear algebra just a tad so they're not just copying your code but understand it a bit more. I liked your solution with gravity on slopes for example, but explaining to a beginner what minusing vectors means would likely have been helpful generally. Just a suggestion.
I understand what you're saying and I appreciate the feedback. The focus of this channel has always been on quick and concise videos and as such it doesn't exactly cater to beginners since I'm going through a lot of concepts quickly. This probably wont change, but I'm always trying to find a better balance of speed and thoroughness so thanks for the comment
@@garbaj That's absolutely fine. It's hard for me who knows a little bit more than a beginner what they would take away but I felt it was a little strong on the how and a little light on the why. Like I say, I could well be wrong here.
this tutorial is outdated. Use this version instead: github.com/GarbajYT/godot_updated_fps_controller
I used that new version but it doesnt work?
free code
Thanks a ton. How would you recommend adding camera switching?
is the scene built like in the video ? because i have a very weird camera glitch when i jump and sadly i cant clone the tscn file since i am not allowed to
is there a way to add double jump to it?
Honestly, between you and Miz, there are so many excellent, informative and concise Godot tutorials that I can barely keep up
Thanks, hopefully there's room for a few more tutorials
I really liked the part where you started giving the character head
Oh you joker
Have been scratching my head on how to solve the issue with sliding on slopes, so this video came out at the perfect time. Great tutorials, keep it up!
glad to help!
10/10 accidentally made half life 3
WHAT! HALF LIFE 3 i watched the the video and i didnt make half life 3 i made crappy fps game
@@surplusgames6059 he's just a little more talented than you
@@spartv1537 he jus built different
He is a born game devloper and we are made into game devloper
Oh no, why do I accidentally make half life all the time?
This is awesome, just one thing can be optimized
Change:
if ground_check.is_colliding():
full_contact = true
else:
full_contact = false
To:
full_contact = ground_check.is_colliding()
yeah, I realized it too late. This is 100% correct
Or you could even just do away with full contact and just use ground_check.is_colliding() as the condition
@@garbaj Yeah, I'd think it'd be more efficient to run the function once per frame, then multiple times a frame though
true
With the capsule Height at 3 meters and the Radius at 1 (half a sphere of 1 meter each side) it means your character is 5 meters tall. You should use an Height of 1 and radius of 0.5 to have a character 2 meters tall.
You can remove the sliding and slow movement on slopes by using the method move_and_slide_with_snap(velocity, snap, Vector3.UP, true, 4, deg2rad(45)).
On the floor: snap = Vector3.DOWN * 0.1
When pressing jump: snap = Vector3()
Also it will allow your character to stick on moving platforms/vehicles and you will save lines of code.
My design sticks to moving platforms and slopes as well, plus by having a dynamic gravity vector that takes slopes into account you eliminate the problem of your character moving slower when going up hills. Also my games only have giants in them ;)
Without you, I'd have left game development now.
DONT GIVE UP
@@garbaj I got rickrolled too many times to give up
This is the 10th time I return to Godot after trying out CryEngine and unreal
@@helloworld5219 F
@@xegrand7548 10th time?
"Name it whatever you want" - Proceeds not to name it "whatever you want" reeeeeeeeeeeeeeeeee
well yh, but that's pretty much bcus no-one wants to be off-track. like when i'm using a tutorial for script in godot, i always write everything to a t
Thanks for the Idea dude lol
Hey, nice video!
If my feedback is welcome I think that you should make the editor UI bigger so it is easier to see, right now all the fonts are super tiny in your video and old people like me have a bad time trying to read it haha (Editor > Editor Settings > Display Scale)
Cheers :)
Thanks, I was wondering how to do that
Garbaj : *explains everything in detail*
Me : *copy and pastes the code so I have more time to simply watch the video and admire it*
you are bad at this
You are a genius. I spent hours on forums trying to find a workaround for stop_on_slopes not working with move_and_slide_with_snap and all sorts of things with little success, and here you just come along changing the gravity vector. I wish I would've seen this video earlier!
I like setting a jump height variable instead of jump force or speed or whatever. this way I don't need to keep trying different values for the jump speed and gravity that look good. Using a kinematics equation:
jumpVelocity = sqrt(2 * gravity * jumpHeight)
I hope this helps!
This is awesome. I've been looking for a solution to the speed change on slopes for a while now. This is EXACTLY what I was looking for!
For those of you who are tired of ctrl+tab'ing from the game , in order to close it while debugging, add this:
func _process(delta):
if(Input.is_action_just_pressed("ui_cancel") and Input.MOUSE_MODE_CAPTURED):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
Now you'll be able to press "Esc" to get the mouse cursor back, and press the "x" thingy.
Have a jolly good evening :D
Thanks!
just get_tree().quit() instead of making the mouse visible, saves more time or instead, just alt+f4
or just press alt f4 for the shortest way
@@harukills but I'm on a laptop, ctrl+tab doesn't work and neither does alt+f4 so I'm stuck
oh alt+tab works
For acceleration, I tend to use h_velocity.move_toward() instead of linear_interpolation(). It might require a different value for acceleration. The difference is that velocity changes linearly but with interpolation logarithmically (although closer to reality).
I’ll have to try that out. Thanks!
Which version of Godot supports move_to() function? I don't see it in my Godot 3.2, maybe it's the newest function in the latest version.
@@Ngong8 sorry, my memory from GameMaker played a trick on me. It's move_toward()
@@AgnisNeZvers It is okay, I later find out that the move_to() was older version of Godot function to behave like move() in newer Godot version.
Edit: I got it wrong, move_to() and move() are no longer present in Godot 3.2.
This is really gonna help me quit worrying about programming a control and actually get on to building the damn game. Thanks!
Hey Garbaj, this tutorial still holds up! it's really fun and satisfying. Thanks!
Fantastic! I love it! Great tutorial! Much better than my old First Person Character Controller!
Glad I could help
This is hands down the best fps character controller I've seen for Godot thus far; especially since it solves the slope problem that *every other tutorial* has.
Thank you! It works like a charm and now I can start a 1st person project.
oh my god i've been trying to figure it out for AGES. thank you
If you really need to slide on slopes for some reason, try using dot product between the groundCheck raycast and the floor normal, if the dot product is greater than some treshold, then the character just don't use that logic to stick to the floor and will start sliding. Great video
Great tip, though I find that the floor_max_angle parameter built into move_and_slide() works just fine for that purpose
@@garbaj oh i didn't know that, guess i'll use that instead
Thank you a thousand for making this video. This really boosts the creation of my second game :)
Neat! This editor + gdscript... almost made game development kinda accessible for beginners. 👑✨👌
One thing not changed:
The player is still a BEAN
😂
we're all just human beans
I know that reference but this is the wrong engine
I wonder if he has made a tutorial on how to make gunshot effects with GODOTS PARTICLE SYSTEM :)
@@jlewwis1995 T H I C C
@@garbaj Bean gang rise up
got a godot ad from this video lol
Aight, I'm off to check your library of videos cause I have some issues with emission strenght > 1 giving off some artefacts if I turn on glow in the world env... and I have glowing runes on walls, meaning, if you're far away, you're greeted with jpeg like artifacts, and I did sort of fix it after spending ( I'm not kidding ) the last 10 hours on that and a few other rather minor issues... and now I took a youtube break. Thanks for being here!
Gravity is integrated here as a speed (y -= gravity), but it should be integrated as an acceleration.
That is, the acceleration is the derivative of speed, hence a change in speed. If you have a constant speed, the acceleration is basically 0 and free fall would feel less realistic.
You have to make it so that the derivative of your speed is a constant - the gravity acceleration.
It means that your speed should increase with 9.81 m/s every second in order to implement proper gravity acceleration.
One way is to keep the speed in a variable and increase it every frame by delta time * acceleration (9.81). Then use this speed to add to a position. Now, the derivative of your speed is no longer 0, so you properly accelerate.
I'm trying to make a semi-realistic tactical first-person RPG. This should help.
for people in godot 4, "move_and_slide()" doesnt use any arguments anymore, and only follows the "velocity" variable
so all you have to do to make the character move in the newest version is just add "velocity = movement" above your "move_and_slide()"
i tried this and it doesnt work, i get an error saying "Identifier "movement" not declared in current scope." can you help me?
@@deandacat358 the variable "movement" is declared at 4:53 but if you dont want to use that im guessing you could just use "direction * speed" as your movement variable (i did not test this method tho)
Just a tip - If you just do check for one value to branch with if & else just to change one bool, then do assign result of that check on the variable. Less lines and easier to read: full_contact = ground_check.is_colliding()
Thanks, I realized this a little too late
Thanks bro, really needed this!
subbed
Me: "You know Garbaj has inspired me to also try out godot to make a shooter I should check for a tutorial on how to make an fps controller in it"
Full circle I guess
There is a problem with this code when you walk down a slope, the player does mini jumps, you can solve it by replacing move_and_slide() with move_and_slide_with_snap (movement, gravity_vec, Vector3.UP)
true
Great content, mate.
been wondering, for how long have you been using Godot and what's your background in programming in general?
I started out with zero programming/game dev experience, and everything I learned was through youtube tutorials, the docs, and random experiments
Awesome 👍 I would appreciate it if you made a video of variables that can be changed with an in game options menu.
for people using 3.4.4 and the player is going up intead of foward change to this
if Input.is_action_pressed("ui_up"):
direction -= transform.basis.y
elif Input.is_action_pressed("ui_down"):
direction += transform.basis.y
Instead of using the ifs in the movement input I get the action strengths of the buttons and add them together in 2 statements, one for left/right and one for up/down in my character controller, might that be a little better, I guess it doesnt really matter since it only runs once per frame anyway and a couple of if statements like that isn't really going to do much to hurt the fps in this case but my version is definitely a little more concise since it only takes up 2 lines and not 8 which is nice :)
Care to show me how you did it?
This has the added benefit of seamlessly adding support for analog input.
Keyboards are digital; the button is either pressed or not. Controllers, on the other hand, are often analog; this allows a smooth transition from walking to running by simply pressing the stick harder/farther.
the best FPS controller I've seen Whimfoome write
I love you Garbaj
Would you be interested in doing a video going over a FPS controller for a retro FPS game like quake or dusk?
I've been working at it for a while now and still have some kinks in it.
Many thanks for the tutorial :)
Literally only tutorial where I have to watch at 0.5 speed instead of 1.5 lmao
thank you so much, this really helped
i love you man
I was listening to music when I first started playing this video, and the chorus started, so it was just:
"In this Godot tutorial, I will be showing you how t-"
*Japanese singing intensifies.*
You could have scripted the movements like this to make it compatible with an analog stick:
direction = Vector3()
direction.z = -Input.get_action_strength("move_forward") + Input.get_action_strength("move_backward")
direction.x = -Input.get_action_strength("move_left") + Input.get_action_strength("move_right")
direction = direction.normalized().rotated(Vector3.UP, rotation.y)
just tried it, it works!
it seems to lag alot for me
Hello! This is an awesome video! The explanation is crystal clear! I just have one question, can I put some animations to it? If yes, please make a video explaining how. thank you so much and more power! : )
I've found a better way to code movement, but i think it can be further improved. The key is using move_toward function, this way you can have acceleration, friction and max_speed without clamping:
func move(delta):
direction_vector = Vector3.ZERO
var x_vector = camera.global_transform.basis.x * (InputForce("move_right") - InputForce("move_left"))
var z_vector = camera.global_transform.basis.z * (InputForce("move_backward") - InputForce("move_forward"))
direction_vector = x_vector + z_vector
direction_vector = direction_vector.normalized()
if direction_vector != Vector3.ZERO:
velocity_vector = velocity_vector.move_toward((direction_vector) * max_speed, acceleration * delta)
else:
velocity_vector = velocity_vector.move_toward(Vector3.ZERO, friction * delta)
move_and_slide_with_snap(velocity_vector, Vector3.DOWN, Vector3.UP, true)
InputForce is just this:
func InputForce(key : String):
return Input.get_action_strength(key)
Video idea: How to make full controller support to your 3D game in Godot.
How to fix this eror 😥
line 50(RETURN _VALUE_DISCARDED):the funtion 'move_and_slide()'returns a value but this is never used
i also got it
Did you ever find a fix for this?
@@simonethistle9069 just press ignore
In the jump condition, you've already stored the result of `ground_check.is_colliding()`. Could spare the call-stack and just use the variable. :)
You're right, I realized this too late
I agree with this statement conceptually, but...
This is something that can be caught in the optimization passes; don't make the mistake of optimizing prematurely, or you end up in some strange rabbit holes. I once spent a couple days trying to determine whether "for" loops or "while" loops were "optimal", before realizing that the compiler/engine usually optimizes all loops to the same machine code regardless, making which loop you use a choice of style rather than efficiency.
That being said, "best practices" are certainly something to strive for... just don't drive yourself crazy about how efficient something is before you have the code actually functional.
Also, what solution do you have for moving platforms?
I found that straight down gravity can work on slopes if disable stop_on_slope and have floor_max_angle correct AND continue adding gravity also when on a floor. But to work with moving platforms you shouldn't add gravity when on the floor (and probably need move_and_slide_with_snap).
I just tested it out and it works perfectly with moving platforms
Im in 3.1 and when i try to move my character the only key that works is the d key and all the other keys just dont respond, instead it stops the player completely, please help 😭
Plz remake this tutorials for godot 4 plzzzzz😭😭😭😭😭
I wanted to check out the Godot basics video, but its unavailable! Please help!
@Garbaj please give me an another link for how to make world like this for my character
Awesome tutorial! Can you make this for Godot 4 as well? Also, is it possible to have different speed when going backwards and sideways?
There is one problem here... If you hold down the jump button, the player does not touch the ground before relaunching again, it jumps from the end of raycast
This a great tut thx
Yo, mr Garbaj, sir, how would you handle small steps, like... with move_and_slide, even if something is 2 inches, it will promptly stop you in your tracks... and I was thinking of casting a ray using the velocity vector to get where I'm looking, but it's kinda hard to:
1) figure out it's the top of the collider that the ray hits
2) get the data out so I can "step" to the right height
3) how I'd step in the first place...
after i finished at 2:14 i tried to run it and yes i made a floor in another scene and chose that scene when played but my debug goes black when i run it please help!!!
Same problem here
same
make sure that the camera doesnt have a separate enviroment, and make sure in project settings that at run time the engine loads the correct scene
THANK YOU I LOVE YOU MAN.......
You were talking so fast I had to reduce the speed to 0.5 or 0.75.
And at that speed it sounded perfectly normal.
the player is stuck in the air and jitters when I try to move, how do I fix this?
curious, since you already assigned ground_check.is_colliding() to full_contact, why not just check for full_contact when determining if the player could jump instead of making yet another check for the raycast colliding?
its quake-creating time :>
The godot basics tutorial link is dead
Do you have a tutorial about making a basic map
yeah he has a basic csg tutorial, but if you want to make a nice map i suggest making your own models, learning custom collissions and how to optimize using portals and multi-mesh instancing
That godot basics tutorial seems to not exist anymore
Hi Garbaj. I'm following your awesome tutorials and I'd like to thanks for them! I'm trying to implement crouching and jumping into this new updated FPS controller. Jumping, sprinting works fine, but cruching is kinda buggy. Seems like the Foot collision can be a problem? In Your first FPS controller version the crouching works fine, but here the camera moves just a little bit down (this is why I'm thinking the Foot is messing here). Do you have any suggestion please?
Questions I had during watching: How does direction get, which way you're facing? My guess would be, that rotate_y in _input() changes the transform.basis so you can rely on that.
Also wondering: Why did you put the key pressed inputs into _physics? Putting it in _input would seem to be the more obvious place for me, but I guess there's a good reason for this.
Even though the player capsule looks the same from all sides, it has a distinct front and back side. For example, you can think of -transform.basis.z like a little arrow that always points out of the front of the player capsule (-z is forward in Godot). When you rotate the player capsule using rotate_y, transform.basis rotates along with it. Direction just copies the direction of that transform.basis arrow and says "thats the direction we want to move".
As far as the input question, I believe we put the key inputs in physics process because it updates a fixed number of times per second which is important when dealing with thing involving physics (such as moving the player controller) whereas input does not. Not too sure about this one though
@@garbaj Thank you
I found a problem with this engine.
If you are standing underneath a low ceiling and you jump, then you stay stuck to the ceiling for a few seconds instead of bouncing off the ceiling and landing on the ground.
How can this problem be solved?
set the gravity vec to zero if it hits the ceiling using is_on_ceiling()
@@garbaj I wrote this in the physics process function, but if I hit the ceiling now the game crashes and the error says _Invalid get index 'z' (on base: 'int")_. It then says the line that caused this was _movement.z = h_velocity.z + gravity_vec.z_
if is_on_ceiling():
gravity_vec = 0
@@garbaj I've found a solution that seems to work. Like what you said, except setting gravity_vec = -gravity_vec/8
I have tried to optimize the script, I have removed ~20 lines of code:
extends KinematicBody
var speed = 6
var ground_acceleration = 6
var air_acceleration = 1
var acceleration = ground_acceleration
var jump = 4.5
var gravity = 9.8
var mouse_sensitivity = 1
var direction = Vector3()
var velocity = Vector3()
var movement = Vector3()
var gravity_vec = Vector3()
func _input(event):
if event is InputEventMouseMotion:
rotation_degrees.y -= event.relative.x * mouse_sensitivity / 10
$Camera.rotation_degrees.x = clamp($Camera.rotation_degrees.x - event.relative.y * mouse_sensitivity / 10, -90, 90)
direction = Vector3()
direction.z = -Input.get_action_strength("move_forward") + Input.get_action_strength("move_backward")
direction.x = -Input.get_action_strength("move_left") + Input.get_action_strength("move_right")
direction = direction.normalized().rotated(Vector3.UP, rotation.y)
func _physics_process(delta):
if is_on_floor():
gravity_vec = -get_floor_normal()
acceleration = ground_acceleration
if $GroundCheck.is_colliding():
gravity_vec = -get_floor_normal() * gravity
else:
gravity_vec += Vector3.DOWN * gravity * delta
acceleration = air_acceleration
if Input.is_action_just_pressed("jump") and is_on_floor():
gravity_vec = Vector3.UP * jump
velocity = velocity.linear_interpolate(direction * speed, acceleration * delta)
movement.z = velocity.z + gravity_vec.z
movement.x = velocity.x + gravity_vec.x
movement.y = gravity_vec.y
move_and_slide(movement, Vector3.UP)
not too bad
@@garbaj I have improved it by removing the ground check, fixed the falling in a direction and added a snap amount:
extends KinematicBody
var speed = 8
var ground_acceleration = 8
var air_acceleration = 2
var acceleration = ground_acceleration
var jump = 4.5
var gravity = 9.8
var stick_amount = 10
var mouse_sensitivity = 1
var direction = Vector3()
var velocity = Vector3()
var movement = Vector3()
var gravity_vec = Vector3()
var grounded = true
func _input(event):
if event is InputEventMouseMotion:
rotation_degrees.y -= event.relative.x * mouse_sensitivity / 10
$Camera.rotation_degrees.x = clamp($Camera.rotation_degrees.x - event.relative.y * mouse_sensitivity / 10, -90, 90)
direction = Vector3()
direction.z = -Input.get_action_strength("move_forward") + Input.get_action_strength("move_backward")
direction.x = -Input.get_action_strength("move_left") + Input.get_action_strength("move_right")
direction = direction.normalized().rotated(Vector3.UP, rotation.y)
func _physics_process(delta):
if is_on_floor():
gravity_vec = -get_floor_normal() * stick_amount
acceleration = ground_acceleration
grounded = true
else:
if grounded:
gravity_vec = Vector3.ZERO
grounded = false
else:
gravity_vec += Vector3.DOWN * gravity * delta
acceleration = air_acceleration
if Input.is_action_just_pressed("jump") and is_on_floor():
grounded = false
gravity_vec = Vector3.UP * jump
velocity = velocity.linear_interpolate(direction * speed, acceleration * delta)
movement.z = velocity.z + gravity_vec.z
movement.x = velocity.x + gravity_vec.x
movement.y = gravity_vec.y
move_and_slide(movement, Vector3.UP)
i tried this, but i got an error about move and slide not being used. pleas ehelp
@@danylbekhoucha6180 Hi Thanks for the code you provided. I was wondering if a solution to controller moving slower down slopes
@RYAN RIVERA Because $Camera looks for a node called "Camera" on the NewFPS, it doesn't see it though. It should be $Head/Camera or better just $Head instead.
how to do a Strafe and BunnyHop mechanics from CSGO?
appreciate
The beginners tutorial isn’t available. Is there an updated one?
The beginner tutorial link is now broken.
great vid
7:45 for me it seems to work better with:
if not is_on_floor():
gravity_vec += Vector3.DOWN * gravity * delta
elif is_on_floor() and full_contact:
gravity_vec = -get_floor_normal() * gravity
else:
gravity_vec = Vector3.DOWN * gravity * delta
When I do the "else" statement your way and walk over the edge of a ramp my character seems to slightly fall in the "ramp normal" direction.
Yeah, that seems to be an issue with this controller. I think I've found a better way to do this so I'll probably have to remake this video AGAIN lol
@@garbaj It's ok haha! Thanks for these awesome tutorials!
How come when i run the game, the character just falls infinitely?
@@dylanisaiahp make colissions
you can make them by parenting a colision shape to a rigid body with the propper shapes
bro where is your vid about making the map?
Dang, it took me half a day figuring out why my player wouldn't move. Forgot that if I move my fps controller to another project, I have to set the WASD inputs again.
The Godot documentation for InputMap ( docs.godotengine.org/en/stable/classes/class_inputmap.html ) has some functions that can help you assign the actions and keys via script, so you don't have to manually change the mappings for each project.
Specifically, look for add_action() and action_add_event() - don't forget to use has_action() to avoid duplicating action names, and event_is_action() can help you avoid keybinding collisions (eg, you don't want to bind "Space" to both "jump" and "fire"). A good place to add actions/events is in the _ready() function.
Here's an example, adding the "move_forward" action and setting its key to "W":
var key_event = InputEventKey.new()
key_event.scancode = KEY_W
InputMap.add_action("move_forward")
InputMap.action_add_event("move_forward", key_event)
@@TheOriginalTim Thank you so much!!
I have a issue wherever the character controller looked the ground is locked to one direction
this doesn't seem to work if the body is moving very slowly. could you look into how to get characters to move up and down slopes while walking, as well as how to handle slopes meeting a flat surface? i find that my characters get stuck trying to go down slopes where the flat surface meets the slant, no matter how much I try to get the colliders to be pixel perfect
I need to update this video again. I've noticed similar problems
At 2:12, I can't get the game to move when I move my mouse. Please help. I copied what you did correctly.
Same
I got it. Just increase the mouse sensitivity to 0.4 and that works
u are awesome! :D
Hey I'm curious how you feel about other devs using your code in their games? Im a new game dev and I'm not sure what the etiquette is of using tutorial code in your own games? Do you expect people to get a general sense from your code and make something different or do you just not care at all? Thanks :)
The code is open sourced under a MIT license so people are free to do what they want with it unless otherwise specified. Hopefully my tutorials can help people learn gdscript so that one day they don't need to use tutorials to make their games
is there anyway for me to combine the fps controller, crouch, wallrun, sprint, maybe grappling hook in the same thing?
i dont think so since there is no documentation about it
for some reason when applying the first scripts for the camera controls, when moving backwards, my camera goes out of the capsule, dunno why
I need the basic world tutorial, the link in the description doesn't work :(
can you please zoom on the cursor because it's so small and i can't find and read it
So after watching the video and doing everything shown, the code works. However, when running next to a wall with collisionshape, the character gets almost magnetized to the wall, presumably because of the bit where we make gravity perpendicular to the ground your standing on. But then I just copied the code on your github, and this problem was solved. What is the solution to that?
Please help, in the TH-cam version it won't stop jumping. And in the github version nothing renders
7:31
what the point of doing if else when you can just assign it to the value?
m_groundCheck = m_groundCheck.IsColliding()
when i run the game the player falls through the floor. what can i do about that?
Make sure that you are playing the right scene and the floor is a staticbody :)
Hi Garbaj, awesome tutorial. Question for you. My Kinematicbody Mesh is basically invisible, how do I get the white capsule look to show. Even if I click on visibility, it shows a vague grey capsule shape that basically blots out the grey lines
Hmmm, Found the answer. I noticed I did not have the DefaultEnvironment.tres. I tried to set in project settings-Rendering Environment but it would stay even after clicking open. When i Opened it then clicked on the default color above it would finally stay.
I thought this was excellent but have a suggestion. Given that you're covering stuff for beginners (which is great), maybe you should have stopped to take a moment to explain the linear algebra just a tad so they're not just copying your code but understand it a bit more. I liked your solution with gravity on slopes for example, but explaining to a beginner what minusing vectors means would likely have been helpful generally.
Just a suggestion.
I understand what you're saying and I appreciate the feedback. The focus of this channel has always been on quick and concise videos and as such it doesn't exactly cater to beginners since I'm going through a lot of concepts quickly. This probably wont change, but I'm always trying to find a better balance of speed and thoroughness so thanks for the comment
@@garbaj That's absolutely fine. It's hard for me who knows a little bit more than a beginner what they would take away but I felt it was a little strong on the how and a little light on the why.
Like I say, I could well be wrong here.
your gravity 20 feeling better than 10 might be because the physics normalize to 1 unit=1meter and your player is 3m tall