Godot Version
4.4.1
Context
I’m playing around with making a flyable helicopter with lift approximations and I have zero background in game-dev or any other 3D environments beyond sometimes trying my hand at Blender.
The following code is an excerpt from my attempt at approximating lift forces for a helicopter. I’ve tried to include only the relevant parts.
class_name Helicopter
extends RigidBody3D
func _ready() -> void:
center_of_mass.x = rotor.position.x
center_of_mass.z = rotor.position.z
func _physics_process(_delta: float) -> void:
# Proportional engine power
var power := engine_rpm / engine_rpm_max
# Apply some lift even when collective is at 0
var lift_coeff = collective / 100 * 0.7 + 0.3
# Approximations
# Lift is force, F = ma => body.mass * g
# Neutral lift (hover): 5600 * 9.8 = 54_880 N
# Lift capacity: Maximum load in kg,
# used to get the maximum amount of lift generated when
# engine is fully powered and collective fully applied
_lift = lift_capacity * 9.8 * power * lift_coeff
var thrust := _lift
var pitch := rotation.z
var roll := rotation.x
# Rotate the thrust vector according to pitch and roll
var tx = -thrust * sin(pitch)
var ty = thrust * cos(roll) * cos(pitch)
var tz = thrust * sin(roll) * cos(pitch)
# Apply the lift generated by the rotor
# Orient the forces to local space and apply lift at the rotor position
apply_force(Vector3(tx, ty, tz) * transform.basis.y, rotor.position)
# Rotation controls
var torque := Vector3.ZERO
if pilot:
var pitch_axis := Input.get_axis("down", "up")
var roll_axis := Input.get_axis("left", "right")
var yaw_axis := Input.get_axis("yaw_left", "yaw_right")
torque.x += roll_axis * 10
torque.y += -yaw_axis * 100
torque.z += -pitch_axis * 50
_rotation = torque * 500
# This does not feel right
apply_torque(_rotation.y * transform.basis.y)
apply_torque(_rotation.x * transform.basis.x)
apply_torque(_rotation.z * transform.basis.z)
Question
My problem currently is the apply_force
function. I’m trying to apply the lift at the rotor, however, as it stands, whenever the helicopter starts moving forward, it starts rolling in just about every direction uncontrollably. At first I thought this might be caused by a misalignment of the center of mass and the upward force, which it partially was, which I remedied in the _ready()
function (I think at least).
In essence I suppose my question is what does “position is the offset from the body origin in global coordinates” mean in practise when trying to apply the force in a local space context?
Also any other tips/suggestions/comments in regards to this are welcome.
I have uploaded everything in this project to a git repository in case there is something I’ve neglected to share here.