PLEASE READ BEFORE RESPONDING ![]()
Context:
I have created a working helicopter, but I have an issue with the cyclic (the joystick thingy).
The joystick control how the helicopter moves and is implemented through an Angular Velocity. The vertical thrust is implemented through a Vector Force.
Problem:
When the joystick is held forward on a real life helicopter, the helicopter will move forward without falling into a front flip.
My helicopter will fall into a front flip no matter how far the joystick is pushed forward. I want the helicopter to fly normally with the joystick held forward, but then do a front flip if the joystick is pushed too far forward.
I donβt want to use an Align Orientation because it will be impossible for the helicopter to do a front flip.
This is basically what happens:

My code:
-- Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")
local UserInputService = game:GetService("UserInputService")
-- Variables
local localPlayer = game:GetService("Players").LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local heliGui = localPlayer.PlayerGui.HelicopterGui
local camera = workspace.CurrentCamera
local helicopter
local vectorForce
local dragForce
local angularVelocity
local collectivePercentage = 0
local turnForce = 0
local goingUp = false
local goingDown = false
local turningLeft = false
local turningRight = false
-- Controls
-- Main Functions
function inputControl(actionName, inputState, inputObject)
if inputObject.KeyCode == Enum.KeyCode.W then
goingUp = inputState == Enum.UserInputState.Begin
end
if inputObject.KeyCode == Enum.KeyCode.S then
goingDown = inputState == Enum.UserInputState.Begin
end
if inputObject.KeyCode == Enum.KeyCode.A then
turningLeft = inputState == Enum.UserInputState.Begin
end
if inputObject.KeyCode == Enum.KeyCode.D then
turningRight = inputState == Enum.UserInputState.Begin
end
end
function addDrag()
local velocity = helicopter.PrimaryPart.AssemblyLinearVelocity
local speed = velocity.Magnitude
local dragDirection = -velocity.Unit
local dragMagnitude = 6 * (speed ^ 2)
dragForce.Force = dragDirection * dragMagnitude
end
function addCollective()
if goingUp then
collectivePercentage += 1
elseif goingDown then
collectivePercentage -= 1
end
collectivePercentage = math.clamp(collectivePercentage, 0, 100)
local collectiveForce = helicopter.PrimaryPart.AssemblyMass * workspace.Gravity * collectivePercentage / 100 * 1.4
vectorForce.Force = Vector3.new(0, collectiveForce, 0)
heliGui.Collective.Text = collectivePercentage .. "%"
local hinge = helicopter.Rotor.RotorShaft.HingeConstraint
hinge.AngularVelocity = collectivePercentage / 2
end
function addAngular()
local mousePosition = UserInputService:GetMouseLocation()
local mouseX = (mousePosition.X - camera.ViewportSize.X / 2) / camera.ViewportSize.X * 2
local mouseY = -(mousePosition.Y - camera.ViewportSize.Y / 2) / camera.ViewportSize.Y * 2
if turningRight then
turnForce = -50
elseif turningLeft then
turnForce = 50
else
turnForce = 0
end
angularVelocity.AngularVelocity = Vector3.new(-mouseY, turnForce, -mouseX)
heliGui.Cyclic.Text = math.round(mouseX) .. ", " .. math.round(mouseY)
end
-- Connection Event
humanoid.Seated:Connect(function(isSeated, seat)
if isSeated and seat.Name == "VehicleSeat" then
helicopter = seat.Parent
vectorForce = seat.Parent.VectorForce
dragForce = seat.Parent.DragForce
angularVelocity = seat.Parent.AngularVelocity
ContextActionService:BindAction("InputControl", inputControl, true, Enum.KeyCode.W, Enum.KeyCode.S, Enum.KeyCode.A, Enum.KeyCode.D)
else
ContextActionService:UnbindAction("InputControl")
end
end)
RunService.RenderStepped:Connect(function(step)
if vectorForce then
addCollective()
addDrag()
addAngular()
end
end)