Helicopter system not flying correctly

I am making a helicopter system, and it’s flying not the right way, let me give you a visual.

Basically my helicopter flies in the exact direction it’s facing, but I wanna add a forward tilt to the helicopter when it’s moving forward:

The issue is when I do fly forward the helicopter flies downwards, due to it facing downwards at the angle. I want it to fly straight the way it’s facing like in the first image shown. I tried so many different things at this point and I’m at my wits end.

Here is the snippet of code that makes the helicopter fly forward in the direction it’s facing.

while seat.Throttle > 0 and wait(0.025) and ignition.Value == true do -- Loop so it happens continuously while the throttle is above 0 (Throttle = 1)
    if Speed < 200 then
        -- Slight increase in speed as the player flies forward
        Speed = Speed + 1
    end
    BP.Position = (script.Parent.CFrame * CFrame.new(0,0,-Speed)).p
    -- BP is a BodyPosition stored in a variable.
    -- Takes the seats' current CFrame and multiplies it by a new CFrame with the Speed as the increment
    -- Basically makes it go forward,  the .p get's the Vector3 in the CFrame
end

The angling is done by the use of a BodyGyro, here is the snippet that makes it tilt forward:

BG.CFrame = script.Parent.CFrame * CFrame.fromEulerAnglesXYZ(-math.rad(5), 0, 0)
-- BG is the variable that references the BodyGyro
-- Makes it tilt 5 radians on the X axis (Forward, relative)

Any help is appreciated, I hope I explained this well enough. I have searched everywhere and can’t find a solution to my specific problem. I prefer something that can be put directly in the script with little to no modifications. You can link any modules that might be of help.

3 Likes

Probably because of the CFrame.new(0,0,-Speed). You are telling the helicopter to go forward, so if it’s turned then it’s logic that it will go forward. CFrame*CFrame will take in count the rotation. So you need to find another function (there is one I forgot it’s name) that dosen’t take in count the rotation

1 Like

Okay so I need it to account for orientation so it flies in the direction it’s facing, I just don’t want it to fly downwards, like in the picture at the top

1 Like

Another way would be to add the „inversed“ rotation
So if Orientation.X = 95, then you just change it to -95

By doing this, the helicopter should go forward too

Some snipped (I didn‘t tried it)

BP.Position = (script.Parent.CFrame * CFrame.new(0,0,-Speed) * CFrame.fromEulerAnglesXYZ(-math.rad(script.Parent.Orientation.X), 0, -math.rad(script.Parent.Orientation.Z))).p

Perhaps this isn’t the most efficient method, but you can weld a part that doesn’t rotate to the helicopter. You can use the welded part for move direction.

Wouldn’t a welded part also rotate anyways? Since it’s welded it would move in relation to the part it’s welded to

Ok, I think I found it:

As mentioned there, it changes the offset (position) but not the rotation. This is maybe better than the other method that I proposed (less calculations = faster script). Sadly, I have to go. Hopefully it‘s what you were searching. I didnt scripted in Roblox for a long time now so I am not sure, but if that‘s not the function you were searching then on this link you can find lots of other functions.

1 Like

If the previous reply isn’t the solution you’re looking for, then one way you could do that in is by also increasing the Y value of the CFrame.new() in this line:

BP.Position = (script.Parent.CFrame * CFrame.new(0,0,-Speed)).p

We’ll replace CFrame.new(0, 0, -Speed) with CFrame.new(0, math.sin(-math.rad(5)) * Speed, -Speed).

If you’re wondering why, read further:

triangle

We won’t be working with the Adjacent in this case. In your issue, the helicopter is moving down on the Hypotenuse only due to its angle, which is the θ. What we’re doing is the following: We’re increasing the Opposite of the triangle by a relative value to the Hypotenuse in the same time it takes the helicopter to reach its destination from the beginning of the Hypotenuse to its end, and we do that each loop.

How do we get that relative value that we increase the Opposite with? There’s a rule which is:

Sin θ = Opposite / Hypotenuse
Then:
Opposite = Sin θ * Hypotenuse

The Hypotenuse is the distance (the Speed here) that the helicopter finishes every loop, so we multiply that by the Sin of the angle and get the value that we use to increase the Opposite (the Y axis).

2 Likes

That sounds good with the whole trygonometry stuff, but the problem is that it‘s always better to avoid them, because they are expensive for the PC. 1 helicopter isn‘t a problem, but lots of helicopters…

Anyways, still seems a good solution

I recommend @dodle120 's solution of using a weld. Kinda like the default roblox character, there’s an invisible root part with the torso attached on top (which can rotate freely). You could make a root part for the helicopter and weld the main helicopter to the root part. That way the root part faces the direction you move in while the helicopter tilts.

Alternatively if your code is in a local script you could

local cam = game.Workspace.CurrentCamera

--Inside loop
BP.Position += (cam.CFrame.lookVector * Vector3.new(1, 0, 1)).unit * Speed

My only issue here is I don’t want players to have full control over every movement. With most helicopter systems the ones you control with the mouse or in this instance the camera, they can do unrealistic maneuvers which kinda takes away from the experience, so I have everything controlled by the keyboard. The turning is done via a BodyGyro

If I understand correctly:

local cam = game.Workspace.CurrentCamera
local UIS = game:GetService("UserInputService")

--Inside Loop
local deltaX = 0
local deltaY = 0

if UIS:IsKeyDown(Enum.KeyCode.D) then
	deltaX += 1
end
if UIS:IsKeyDown(Enum.KeyCode.A) then
	deltaX -= 1
end
if UIS:IsKeyDown(Enum.KeyCode.W) then
	deltaY += 1
end
if UIS:IsKeyDown(Enum.KeyCode.S) then
	deltaY -= 1
end

local forward = (cam.CFrame.LookVector * Vector3.new(1, 0, 1)).unit
local side = (cam.CFrame.RightVector * Vector3.new(1, 0, 1)).unit
local deltaVec = (forward * deltaY) + (side * deltaX)
if deltaVec.magnitude > 0 then
	BP.Position += deltaVec.unit * Speed
end

I believe this should work:

while seat.Throttle > 0 and wait(0.025) and ignition.Value == true do
    if Speed < 200 then
        Speed = Speed + 1
    end
    local parentLookVector = script.Parent.CFrame.LookVector
    BP.Position = script.Parent.CFrame.Position + Vector3.new(parentLookVector.X, 0, parentLookVector.Z)*Speed
end

Unfortunately the helicopter will not move with your code :frowning:

1 Like