Help making player move based on rotation of a vehicle they are inside of

Godot Version



This is really weird to me. I have a spaceship object. When entering the spaceship, the player’s up-direction (which is used everywhere for the physics), and its rotation is set so that the gravity always faces downwards in relativity of the ship. And when leaving the spaceship, gravity faces downwards in some places, or becomes 0-g on other places. Everything works, except one thing.

When rotating the ship, gravity (including the direction the player falls/jumps) is set correctly. It works exactly as expected. And movement works correctly, assuming I only change a single rotation axis on the ship. So, I can turn the ship upside-down, and I will jump “down” towards the planet, where the top of the ship is. All of that works. So I know the problem which i’m facing has nothing to do with that.

My problem is, whenever I change 2 or 3 rotational values of the ship, and try to walk around, its behaviour is very unexpected. Sometimes it seems to move relative to the planet, and other times it seems to just move in random directions. Here’s the code where I am positive the problem is most likely to be located:

# `direction` is a Vector2 of what direction im moving, where the y axis is
# fowards-backwards, and the x axis is left-right
# `neck` is a Node3D, and always faces in the direction the player is facing.
# Whats going on here is it is rotating the direction to be relative to
# the player's facing direction
var dir := direction.rotated(-neck.rotation.y)

# This is converting the `dir` to a Vector3. The massive line of `rotated`
# functions are applying the player's rotation (which is always equal to
# the ship's rotation) to the velocity. This only appears to work for one
# (and rarely 2) axis at a time. But never 3 axis.
var move_dir := (
        (Vector3.FOWARD * -dir.y),
        (Vector3.RIGHT * dir.x)
    ).rotated(Vector3(1, 0, 0), rotation.x) \
                .rotated(Vector3(0, 1, 0), rotation.y) \
                .rotated(Vector3(0, 0, 1), rotation.z)

velocity += move_dir * current_speed


And to answer some questions I can see coming, so I’ll awnser before you ask them:

  • Is the player a child of the spaceship node: I tried that before, but it didn’t work. No, it is not a child of the spaceship.
  • Do you have unexpeced behaviour anywhere else that may be causing the problem?: Again no, everything works when jumping, falling, or using the jetpack. You always go in the correct direction.
  • Have you lost your freaking mind and can’t comprehend the simplest of things anymore?: Yes, I absolutely have lost my freaking mind. So if it’s a simple 1-liner fix, please don’t blame me.

Please help me with this weird issue, thank you.