Camera inverting for no reason?

Godot Version:
4.3

Question
I keep getting this issue in Godot where if I look straight up or down then my controls and camera rotations get inverted, I did more testing and what triggers it is going left or right, I tested going up and down multiple times as soon as the game started, and no issues, then I tested with Inputs, crouch nothing, forward/backward nothing, and whenever I went left or right and then looked straight up or down it inverted the controls and camera directions. Any help is appreciate.

Player Code(might be a bit messy I am 1 month in now):

extends CharacterBody3D

signal Health_Changed(health_value)

@export var Walking_Speed := 3.5
@export var Sprinting_Speed := 6.0
@export var Crouching_Speed := 2.0
@export var Mouse_Sens := 0.135

@onready var Neck := $Neck
@onready var Camera := $Neck/Head/Eyes/Camera
@onready var Head := $Neck/Head
@onready var Eyes := $Neck/Head/Eyes
@onready var Standing_CShape := $Standing_Collision_Shape
@onready var Crouching_CShape := $Crouching_Collision_Shape
@onready var Crouching_RayCast := $Crouching_RayCast
@onready var Shoot_RayCast := $Neck/Head/Eyes/Camera/Shoot_RayCast
@onready var Weapons := $Neck/Head/Eyes/Weapons
@onready var Pistol_AC := $Timers/Pistol_Attack_Cooldown

var Direction := Vector3.ZERO
var Slide_Vector := Vector2.ZERO
var Head_Bobbing_Vector := Vector2.ZERO
var mouse_input : Vector2
var Weapon_Holder_Pos : Vector3
var Health := 100
var DMG := 20
var Crouching_Depth := -0.6
var Current_Speed := 3.0
var Jump_Velocity := 4.5
var Lerp_Speed := 10.0
var Air_Lerp_Speed := 3.0
var Slide_Timer := 0.0
var Slide_Timer_Max := 1.0
var Slide_Speed := 11.0
var Slide_Tilt_Amount := 5.0
var Weapon_Sway := 5.0
var Weapon_Rotation := 0.1
var Camera_Rotation := 0.0275
var Head_Bobbing_Sprinting_Speed := 15.0
var Head_Bobbing_Walking_Speed := 11.0
var Head_Bobbing_Crouching_Speed := 7.0
var Head_Bobbing_Sprinting_Intensity := 0.29
var Head_Bobbing_Walking_Intensity := 0.2
var Head_Bobbing_Crouching_Intensity := 0.1
var Head_Bobbing_Current_Intensity := 0.0
var Head_Bobbing_Index := 0.0
var Can_Shoot := true
var Can_WallRun
var isCrouching := false
var isWalking := false
var isSprinting := false
var isSliding := false
var isIdle := false
var isFreeLooking := false
var isWallRunning := false

func _enter_tree() -> void:
	set_multiplayer_authority(str(name).to_int())

func _ready() -> void:
	if not is_multiplayer_authority(): return
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	Camera.current = true

func _unhandled_input(event):
	if not is_multiplayer_authority(): return
	if event is InputEventMouseMotion:
		if isFreeLooking:
			Neck.rotate_y(deg_to_rad(-event.relative.x * Mouse_Sens))
			Neck.rotation.y = clamp(Neck.rotation.y,deg_to_rad(-125),deg_to_rad(125))
		else:
			rotate_y(deg_to_rad(-event.relative.x * Mouse_Sens))
			Head.rotate_x(deg_to_rad(-event.relative.y * Mouse_Sens))
			Head.rotation.x = clamp(Head.rotation.x,deg_to_rad(-89),deg_to_rad(89))
	
	if Input.is_action_just_pressed("Attack"):
		$Sounds/Pistol.play()
		if Shoot_RayCast.is_colliding():
			var Hit_Player = Shoot_RayCast.get_collider()
			Hit_Player.receive_dmg.rpc_id(Hit_Player.get_multiplayer_authority())

