I am currently working on a helicopter. My goal is to make it realistic, and so, I am currently using a vector force to give the helicopter lift. When the player holds W, the vector force is increased (like raising the collective in a helicopter) and inversely for when the player holds S.
Originally, my issue was that when the vector force was applied to my helicopter, it was constantly accelerating, resulting in very high amounts of velocity. To counter this acceleration, I found this post on drag: How do I limit the velocity of VectorForce? - #20 by dthecoolest
After implementing a drag force into my equation for lift, the result I get is unnatural. Although my speed doesn’t increase infinitely, it takes a long time for the speed to stabilize, and it is impossible for the helicopter to be at 0 speed (i.e. hovering).
Here is a video (I am using a platform instead of a helicopter to facilitate the scripting):
Notice how the speed can never reach zero, even when I set the force to be the exact amount required to counter gravity.
Here is an example of what I’m trying to replicate:
As you can see, the speed of the helicopter reaches 0 within a few seconds.
My question is, how can I make my lift feel more realistic? Is a drag force the right way to go, or is there another method? If drag is the right way to go, how can I tweak it so my helicopter can actually enter a hover state?
Here’s my script:
local UIS = game:GetService("UserInputService")
local localPlayer = game.Players.LocalPlayer
local helicopter = script.Parent:FindFirstChild("Helicopter")
local W,S
local increment = 100
UIS.InputBegan:Connect(function(input, gameProcessed)
if input.KeyCode == Enum.KeyCode.W then
W = true
elseif input.KeyCode == Enum.KeyCode.S then
S = true
end
end)
UIS.InputEnded:Connect(function(input, gameProcessed)
if input.KeyCode == Enum.KeyCode.W then
W = false
elseif input.KeyCode == Enum.KeyCode.S then
S = false
end
end)
local liftForce = Instance.new("VectorForce")
local attachment = Instance.new("Attachment", helicopter.PrimaryPart)
liftForce.Name = "LiftForce"
liftForce.Attachment0 = attachment
liftForce.Force = Vector3.new()
liftForce.RelativeTo = Enum.ActuatorRelativeTo.World
liftForce.Parent = helicopter.PrimaryPart
liftForce.ApplyAtCenterOfMass = true
local dragForce = Instance.new("VectorForce")
local attachment2 = Instance.new("Attachment", helicopter.PrimaryPart)
dragForce.Name = "DragForce"
dragForce.Attachment0 = attachment2
dragForce.Force = Vector3.new()
dragForce.RelativeTo = Enum.ActuatorRelativeTo.World
dragForce.Parent = helicopter.PrimaryPart
liftForce.ApplyAtCenterOfMass = true
game:GetService("RunService").Heartbeat:Connect(function()
local velocity = helicopter.PrimaryPart.AssemblyLinearVelocity
local currentLiftForce = liftForce.Force.Y
local forceRequiredtoHover = helicopter.PrimaryPart.AssemblyMass * workspace.Gravity
if W and currentLiftForce < 15000 then
liftForce.Force = Vector3.new(0, currentLiftForce + increment, 0)
end
if S and currentLiftForce > 0 then
liftForce.Force = Vector3.new(0, currentLiftForce - increment, 0)
end
if velocity.Magnitude > 0 then
dragForce.Force = (velocity.Magnitude^2) * -velocity.Unit * Vector3.new(0,1,0)
else
dragForce.Force = Vector3.new()
end
if not W and not S and currentLiftForce < forceRequiredtoHover + 100 and currentLiftForce > forceRequiredtoHover - 100 then
liftForce.Force = Vector3.new(0, forceRequiredtoHover, 0)
end
localPlayer.PlayerGui.ScreenGui:FindFirstChild("Speed indicator").Number.Text = string.format("%.2f", velocity.Magnitude)
localPlayer.PlayerGui.ScreenGui:FindFirstChild("Lift force indicator").Number.Text = currentLiftForce
end)