- Edited
So, I'm trying to implement a 6 DOF character controller a la Space Engineers. My problem is 2-fold.
-When rotating the player around the Z(forward) axis any linear movement stays locked to the global XYZ. I'm at a loss on how to fix this issue.
-When switching between XY rotation(mouse) and Z rotation(mapped Input Events), player rotation resets, Although it seems to maintain the previous rotation when switching back. My assumption is that it is obviously due to player.transform.basis = Basis()
however I can't get the rotations to work "correctly" without it.
I have read through the Transform3D Docs etc. but I've obviously missed something or may be approaching this from completely the wrong angle(pun intended).
The only thing in my player script at the moment is variable declarations and move_and_slide()
extends Node
class_name InputManager
@export var player: Player
var mouse_sensitivity = 0.002
var rot_x = 0
var rot_y = 0
var rot_z = 0
var rot_speed = 0.01
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func _process(delta):
var input_dir = Input.get_vector("Strafe Left", "Strafe Right", "Move Forward", "Move Backward")
var direction: Vector3
direction = (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
# If player is not on ground
if Input.is_action_pressed("Jump"):
direction.y = 1
elif Input.is_action_pressed("Crouch"):
direction.y = -1
else: direction.y = 0
if direction:
player.velocity += direction * player.THRUSTER_SPEED
else:
player.velocity.x = move_toward(player.velocity.x, 0, player.THRUSTER_SPEED)
player.velocity.y = move_toward(player.velocity.y, 0, player.THRUSTER_SPEED)
player.velocity.z = move_toward(player.velocity.z, 0, player.THRUSTER_SPEED)
# Rotate player around z axis
if Input.is_action_pressed("Rotate Clockwise"):
rot_z -= rot_speed
player.transform.basis = Basis() # reset rotation
player.rotate_z(rot_z)
elif Input.is_action_pressed("Rotate Counterclockwise"):
rot_z += rot_speed
player.transform.basis = Basis() # reset rotation
player.rotate_object_local(Vector3(0, 0, 1), rot_z)
func _input(event):
if event is InputEventMouseMotion:
# Mouse Look
rot_x += -event.relative.y * mouse_sensitivity # set player x axis rotation amount from mouse y
rot_y += -event.relative.x * mouse_sensitivity # set player y axis rotation amount from mouse x
player.transform.basis = Basis() # reset rotation
player.rotate_y(rot_y) # first rotate in Y
player.rotate_x(rot_x) # then rotate in X
player.rotation.x = clampf(player.rotation.x, -deg_to_rad(70), deg_to_rad(70))