First person camera rotating when I scroll up and down?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By GodotBeginner2023

Here’s the code.

{

class_name Player extends CharacterBody3D

@export_category("Player")

@export_range(0.1, 9.25, 0.05, "or_greater") var camera_sens: float = 3

var mouse_captured: bool = false
var mouse_sensitivity = 0.002

var look_dir: Vector2 # Input direction for look/aim


@onready var camera: Camera3D = $Pivot2/Camera

func _ready() -> void:
	capture_mouse()

func _input(event: InputEvent) -> void:
	if event is InputEventMouseMotion: look_dir = event.relative * 0.01
	if Input.is_action_just_pressed("exit"): get_tree().quit()

func _physics_process(delta: float) -> void:
	if mouse_captured: _rotate_camera(delta)

func capture_mouse() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	mouse_captured = true

func release_mouse() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
	mouse_captured = false

func _rotate_camera(delta: float, sens_mod: float = 1.0) -> void:
	look_dir += Input.get_vector("ui_left","ui_right","ui_up","ui_down")
	camera.rotation.y -= look_dir.x * camera_sens * sens_mod * delta
	camera.rotation.x = clamp(camera.rotation.x - look_dir.y * camera_sens * sens_mod * delta, -1.5, 1.5)
	look_dir = Vector2.ZERO

func _unhandled_input(event):
	if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
		# Get the relative mouse motion in both x and y directions
		var motion = event.relative
		# Calculate the horizontal rotation angle based on the mouse sensitivity
		var rot_y = -motion.x * mouse_sensitivity
		# Rotate the camera around the y-axis (horizontal rotation)
		rotate_y(rot_y)
		# Calculate the vertical rotation angle based on the mouse sensitivity
		var rot_x = -motion.y * mouse_sensitivity
		# Rotate the camera around the x-axis (vertical rotation)
		rotate_x(rot_x)
		# Limit the camera's vertical rotation to a reasonable range of angles
		$Pivot.rotation.x = clamp($Pivot.rotation.x, deg_to_rad(-90), deg_to_rad(90))
		
# accumulators
var rot_x = 0
var rot_y = 0

}

Thanks.

Please use proper formating for your code. It’s really hard to read what’s what

woyosensei | 2023-04-09 11:25

Fixed, I think

GodotBeginner2023 | 2023-04-09 16:22

Not really. Select your code and click {} button on the top panel.
Then you have something like:

func _ready():
      whatever here

woyosensei | 2023-04-09 17:13

Okay, finally properly fixed.

GodotBeginner2023 | 2023-04-09 17:43

:bust_in_silhouette: Reply From: woyosensei

OK, much better. You are in the right direction.
You need to separate event.relative into two axis, x and y, something like this:

func _input(event: InputEvent) -> void:
    if event is InputEventMouseMotion:
        rotate_y(deg2rad(-event.relative.x * mouseSens))
        
        var xDelta = event.relative.y * mouseSens
        if cameraXRot + xDelta > -85 and cameraXRot + xDelta < 85:
            camera.rotate_x(deg2rad(-xDelta))
            cameraXRot += xDelta

Adjust to your needs.
Apologise for bad formating. I’m not on my PC and I copyied it from my discord. You can figure it out.
Basically the way you rotate camera in fps games works like this:
You rotate your character in y axis for moving left and right (x axis for mouse event), but you rotate only camera/pivot which is character’s child when you look up or down (y axis for mouse).