seemsvanjest For yaw, pitch and roll you should rotate around player's current basis axes not around parent's local axes, unless you want some axes to be "absolute"
Or if you keep yaw, pitch and roll in custom properties then when constructing the final basis you need to apply all rotations, always in the same order.
For more specific advice, best to show an example of the kind of movement control you want to implement.

    xyz I figured it was something like that, but haven't been able to figure out how to make it happen. I realise I am probably missing something obvious but it just escapes me.

    xyz The intended movement control is exactly the same as Space Engineers' jetpack control. Jetpack in space.
    The linear motion works exactly as intended, it's just the rotation that's screwy.

    For yaw, pitch and roll you should rotate around player's current basis axes

    This is the bit that's confusing me. My understanding was that rotate_x/y/z did this. Obviously I was wrong...

    • xyz replied to this.

      seemsvanjest Well best to find a video example. You can't expect everyone here played Space Engineers 🙂 The important thing to determine is does it uses full 6 dof or a variant with some limitations.

        seemsvanjest My understanding was that rotate_x/y/z did this.

        rotate_*() rotates around axes of the parent's coordinate system.
        rotate_object_local() rotates around axes specified in object's local coordinate system.

        kuligs2 Current behaviour.
        [
        After any rotation, linear movement remains along global axes.

        • xyz replied to this.

          xyz

          You can't expect everyone here played Space Engineers

          Fair enough.

          rotate_object_local() rotates around axes specified in object's local coordinate system.

          I was originally using rotate_object_local() with the same results. I switched to rotate_* while trying to fix it.

          • xyz replied to this.

            seemsvanjest After any rotation, linear movement remains along global axes.

            Same problem as with rotations. You need to move along player's basis axes, not along parent's x, y, z axes, which your code currently does.

            seemsvanjest Here's a simple example of full 6 dof control:

            extends Node3D
            
            const MOVE_SPEED = 20.0
            const ROTATE_SPEED = PI
            const MOUSE_SENSITIVITY = .04
            
            func _input(e):
            	if e is InputEventMouseMotion:
            		rotate_object_local(Vector3.UP, -e.relative.x * MOUSE_SENSITIVITY) 	# yaw
            		rotate_object_local(Vector3.RIGHT, -e.relative.y * MOUSE_SENSITIVITY) 	# pitch
            
            func _process(dt):
            	rotate_object_local(Vector3.FORWARD, Input.get_axis("roll_ccw", "roll_cw") * ROTATE_SPEED * dt) # roll
            	
            	var vel = Vector3(
            		Input.get_axis("left", "right"), Input.get_axis("up", "down"), Input.get_axis("forward", "back")
            	) * MOVE_SPEED
            	global_position += global_basis * vel * dt

              xyz All working now. It makes a lot more sense after the example. global_basis was the missing piece of the puzzle for me. Thanks again for your patience and taking the time to post the example.