Rotating an object using "rotate_object_local" does not rotate it in its local axis - Aircraft Controls

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lemosvncs

I’m trying to build an arcade flying game, but I’m having difficulties understanding and applying rotation, when my camera is not static.

Basically, I have a scene composed of:

Kinematic Body

  • MeshInstance
  • CollisionShape
  • Camera

And the following code on the KinematicBody:

extends KinematicBody
var pitch_input:float = 0.0
var roll_input:float = 0.0
var pitch:float = 0.0
var yaw:float = 0.0
var roll:float = 0.0
var _velocity
var Pitch
var Roll

func get_input(_delta):
# pitch, assigned to controler axis or buttons
pitch_input =  Input.get_action_strength("pitch_up") - Input.get_action_strength("pitch_down")

# roll
roll_input = Input.get_action_strength("roll_left") - Input.get_action_strength("roll_right")

func _physics_process(delta: float) -> void:
get_input(delta)

pitch = pitch + pitch_input * .1
roll = roll + roll_input * .1

transform.basis = Basis()
rotate_object_local(Vector3(1,0,0), pitch)
rotate_object_local(Vector3(0,0,1), roll)

transform = transform.orthonormalized()

_velocity = -transform.basis.xform(Vector3(0, 0, 0))
_velocity = move_and_slide(_velocity, Vector3.UP)

I expected that “rotate_object_local” would rotate the object aroung its local x and z axis, as if I was rotating them in the inspector using the local space. But what happes is that the axis are dependent on the pointing direction of the camera.

Its also weird to me that if the camera is static and not a child of the KinematicBody, everything works IF I use:

rotate_object_local(Vector3(1,0,0), pitch)
rotate(Vector3(0,0,1), roll)

I also tryed rotating around the camera basis, but it did not work the way I tried:

rotate_object_local($Camera.transform.basis.z, roll)

I also tried to put things in gimbals, like:

Roll
–Pitch
—KinematicBody
---- …

And rotating the Roll and the Pitch, but results were basically the same.

Also, I can kind of get the result I expect using RigidBody, but all the rest of the things I want to do would be much harder (I think).

If anybody could shed some light, I would really appreciate. Living is easy, 3D math is hard.

:bust_in_silhouette: Reply From: lemosvncs

Answering my own question:
I still don’t know why things are the way they are, but I could get it working removing “transform.basis = Basis()” and “transform = transform.orthonormalized()” and updating the core of the code to something like this:

global_rotate(transform.basis.x.normalized(), rotation_x * delta)
global_rotate(transform.basis.y.normalized(), rotation_y * delta)
global_rotate(transform.basis.z.normalized(), roll* delta)
_velocity = -global_transform.basis.z.normalized() * forward_thrust
_velocity = move_and_slide(_velocity, Vector3.UP)

Basically, I tried to improve on this answer: https://forum.godotengine.org/63203/basic-aircraft-controls

I was having the hardest time figuring this out, thank you for sharing your solution lemosvncs!

ChildLearning.Club | 2022-05-01 23:51