The root cause of this problem is this code in game.gd
:
func _ready():
# Hide the cursor without capturing it
Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED_HIDDEN)
By setting the mouse mode to CONFINED_HIDDEN
, you’ve limited the cursor’s range of movement to be within the game window, but most importantly, the cursor is still free to move around within the game window, limited by the window’s border.
To get to the point: the limited rotation you are experiencing is due to the mouse cursor slamming into the left and right borders of the game window, but it’s hard to know this because the cursor has also been hidden.
Here is how to fix this.
First, change the mouse mode to CAPTURED
in game.gd
:
# Called when the node enters the scene tree for the first time.
func _ready():
# Hide the cursor and capture it
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
Judging by the comment that was in the code, setting the mouse mode to CONFINED_HIDDEN
seemed intentional, but I’m not sure why. Generally, for a first-person game, you want to use CAPTURED
instead.
However, when using MOUSE_MODE_CAPTURED
, get_viewport().get_mouse_position()
won’t be useful, since the mouse is pinned to the center of the screen.
So you’ll need to update Character_Controller.gd
accordingly.
Here is how I would rewrite it:
var mouse_delta := Vector2.ZERO
func _ready():
pass
func _physics_process(delta):
mouseMovement()
movement(delta)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
mouse_delta += event.relative
func mouseMovement():
var rotateDelta = Vector2(0, 0)
rotateDelta.y += -mouse_delta.x * sensitivity_x
rotateDelta.x += -mouse_delta.y * sensitivity_y
# Apply rotation to the head
head.rotate_x(rotateDelta.x)
head.rotation.x = clamp(head.rotation.x, -PI / 2, PI / 2) # Clamp X rotation for head
print("Head rotation X: ", head.rotation.x) # Debug statement
# Manually rotate character controller on Y-axis without clamp
rotate_y(rotateDelta.y)
print("Character rotation Y: ", rotation.y) # Debug statement
mouse_delta = Vector2.ZERO
The key here is using _unhandled_input
to get the .relative
mouse motion.