Hello, I’m working on an aircraft system. But I’m struggling to control the aircraft when it’s on ground. I checked all the topics about the centripetal motion but couldn’t find any answer. I also asked chatgpt but still same result.
So when the engines are open the red arrow is the force being applied to front. But when I set rudder to -30 degrees, I want the plane to turn slowly to right.
Can someone help please? This is the code:
local Bindings = {
["ThrottleUp"] = Enum.KeyCode.W,
["ThrottleDown"] = Enum.KeyCode.S,
["Flaps"] = Enum.KeyCode.F
}
local elevatorAddition = -3
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local boost = 0
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local ignore = {"fuselage01","fuselage_wings","wing_support_L01","wing_support_R01","undercarriage02","undercarriage_L01","undercarriage_R01","undercarriage_tail01","TIP","Plane","Holder","prop01","prop02","rudder01"}
local connection, seat
local parts = {}
local hinges = {}
local EnginePower = 300
local throttle = 0
local thrust = 0
local flapStatus = 1
local Flaps = {0,-10,-20,-30}
local AirDensity = 0.01
local Mouse = nil
local function calculateCentripetalForce(velocity, radius)
local speed = velocity.Magnitude
local centripetalForceMagnitude = (speed^2) / radius
return velocity.Unit * centripetalForceMagnitude
end
local function Start()
local model = seat:FindFirstAncestorOfClass("Model")
Mouse = game.Players.LocalPlayer:GetMouse()
for index, descendant in model:GetDescendants() do
if descendant:IsA("BasePart") then
local A0 = Instance.new("Attachment", descendant)
local A1 = Instance.new("Attachment", descendant)
local VectorForce = Instance.new("VectorForce")
VectorForce.Attachment0 = A0
VectorForce.Parent = descendant
local beam = Instance.new("Beam")
beam.Parent = descendant
beam.FaceCamera = true
beam.Segments = 1
beam.Width0 = 0.2
beam.Width1 = 0.2
beam.Color = ColorSequence.new(Color3.fromRGB(64, 245, 169))
beam.Attachment0 = A0
beam.Attachment1 = A1
table.insert(parts, {
Part = descendant,
Attachment0 = A0,
Attachment1 = A1,
Beam = beam,
VectorForce = VectorForce,
AreaX = descendant.Size.Y * descendant.Size.Z,
AreaY = descendant.Size.X * descendant.Size.Z,
AreaZ = descendant.Size.X * descendant.Size.Y
})
elseif descendant.ClassName == "HingeConstraint" then
table.insert(hinges, descendant)
end
end
end
local function Stop()
for index, data in parts do
data.Attachment0:Destroy()
data.Attachment1:Destroy()
data.Beam:Destroy()
end
table.clear(parts)
table.clear(hinges)
end
local function calculateServoAngle(hinge, targetPosition)
local baseAttachment = hinge.Attachment0
local object_horizontal_offset = (baseAttachment.WorldCFrame):PointToObjectSpace(targetPosition)
local object_yaw_angle = math.atan2(object_horizontal_offset.Y, -object_horizontal_offset.Z)
object_yaw_angle = math.deg(object_yaw_angle)
return object_yaw_angle
end
local function Loop(deltaTime)
--[[ BACK-END ]]--
--12500
if UserInputService:IsKeyDown(Bindings.ThrottleUp) then throttle += 50 * deltaTime end
if UserInputService:IsKeyDown(Bindings.ThrottleDown) then throttle -= 50 * deltaTime end
local fixedThrottle = math.round(throttle)
if fixedThrottle > 100 then
fixedThrottle = 100
elseif fixedThrottle < 0 then
fixedThrottle = 0
end
throttle = fixedThrottle
if thrust < throttle * EnginePower then
thrust += EnginePower
elseif thrust > throttle * EnginePower then
thrust -= EnginePower
end
if thrust ~= 0 then
boost += EnginePower / 10
else
boost -= EnginePower / 3
if boost <= 0 then
boost = 0
end
end
--thrust += EnginePower
--[[ FRONT-END ]]--
for index, data in parts do
local velocity = -data.Part:GetVelocityAtPosition(data.Part.Position)
if data.Part.Name == "Motor" then
data.VectorForce.Force = Vector3.new(0,0,-(thrust + boost))
else
data.VectorForce.Force = Vector3.zero
end
if data.Part.Name == "TIP" then
data.Part.Orientation = data.Part.Orientation + Vector3.new(0, 10 * deltaTime, 0) -- Rotate the TIP part for visual effect
end
if table.find(ignore, data.Part.Name) then
else
if velocity.Magnitude > 0 then
local dotRight = data.Part.CFrame.RightVector:Dot(velocity.Unit)
data.VectorForce.Force += Vector3.xAxis * AirDensity * dotRight * data.AreaX * velocity.Magnitude^2
local dotUp = data.Part.CFrame.UpVector:Dot(velocity.Unit)
data.VectorForce.Force += Vector3.yAxis * AirDensity * dotUp * data.AreaY * velocity.Magnitude^2
local dotLook = data.Part.CFrame.LookVector:Dot(velocity.Unit)
data.VectorForce.Force -= Vector3.zAxis * AirDensity * dotLook * data.AreaZ * velocity.Magnitude^2
end
data.Attachment1.Position = data.VectorForce.Force / 400
end
end
for index, hinge in hinges do
hinge.TargetAngle = 0
for index, value in hinge:GetAttributes() do
--[[if hinge:GetAttributes()["Type"] == "Elevator" then
hinge.TargetAngle += -math.clamp(calculateServoAngle(hinge, Mouse.Hit.Position), -20,20)
end]]
if hinge:GetAttributes()["Type"] == "Flap" then
hinge.TargetAngle += Flaps[flapStatus]
end
local SCREEN_WIDTH = game.Workspace.Camera.ViewportSize.X
local SCREEN_LENGTH = game.Workspace.Camera.ViewportSize.Y
local MouseX = UserInputService:GetMouseLocation().X
local MouseY = UserInputService:GetMouseLocation().Y
local normalizedX = (MouseX/SCREEN_WIDTH * 2) - 1
local normalizedY = (MouseY/SCREEN_LENGTH * 2) - 1
if index ~= "Type" then
if hinge:GetAttributes()["Type"] == "Aileron" then
hinge.TargetAngle += (normalizedX * value)
elseif hinge:GetAttributes()["Type"] == "Elevator" then
hinge.TargetAngle += normalizedY * value
hinge.TargetAngle += elevatorAddition
elseif hinge:GetAttributes()["Type"] == "Rudder" then
hinge.TargetAngle += seat["SteerFloat"] * value
end
end
end
--hinge.TargetAngle += -math.clamp(calculateServoAngle(hinge, Mouse.Hit.Position), -20,20)
--[[
for index, value in hinge:GetAttributes() do
hinge.TargetAngle += seat[index] * value
end--]]
end
end
UserInputService.InputBegan:Connect(function(input, gameProc)
if gameProc == false then
if connection ~= nil then
if input.KeyCode == Bindings.Flaps then
if flapStatus == #Flaps then
flapStatus = 1
else
flapStatus += 1
end
end
end
end
end)
local function Seated(active, currentSeat)
if active == false then
if connection == nil then return end
connection:Disconnect()
connection = nil
Stop()
elseif currentSeat.Name == "Plane" then
seat = currentSeat
Start()
connection = RunService.PostSimulation:Connect(Loop)
end
end
humanoid.Seated:Connect(Seated)
Thank you!
