How do I make a smooth camera rotation in Godot 4.2.1?

Godot Version

4.2.1

Question

I first defined targetrotation and targetposition

@onready var spring_arm = $SpringArm3D
# Camera smoothing variables
var target_position = Vector3()
var target_rotation = Vector3()
var smoothing_speed = 5.0

func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	target_position = spring_arm.global_transform.origin
	target_rotation = spring_arm.rotation

Then I tried to make the camera turn smoothly

func _unhandled_input(event) -> void:
	if event is InputEventMouseMotion and moving_camera:
		target_rotation.x -= event.relative.y * mouse_sensitivity
		target_rotation.x = clamp(target_rotation.x, deg_to_rad(-90), deg_to_rad(30))
		target_rotation.y -= event.relative.x * mouse_sensitivity

	if event is InputEventJoypadMotion:
		pass

	if event.is_action_pressed("Pause"):
		$PauseMenu.pause()

func smooth_camera(delta):
	var target_rot_quat = Quaternion().from_euler(target_rotation)
	spring_arm.global_transform.origin = spring_arm.global_transform.origin.lerp(global_transform.origin, smoothing_speed * delta) + Vector3(0,.15,0)
	spring_arm.rotation = spring_arm.rotation.slerp(target_rot_quat, smoothing_speed * delta)
	print(spring_arm.rotation.y)

However, this line causes me all the issue

spring_arm.rotation = spring_arm.rotation.slerp(target_rot_quat, smoothing_speed * delta)

Slerp doesn’t take in quaternions but I really need something to rotate around a circle without spinning out of control once rotation reaches past pi,

spring_arm.rotation = spring_arm.rotation.lerp(target_rotation, smoothing_speed * delta)

This is an older version of this line, when i rotate too much the camera spins out of control, which is why I wanted to use the quaternion, if I didn’t want camera smoothness I could;ve settled for just:

spring_arm.rotation = target_rotation

so can you help me find a way to make smooth camera movement in godot 4.2.1? A lot of resources are from older versions

I think the problem you’re facing is a matter of forcing the use of quaternions.

As other people, I usually recommend using quaternions whenever working with rotations. However, in your specific case you’re dealing with an object whose z-rotation is irrelevant. Therefore, quaternions are not the simplest way to achieve your desired result. Interpolating between quaternions will inevitably produce z-rotation here which is undesired.

In this case, use euler angles (i.e. 3D vectors) to represent your rotation.

var target_rotation: Vector3
var smooth_rotation: Vector3
var mouse_sensitivity = 0.01

func _ready():
	# Lock the mouse to the window center
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _process(delta):
	# Integrate the smooth rotation based on the target rotation
	# ...and a "smoothing factor" of 10
	smooth_rotation = smooth_rotation.lerp(target_rotation, delta * 10)
	rotation = smooth_rotation

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		target_rotation.x -= event.relative.y * mouse_sensitivity
		target_rotation.x = clamp(target_rotation.x, deg_to_rad(-80), deg_to_rad(50))
		target_rotation.y -= event.relative.x * mouse_sensitivity

Seeing as you’re a beginner, I would recommend that you take a look at the official Godot Docs’ GDScript Manual. There you’ll find most, if not everything, you need to become a competent GDScript user.

EulerAngles work really well for this exact purpose!? I finally have a working smooth camera

1 Like

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