Just to let you know there's a technical issue with the www version of the website right now, but you should still be able to access it at codewithtom.com. Apologies for the inconvenience and thanks!
Thank you for taking the time at the end of the video to go through almost line by line and recap what the code does and how it affects the project, a lot more presenters could benefit from this, it's very helpful to a novice of programming. Great tutorial, easily one of the best I've seen on RU-vid, especially for Godot.
@@CodeWithTom I 100% agree, I like your summary on everything you have taught during the tutorial. Everything is very well explained, pace is excellent, very much appreciated.
This is the first Godot video which I actually understand - I didn't need to replay anything to understand what was going on, not to mention the fact that you started on a blank project instead of using a premade one. Thanks a lot!
Thanks for the video, got it all down. My only mistake was typing action_just_pressed instead of action_pressed. All in all I really like the pace. You do not go so fast that I have to rewind constantly like other youtuber's tutorials.
hi total novice here but I use the youtube video speed functions for those videos where the passing is to fast or (very rearly) to slow. After I saw a friend doing it I started using the speed options and its been a huge help for me, so just passing the trick on :-)
Thank you, this was very well explained. I was going through FPS character control in Godot documentation, but was not clear on many things. The way you added functionality step by step, explaining at every point what additional lines of code were doing, made it so much easier for me to understand.
Why did everything he explained made sense to me first time. Usually, tutorial videos like this does not make sense to me and I have to re watch to understand. I respect your short on point explanations. No stretching out here.
This tutorial uses the most suitable standard API than I saw in other tutorials, which use a lot of non-standard unnecessary mathematical operations (I would say hacks, for example lerp function on both axis for smooth moving and so on), thanks! P.S. You can use clamp() function to set min and max viewing angle.
I took one cs class in college and I was able to follow your tutorial! I appreciate you talking through your logic so I can more or less understand how the code works.
I was looking for a quick way to understand how the godot engine works by looking at someone code something simple and wow i just loved it! Thanks explaining everything so clearly and easy to understand. Keep it up!
One thing you didn't address here (I don't know yet if you addressed it later), is that *velocity.y* is being reset every frame when you interpolated the vector, and so gravity isn't being accumulated and the player falls like it's on an elevator. I played around with two solutions: *1-* Store *velocity.y* in a throwaway variable right before interpolating the velocity, and then set *velocity.y* to it and apply gravity as normal. Basically this: *var y_speed = velocity.y* *velocity = velocity.linear_interpolate(direction * speed, acceleration * delta)* *velocity.y = y_speed* *velocity.y -= gravity* *2-* Interpolate only the *x* and *z* components of *velocity* with the *lerp()* function. Like this: *velocity.x = lerp(velocity.x, direction.x*speed, acceleration * delta)* *velocity.z = lerp(velocity.z, direction.z*speed, acceleration * delta)* *velocity.y -= gravity*
Thank you! This is easily the most concise, simple, well-coded and easy to follow video of this type I've found on RU-vid. Thank you, thank you, thank you.
If you're having issues spawning the bullet: make sure the Player, Sprite, CollisionShape2D all have their centers aligned aligned! Player's elements can be at the bottom of the screen like in the video, but the Bullet should have everything aligned in the center (0,0)! I had to adjust the position offset a little bit, so my vector ended with position.y - 30 instead of 20, to avoid the Player getting nudged off screen with each bullet spawn. hope this helps someone. also, you can use print(......) to get an idea of what a line of script is doing, it will print it into the console. neat way to learn and find out what you're doing wrong
thank you so much for this tutorial. I was having a really hard time figuring out godot and this helped a ton. super simple instruction, straight to the point and very easy to understand
just started coding with godot and much thanks for this tutorial :) helping me understand it alot better, will continue and let u know how i get on hehe
I think the better way to clamp the x rotation of the camera is by using the clamp function: var cam_x_rot = 0 func _input(event): if (event is InputEventMouseMotion): head.rotate_y(deg2rad(-event.relative.x * mouse_sens)) cam_x_rot += event.relative.y * mouse_sens cam_x_rot = clamp(cam_x_rot, -90, 90) camera.set_rotation_degrees(Vector3(-cam_x_rot, 0, 0))
This is an incredible tutorial. I am just getting into Godot and this is one of the best tutorials I have seen yet. Way too many people assume previous programming knowledge, you explain it very well. I have a game idea that I want to see through as a hobby project. Will certainly be catching up on the rest of your videos.
Great series overall but i have a suggestion on how to handle limiting the player to rotate far beyond 90 degrees, this is what you can do instead of having a global variable: # Rotate the whole player instead of just the head. self.rotate_y(deg2rad(-event.relative.x * mouse_sensitivity)); camera.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity)); # We can make use of the rotation_degrees property and the method clamp var cam_rotation = camera.rotation_degrees; cam_rotation.x = clamp(cam_rotation.x, -90, 90); camera.rotation_degrees = cam_rotation;
@@pierrenagonio Try this but it has an issue with it, it won't let you go far left at all even after you move there. I do have an idea on how to make it work though. Let me know if you would like to know. This is the code that isnt fully working: # Rotate the whole player instead of just the head. self.rotate_y(deg2rad(-event.relative.x * mouse_sensitivity)); camera.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity)); # We can make use of the rotation_degrees property and the method clamp var cam_rotation = camera.rotation_degrees; cam_rotation.x = clamp(cam_rotation.x, -90, 90); camera.rotation_degrees = cam_rotation; # Limit player body y axis rotation var self_rotation = self.rotation_degrees; self_rotation.y = clamp(self_rotation.y, -90, 90); self.rotation_degrees = self_rotation;
@@pierrenagonio I just uploaded this code here, it limits left and right side and it will rotate body to where camera is facing when you move forward. Note that I changed the Player scene's structure. Code and new scene structure here: gist.github.com/ShRyDeR/5db7e72775c4749ffea38ccf159552a2
@@bussin1337 amazing! Thank you very much for this work. I have took one part from your code and luckly is working with my game. Thank you one more time for your time and for sharing your knowledge. I wish I have you in my halp godo desk but I don't want to waste your time. Peace.
I wrote my script to be exactly like yours, but for some reason when I start the game my player always falls through the ground into the void. Can you explain this, please? Edit 1: It turned out my player fell through because I couldn't make the collision shape work without a static body attached to the ground. Thank you for this wonderful tutorial!
@@nuralimedeu when you add child node(Ctrl+A) search for CSG, there you will get csg cube, sphere , capsule similar to the ones in mesh instance. You will find Enable Collision tickbox in property panel
Can not say less than "excellent tutorial". You may want to add as a side note that not normalizing the direction vector would result in the famous strafe running bug/feature which was present in the game "Doom" from 1993.
They should add this basic controller, physics as predefined...like in UE4...you can do all of this in only few clicks and even with much more tunning (acceleration, gravity, air control, movement mode: walking, crouching, flying, swimming etc) and with one click you can replicate all of this for multiplayer
Why use if statement for vertical camera rotation and not just clamp value like this: camera_x_rotation = clamp(camera_x_rotation + x_delta, -90, 90) ???
@@vickylance could just update the actual x rotation. i.e var x_delta = -event.relative.y * mouse_sensitivity; camera.rotation_degrees.x = clamp(x_delta + camera.rotation_degrees.x, -90, 90);
this is really good! you ecplained what the code really does and that makes it easy for beginners! you also did an overview of the code at the end which further explains the code
This was an excellently presented example Tom, however I have one gripe. I added a crosshair to the UI control node, dead center of the screen, and found that small movements with my mouse were not registering as I expected them too. After hunting down a couple of other FPS tuts on Godot, I saw a key difference between those examples and yours - the camera movement occurs in the `_physics_process` listener rather than the `_input` listener. When I moved the camera movement into the physics process and accounted for the time-delta to make the movement FPS independent, I had to raise the mouse_sensitivity to 10, but after that, it worked precisely as I expected it to.
@@CodeWithTom Welcome! Thanks for the intro to 3D. Like I say, it was excellently presented. Also, you gave insight into the library where others did not, and a person with development experience, like myself, will truly appreciate that. Cheers!
half code extends KinematicBody export var speed = 10 export var acceleration = 5 export var gravity = 0.98 export var jump_power = 30 export var mouse_sensitivity = 0.3 onready var head = $Head onready var camera = $Head/Camera var velocity = Vector3() func _input(event): if event is InputEventMouseButton Motion : head.rotate_y(deg2rad(event.relative.x * 0.3 )) func _physics_process(delta): var head_basis = head.get_global_transform().basis var direction = Vector3() if Input.is_action_pressed("move_forward"): direction -= head_basis.z elif Input.is_action_pressed("move_backward"): direction += head_basis.z if Input.is_action_pressed("move_left"): direction -= head_basis.x elif Input.is_action_pressed("move_right"): direction += head_basis.x direction = direction.normalized() velocity = velocity.linear_interpolate(direction * speed, acceleration * delta ) velocity = move_and_slide(velocity)
Getting the basis from the _camera_ instead of the _head_ seems to do half the job of turning your controller into a fly camera, which can be quite useful for debugging (and cheating).
27:50 F5 and F8 start and stop debugging respectively. So if you don't want to bind a key to unlock the cursor, you can just hit F8 to close the window.
Tom what should i do? When i type this script camera.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity)) when i launch the game i does not work plsss help me!!!😫😫😫😫😫
Hello everyone. I was having an issue where my player was falling through the floor. Im not sure if this is due to an update or something. My kinematic body would not detect the collision with the floor, because godot didnt like having a collision shape attached to spaitial or mesh instance. I added a static body inbetween the spaitial and the mesh instance and that fixed the issue
If you treat the ingame units as meters, and size the character and all your game objects accordingly, the variables like speed and acceleration will be in m/s and m/s^2 Currently I have the first person collider at 1.80m tall and 0.50m wide (radius 0.25) and the camera height at 1.65m, which would be eye height. Rotating the camera up and down goes around a RotationHelper (your Head) node, like in the official tutorial, which I have placed 0.15m lower than the camera, at 1.50 m. I think this makes the up and down movement more realistic looking, as you would pivot your head at your neck, not your eyeballs.
Well done Tom! Very clear and to the point. Quick question: Why did you put the movement on the Head node instead of the Player node? Wouldn't that just move the head without the body? regardless, thanks so much for this video and the other FPS tutorials you've made.
Hey thanks for the feedback! That's strange, do you get any more error messages? If you are able to join the discord and share your project files with me I would be happy to take a look
you can also use the $Head object's rotation_degrees.x instead of rotate_x() which forces you to mess with deg2rad(), instead of just using degrees directly. not sure if this is a 3.2.3 specific feature though...
@@CodeWithTom Hi Tom, I just noticed as I am using Godot 3.1 that I have this error code ( The argument 'delta' is never used in the function '_process'. ), is this something with 3.1 as the player will no longer move and I am unsure where things are amiss. Thanks for your reply.
Invalid get index 'relative' (in base: 'InputEventKey'). Can someone help me? when I start the game from the menu it works normally, but the console detects this bug, and when I have run by F5, it just closes by itself after I press any movement key
Hey, I am using 3.2.1, and there are different trimesh collision options, I was wondering what the difference between them was. Godot explains briefly, but I am not too sure about what they mean by "slowest" or "accurate" There's trimesh static body, trimesh collision sibling, and multiple convex collision siblings.
I realize this is a bit late, but I'll try to help anyways. "slowest" and "accuracy" are in terms of physics simulation. Due to computers having finite processing power and memory, we can't simulate physics at 100% accuracy. Thus, there is a tradeoff: You can have really fast physics simulation with less accuracy, or you can have slower physics simulation with more accuracy. If a collider says it's slower or more accurate, that's all it means: It will make the physics simulation take longer, but it will be closer to real life.
I got a problem with the code it had to do with line 16: var direction = Vector3() Does anybody know how to fix it? It says it's an indentation problem, but whoever I tab it again or untab it adds that problem to the next line.
i make 3d fps game for mobile, but i will try to play in mobile , i will touch(swipe) mouse motion only, it will work properly, and i will touch (move) joystick only, then joystick work properly, but i will use both of them, first i will touch mouse motion and after touch joystick, both of them work properly but first i will touch joystick and after touch mouse motion , joystick will work but mouse motion not work, 😢😢how to solve please help
That was great, Watched this pt1 yesterday to get a feel for it, and just gone over it again following along in godot, nice clean code, allowed me to add a double jump, and disable to controls in the game with the mouse capture parts, something that I dont understand, is on the Clamping of the head angle, why not user the clamp function in the engine?
I have a problem. I fall through the floor when I have gravity on so I think it’s something to do with how the player collides with the collision shape
Hah thanks. I'm not focussing on clean code in these tutorials, I could spend hours talking about refactoring but that's not really the primary goal here. But glad you found it to be clean!
I loved the tutorial but I'm using the Godot 3.2.2 and I'm not sure what happend but it told me that an error occurd and my elif statement for the forward and backard if statement was misplaced here are my code lines for reference. if Input.is_action_pressed("move_forward"): direction -= head_basis.z elif Input.is_action_pressed("move_backward"): direction += head_basis.z
Why do you rotate the head when panning the camera left and right but only the camera when panning up and down? The camera is a child of the head so it should always rotate along with it right?
Good question. There are numerous reasons. One being to do with the way 3d rotations work with Euler angles. It would become distorted. The second is due to using the camera z basis for the forward vector for movement. If you rotate the whole head, the forward vector won't be parallel to the ground so you end up with slower movement when looking down.
Take a look at the gifs as you scroll down this page to see the distortion I mention. Of course you can do it differently ,ensuring you rotate on the Y first. But separating the head object rotation has other benefits such as the z basis issue. docs.godotengine.org/en/3.1/tutorials/3d/using_transforms.html
hi Tom. just to let you know, the CollisionShape you set up around 5:50 doesn't really work. the moment you turn on gravity you fall trough your ground. You fixed it yourself here, as you show us also another way to set it up (with a static body). Because you stick to that for the remainder of the course you don't notice, but if you stick with a CollisionShape on a MeshInstance as shown around 5:50 your project goes wrong the moment you turn on gravity.