func _physics_process(delta) -> void:
	if not is_multiplayer_authority(): return
	var input_dir := Input.get_vector("Move_Left", "Move_Right", "Move_Forward", "Move_Backward")
	if Input.is_action_pressed("Crouch") || isSliding:
		Current_Speed = lerp(Current_Speed,Crouching_Speed,delta*Lerp_Speed)
		Head.position.y = lerp(Head.position.y,Crouching_Depth,delta*Lerp_Speed)
		Standing_CShape.disabled = true
		Crouching_CShape.disabled = false
		
		if isSprinting && input_dir != Vector2.ZERO && is_on_floor():
			isFreeLooking = true
			isSliding = true
			Slide_Timer = Slide_Timer_Max
			Slide_Vector = input_dir
		isCrouching = true
		isWalking = false
		isSprinting = false
		isIdle = false
	elif !Crouching_RayCast.is_colliding():
		Standing_CShape.disabled = false
		Crouching_CShape.disabled = true
		Head.position.y = lerp(Head.position.y,0.0,delta*Lerp_Speed)
		if Input.is_action_pressed("Sprint"):
			if is_on_floor():
				Current_Speed = lerp(Current_Speed,Sprinting_Speed,delta*Lerp_Speed)
				isCrouching = false
				isWalking = false
				isSprinting = true
				isIdle = false
		else:
			Current_Speed = lerp(Current_Speed,Walking_Speed,delta*Lerp_Speed)
			isCrouching = false
			isWalking = true
			isSprinting = false
			isIdle = false
	
	if isSprinting:
		Head_Bobbing_Current_Intensity = Head_Bobbing_Sprinting_Intensity
		Head_Bobbing_Index += Head_Bobbing_Sprinting_Speed * delta
	elif isWalking:
		Head_Bobbing_Current_Intensity = Head_Bobbing_Walking_Intensity
		Head_Bobbing_Index += Head_Bobbing_Walking_Speed * delta
	elif isCrouching:
		Head_Bobbing_Current_Intensity = Head_Bobbing_Crouching_Intensity
		Head_Bobbing_Index += Head_Bobbing_Crouching_Speed * delta
	
	if is_on_floor() && !isSliding && input_dir != Vector2.ZERO:
		Head_Bobbing_Vector.y = sin(Head_Bobbing_Index)
		Head_Bobbing_Vector.x = sin(Head_Bobbing_Index/2) + 0.5
		Eyes.position.y = lerp(Eyes.position.y,Head_Bobbing_Vector.y*(Head_Bobbing_Current_Intensity/2.0),delta*Lerp_Speed)
		Eyes.position.x = lerp(Eyes.position.x,Head_Bobbing_Vector.x*Head_Bobbing_Current_Intensity,delta*Lerp_Speed)
	else:
		Eyes.position.y = lerp(Eyes.position.y,0.0,delta*Lerp_Speed)
		Eyes.position.x = lerp(Eyes.position.x,0.0,delta*Lerp_Speed)
	if not is_on_floor():
		velocity += get_gravity() * delta

	if Input.is_action_just_pressed("Jump") and is_on_floor():
		velocity.y = Jump_Velocity
		isSliding = false
	
	if Input.is_action_pressed("Free_Looking") || isSliding:
		isFreeLooking = true
		if isSliding:
			Camera.rotation.z = lerp(Camera.rotation.z,-deg_to_rad(7.0),delta*Lerp_Speed)
	else:
		isFreeLooking = false
		Neck.rotation.y = lerp(Neck.rotation.y,0.0,delta*Lerp_Speed)
		Camera.rotation.z = lerp(Camera.rotation.z,0.0,delta*Lerp_Speed)
	
	if isSliding:
		Slide_Timer -= delta
		if Slide_Timer <= 0:
			isSliding = false
			isFreeLooking = false
	
	if is_on_floor():
		Direction = lerp(Direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*Lerp_Speed)
	else:
		if input_dir != Vector2.ZERO:
			Direction = lerp(Direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*Air_Lerp_Speed)
	if isSliding:
		Direction = (transform.basis * Vector3(Slide_Vector.x,0,Slide_Vector.y)).normalized()
	
	if Direction:
		velocity.x = Direction.x * Current_Speed
		velocity.z = Direction.z * Current_Speed
		if isSliding:
			velocity.x = Direction.x * (Slide_Timer + 0.1) * Slide_Speed
			velocity.z = Direction.z * (Slide_Timer + 0.1) * Slide_Speed
	else:
		velocity.x = move_toward(velocity.x, 0, Current_Speed)
		velocity.z = move_toward(velocity.z, 0, Current_Speed)

	if !Input.is_anything_pressed():
		isIdle = true
		isCrouching = false
		isWalking = false
		isSprinting = false

	move_and_slide()
	cam_tilt(input_dir.x, delta)
	weapon_tilt(input_dir.x, delta)
	weapon_sway(delta)
	weapon_bob(velocity.length(),delta)

There is more code, but I did not include the func’s that shouldn’t matter.

You didn’t put cam_tilt in the snippets.

I just checked, cam_tilt is the issue but I dont know what part of it, anyway here is the code for it.

func cam_tilt(input_x, delta) -> void:
	if Head:
		Head.rotation.z = lerp(Head.rotation.z, -input_x * Camera_Rotation, 10
* delta)

I found the issue, I had to change Head → Camera.

func cam_tilt(input_x, delta) -> void:
	if Camera:
		Camera.rotation.z = lerp(Camera.rotation.z, -input_x * Camera_Rotation, 10 * delta)

I’ll admit I didn’t read all your code, so this might not be relevant but letting you know just in case.

You might want to use lerp_angle instead of lerp.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.