+1 vote

Hi, StrikerSVX again, i need some help to develop some basic aircraft controls, things like pitch, yaw and roll (i really don't know if this terms are correct), i already made simple script but im having problems making the plane behave like a plane would do.

extends KinematicBody

var turn_speed = 30
var speed = 10

var rot_x = 0.0
var rot_y = 0.0
var rot_z = 0.0

func _physics_process(delta):
    get_input(delta)
    rotation_degrees.x = rot_x
    rotation_degrees.y = rot_y
    rotation_degrees.z = rot_z

    $CameraRig.rotation_degrees.z = -rot_z

    move_and_collide(-transform.basis.z * speed * delta)

func get_input(delta):
    if Input.is_action_pressed("W"):
        rot_x += turn_speed * delta
    if Input.is_action_pressed("S"):
        rot_x += -turn_speed * delta
    if Input.is_action_pressed("D"):
        rot_y += -turn_speed * delta
    if Input.is_action_pressed("A"):
        rot_y += turn_speed * delta
    if Input.is_action_pressed("Q"):
        rot_z += turn_speed * delta
    if Input.is_action_pressed("E"):
        rot_z += -turn_speed * delta

the plane is a simple kinematicbody + meshinstance with collisions and a camera inside a spatial node called CameraRig, right now everything the plane do is pitch up and down, roll left and right, turn left and right, but when i roll the plane, the pitch doesn't change and turning left and right doesn't look or fell like a plane, it appears to be something like how to make the rolling change the direction the plane is going to go when you want it to go up or down, but i don't know, if you have something to point me in the right direction i would apreciate, searching for tutorials didn't help in anything because there's almost none in this topic.

asked Mar 5 in Engine by StrikerSVX (69 points)

If you want your plane to have aerodynamics behavior when changing the attitude (pitch, yaw and roll) you need to implement it yourself. If you can't find a tutorial on the topic maybe try to find a tutorial on flying simulation in any other programming language and port it to Godot. That is what I would do. There are probably dozens of articles on the subject with varying level of simulation accuracy.

Also I believe you are not using the right body to to physics, perhaps a rigidbody would be better and apply the lift, drag, thrust and gravity forces according to the attitude you are in.

That's a way of doing it, but im trying to reach something a lot more basic and more arcady, there's already a lot of aircraft simulations. But thanks for your comment, anything to help me create something functional is apreciated.

1 Answer

+2 votes
Best answer

If your "aircraft" is free to turn in each direction then you might not get happy when working with rotation angles. You might run into "gimbal hell"/gimbal lock sooner or later. The right way would be to use transforms for that.

See here about the problem with euler angles:
https://docs.godotengine.org/en/stable/tutorials/3d/using_transforms.html

It might work though if your arcade plane is very limited in motion. I.e. never turns upside down. Doesn't do loops or doesn't roll over 90°.

I have a little spacecraft demo in my physics cheat sheet post which demonstrates at least pitch and roll (didn't implement yaw on that one) using a rigidbody.
https://godotforums.org/discussion/18480/godot-3d-vector-physics-cheat-sheet

enter image description here

Even more on topic:
Also Andrew wilkes did a demo project with an aircraft.
https://godotforums.org/discussion/18480/godot-3d-vector-physics-cheat-sheet

answered Mar 5 by wombatstampede (3,185 points)
selected Jul 18 by StrikerSVX

i remember reading about euler angles and why you shouldn't use it, but what im trying to do doesn't use eulers angles, im just trying to make something like a plane fly, your demos are intersting and the spaceship one is almost what im trying to achieve, thanks for helping anyway, now im going to try making something with all this knowledge.

Well, working on this piece of code i discovered global_rotation on the documentation, here's the new code:

extends KinematicBody

var turn_speed = 1
var speed = 15

func _physics_process(delta):
    if Input.is_action_pressed("W"):
        global_rotate(transform.basis.x, turn_speed * delta)
    if Input.is_action_pressed("S"):
        global_rotate(transform.basis.x, -turn_speed * delta)
    if Input.is_action_pressed("D"):
        global_rotate(transform.basis.y, -turn_speed * delta)
    if Input.is_action_pressed("A"):
        global_rotate(transform.basis.y, turn_speed * delta)
    if Input.is_action_pressed("Q"):
        global_rotate(transform.basis.z, turn_speed * delta)
    if Input.is_action_pressed("E"):
        global_rotate(transform.basis.z, -turn_speed * delta)

    move_and_collide(-global_transform.basis.z * speed * delta)

it functions very close to what i was trying to achieve, but still needs some modification, the plane accelerates on its own, and you can roll the plane and the plane will behave almost like a plane but without gravity.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.