Looks like you're not logged in

Login or Register to continue

Lesson Q&A

Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.

  • Crouch bug with jumpingTazerrtotIf you hold the crouch button while landing from a jump the camera returns to the neck's start height, but the collision shape remains smaller. This lets you go under the low ceiling while the camera is still at standing height. I resolved this by adding the same "target_neck_height" code into the landing section like so: ```gdscript var just_landed := was_in_air and is_on_floor() if just_landed: var impact_intensity := fall_speed / max_fall_speed var target_neck_height := 0.0 if Input.is_action_pressed("crouch"): target_neck_height = _neck_crouch_height else: target_neck_height = _neck_start_height var impact_tween := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) impact_tween.tween_property(_neck, "position:y", target_neck_height - 0.2 * impact_intensity, 0.06) impact_tween.tween_property(_neck, "position:y", target_neck_height, 0.1) ``` then also added `set_is_crouching(false)` when jumping so the character wouldn't be crouched in the air. Also changed the jump code so that it would un-crouch while jumping, but not if the ceiling wont let it un-crouch, because that causes the camera to go above the ceiling briefly. ```gdscript if is_on_floor() and Input.is_action_just_pressed("jump"): if is_crouching: _crouch_ceiling_cast.force_shapecast_update() if not _crouch_ceiling_cast.is_colliding(): velocity.y = jump_velocity set_is_crouching(false) else: velocity.y = jump_velocity set_is_crouching(false) ``` Only thing is this also makes the landing while holding crouch look kinda soft even from high heights, which might be fine though. Also, after writing this I went and tried copy/pasting your full code for the lesson just to check if my implementation differed from yours so I had a bug you didn't and noticed some differences between the lesson and the code reference. First is it references an animation player that doesn't exist yet, and second is it added a condition to jumping that wasn't there in the lesson- the reason for the bug I found; the lesson didn't mention not allowing the character to jump while crouched. Was a fun challenge to fix though even if jumping from a crouched position wasn't intended. 3 1 Apr. 11, 2025
  • Cannot un-crouch?KasomotI have an issue with standing back up after pressing crouch. When I press the crouch key every thing works as expected but when I release the key the camera and collision shapes do not return to their original positions. The solution project everything is working, I copied over player.gd to my project and the issue is still there. I'm a little stumped on this one. I used a print directly after is_crouching = new_value on line 182 and it only logs a single true after the first press and no other output regardless of how many times I press the key. 2 0 May. 06, 2025
  • Camera somehow moving up/down when crouchingdim-pantherHey, so i did the shape adjustment task when crouching, and the next one is adjusting the camera when crouching. I have 2 problems now: 1. I can't understand why do we divide the collision shape position like this. **_collision_shape.position.y = _collision_shape.shape.height / 2.0** Can't we always just assign it 1.0 value in local space? If shape height was 3, then it would be 1.5, which doesnt seem right etc. 2. My camera is 'tweening' when coming down, and coming up instantly, but the thing is, i haven't even started the challenge on moving the camera when crouching. Any idea what would force the camera to adjust without any specific camera position updates? My player script below. I even checked reference to camera variable, and all it does is the rotation on mouse/joystick movement. ```gdscript class_name PlayerFPSController extends CharacterBody3D @onready var _neck: Node3D = %Neck @onready var _neck_start_height: float = _neck.position.y var _jump_count := 0 @onready var _collision_shape: CollisionShape3D = %CollisionShape3D @onready var _collision_shape_start_height: float = _collision_shape.shape.height @onready var _crouch_ceiling_cast: ShapeCast3D = %CrouchCeilingCast @export_range(0.001, 1.0) var mouse_sensitivity := 0.005 @export_range(0.001, 1.0) var joystick_sensitivity := 4.0 @export_category("Ground movement") @export_range(1.0, 10.0, 0.1) var max_speed_jog := 4.0 @export_range(1.0, 15.0, 0.1) var max_speed_sprint := 7.0 @export_range(1.0, 100.0, 0.1) var acceleration_jog := 15.0 @export_range(1.0, 100.0, 0.1) var acceleration_sprint := 25.0 @export_range(1.0, 100.0, 0.1) var deceleration := 12.0 @export_category("Air movement") @export_range(1.0, 50.0, 0.1) var gravity := 17.0 @export_range(1.0, 50.0, 0.1) var max_fall_speed := 20.0 @export_range(1.0, 20.0, 0.1) var jump_velocity := 8.0 @export_range(2, 10, 1) var max_jump_count := 2 var is_crouching := false: set = set_is_crouching func set_is_crouching(new_value: bool) -> void: if is_crouching == new_value: return if new_value == false: _crouch_ceiling_cast.force_shapecast_update() if _crouch_ceiling_cast.is_colliding(): return is_crouching = new_value if is_crouching: _collision_shape.shape.height = _collision_shape_start_height / 2.0 else: _collision_shape.shape.height = _collision_shape_start_height _collision_shape.position.y = _collision_shape.shape.height / 2.0 func _unhandled_input(event: InputEvent) -> void: var is_mouse_button := event is InputEventMouseButton var is_mouse_captured := Input.mouse_mode == Input.MOUSE_MODE_CAPTURED var is_escape_pressed := event.is_action_pressed("ui_cancel") if is_mouse_button and not is_mouse_captured: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED elif is_escape_pressed and is_mouse_captured: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE if (event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED): var look_offset_2d: Vector2 = event.screen_relative * mouse_sensitivity _rotate_camera_by(look_offset_2d) @onready var _camera: Camera3D = %Camera3D func _rotate_camera_by(look_offset_2d: Vector2) -> void: _camera.rotation.y -= look_offset_2d.x _camera.rotation.x -= look_offset_2d.y _camera.rotation.y = wrapf(_camera.rotation.y, -PI, PI) const MAX_VERTICAL_ANGLE := PI / 3.0 _camera.rotation.x = clampf(_camera.rotation.x, -1.0 * MAX_VERTICAL_ANGLE, MAX_VERTICAL_ANGLE) _camera.orthonormalize() func _process(delta: float) -> void: var look_vector := Input.get_vector("look_left", "look_right", "look_up", "look_down") _rotate_camera_by(look_vector * joystick_sensitivity * delta) func _physics_process(delta: float) -> void: var input_direction_2d := Input.get_vector("move_left", "move_right", "move_forward", "move_back") var movement_direction_2d := input_direction_2d.rotated(-1.0 * _camera.rotation.y) var movement_direction_3d := Vector3(movement_direction_2d.x, 0.0, movement_direction_2d.y) var player_wants_to_move := movement_direction_2d.length() > 0.1 if player_wants_to_move: var max_speed := max_speed_jog var acceleration := acceleration_jog if Input.is_action_pressed("sprint"): max_speed = max_speed_sprint acceleration = acceleration_sprint var velocity_ground_plane := Vector3(velocity.x, 0.0, velocity.z) var velocity_change := acceleration * delta velocity_ground_plane = velocity_ground_plane.move_toward( movement_direction_3d * max_speed, velocity_change ) velocity.x = velocity_ground_plane.x velocity.z = velocity_ground_plane.z else: var velocity_ground_plane := Vector3(velocity.x, 0.0, velocity.z) velocity_ground_plane = velocity_ground_plane.move_toward(Vector3.ZERO, deceleration * delta) velocity.x = velocity_ground_plane.x velocity.z = velocity_ground_plane.z if is_on_floor(): set_is_crouching(Input.is_action_pressed("crouching")) if not is_on_floor(): velocity.y -= gravity * delta velocity.y = maxf(velocity.y, -max_fall_speed) if is_on_floor() and Input.is_action_just_pressed("jump"): _jump_count = 1 velocity.y = jump_velocity if not is_on_floor() and Input.is_action_just_pressed("jump") and _jump_count < max_jump_count: _jump_count += 1 velocity.y = jump_velocity var was_in_air := not is_on_floor() var fall_speed := absf(velocity.y) move_and_slide() var just_landed := was_in_air and is_on_floor() if just_landed: var impact_intensity := fall_speed / max_fall_speed var impact_tween := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) impact_tween.tween_property(_neck, "position:y", _neck.position.y - 0.2 * impact_intensity, 0.06) impact_tween.tween_property(_neck, "position:y", _neck_start_height, 0.1) ``` 6 0 May. 06, 2025
Site is in BETA!found a bug?