Cannot keep camera from

Godot Version

4.2.2

Question

I am making a fps game and my camera always keeps going angles that are not upright
here’s the code I made:

# Converts mouse movement (pixels) to rotation (radians).
var mouse_sensitivity = 0.002
func _ready():
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _input(event):
	if event.is_action_pressed("ui_cancel"):
		Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
	if event.is_action_pressed("fire"):
		if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE:
			Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _unhandled_input(event):
	if event is InputEventMouseMotion:
		rotate_y(-event.relative.x * mouse_sensitivity)

basically the camera is not staying up-right like all fps games do.

In a first-person shooter (FPS) game, the camera should stay upright to avoid unwanted tilting or rolling. This requires separate handling for yaw (horizontal rotation) and pitch (vertical rotation) to ensure the camera stays aligned with the world’s up axis.

Here’s how you can modify your script to keep the camera upright:

  1. Separate Yaw and Pitch Rotation: Use two separate nodes, one for yaw (horizontal rotation) and one for pitch (vertical rotation).

  2. Limit Pitch Rotation: Constrain the pitch to avoid looking too far up or down, which could lead to unwanted rolling.

Here’s an example implementation:

Scene Setup:

  1. Create a Spatial or Node as the root node.
  2. Add a Spatial or Node for the player body (this will handle yaw).
  3. Add a Camera node (or Camera2D if in 2D) as a child of the player body (this will handle pitch).

Script Example:

Attach this script to the root node:

extends Spatial # or Node if in 2D

@export var mouse_sensitivity: float = 0.002
@onready var player_body = $PlayerBody
@onready var camera = player_body.get_node("Camera") # Adjust the path to your camera node
var pitch: float = 0.0

func _ready():
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _input(event):
	if event.is_action_pressed("ui_cancel"):
		Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
	if event.is_action_pressed("fire"):
		if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE:
			Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		# Yaw rotation (horizontal)
		player_body.rotate_y(-event.relative.x * mouse_sensitivity)

		# Pitch rotation (vertical)
		pitch -= event.relative.y * mouse_sensitivity
		pitch = clamp(pitch, deg2rad(-90), deg2rad(90)) # Limit pitch to avoid unwanted rolling
		camera.rotation.x = pitch

Explanation:

  • Separate Nodes for Yaw and Pitch:

    • player_body handles horizontal rotation (yaw).
    • camera handles vertical rotation (pitch).
  • Yaw Rotation:

    • Applied to player_body using rotate_y.
  • Pitch Rotation:

    • Applied to camera by adjusting its rotation.x.
    • Pitch is clamped to ensure the camera doesn’t rotate too far up or down, maintaining a stable upright orientation.
  • Input Handling:

    • _input(event) handles mouse mode switching.
    • _unhandled_input(event) handles mouse motion for rotating the camera.

By separating yaw and pitch rotation and clamping the pitch, you ensure the camera remains upright, providing a more stable and expected FPS camera behavior.

I inserted it and it gave me this error

Function “deg_2_rad()” not found in base self.

it is called deg_to_rad in Godot 4

2 Likes

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