Hi, I’m trying to make a game in a zero gravity 3d environment, where the character can rotate freely in all directions, (think Outer Wilds, Hard Space: Ship Breaker, Space Engineers, etc); but I’m having trouble with the camera controls. They don’t seem to work properly relative to the current/actual orientation of the camera.
Is anyone able to help me fix this code, or guide me towards the right functions (like maybe I need to try to figure out quaternions? etc.)
func _unhandled_input(event: InputEvent) -> void:
# Mouse capturing
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
capture_mouse()
if Input.is_key_pressed(KEY_ESCAPE):
release_mouse()
if event is InputEventMouseMotion:
rot_x -= event.screen_relative.x * look_speed
rot_y -= event.screen_relative.y * look_speed
if Input.is_action_pressed("move_tilt_left"):
rot_z += tilt_speed
if Input.is_action_pressed("move_tilt_right"):
rot_z -= tilt_speed
transform.basis = Basis()
rotate_object_local(Vector3(0,1,0), rot_x) # first rotate in Y
rotate_object_local(Vector3(1,0,0), rot_y) # then rotate in X
rotate_object_local(Vector3(0,0,1), rot_z) #rotate in Z
This is first person. This is my node structure. This script is attached to the player, and the camera is attached direction on top of the player.
I’ve been trying to mess around with quaternions since it seems to be the elegant (but difficult) solution. I’m not sure if using three nodes with each controlling one axis would solve gimbal lock problems.
Since you’re doing a lot of cumulative rotations, it’d be good idea to orthonormalize the basis to prevent precision errors buildup. As a last line add: