Helicopter turning problem (Y axis messed up after changing the X axis)

Hello! I just started working on a helicopter and I ran into a problem, the turning was normal before adding a forward tilt to the helicopter and now it does this:
After Adding the forward tilt:


Before adding the forward tilt:

Here is my code:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local Player:Player = Players.LocalPlayer
local Character = Player.Character

local Helicopter:Model = script.Helicopter.Value
local Primary = Helicopter.PrimaryPart

local LinearVelocity:LinearVelocity = Primary.LinearVelocity
local VectorForce:VectorForce = Primary.VectorForce
local AlignOrientation:AlignOrientation = Primary.AlignOrientation

local ControlModule = require(Player.PlayerScripts.PlayerModule.ControlModule)

local MaxSpeed = 50
local AccelerationSpeed = 2.5
local CurrentSpeed = 0

local function GetMass()
	local TotalMass = 0
	
	for _, v in Helicopter:GetDescendants() do
		if v:IsA("BasePart") then
			TotalMass += v:GetMass()
		end
	end
	for _, v in Character:GetDescendants() do
		if v:IsA("BasePart") then
			TotalMass += v:GetMass()
		end
	end
	
	return TotalMass
end

RunService.RenderStepped:Connect(function(DeltaTime)
	local MoveVector = ControlModule:GetMoveVector()
	VectorForce.Force = Vector3.new(0, workspace.Gravity * GetMass(), 0)

	local SpeedGoal = math.abs(MoveVector.Z) * MaxSpeed
	CurrentSpeed = CurrentSpeed + (SpeedGoal - CurrentSpeed) * math.min(DeltaTime * AccelerationSpeed, 1)
	
	local NormalizedLookVector = Primary.CFrame.LookVector.Unit
	LinearVelocity.VectorVelocity = Vector3.new(NormalizedLookVector.X, 0, NormalizedLookVector.Z) * -(MoveVector.Z * CurrentSpeed)
	
	local AlignOrientationCFrame = AlignOrientation.CFrame * CFrame.Angles(math.rad(10) * -MoveVector.Z, math.rad(-MoveVector.X), 0)
	local X, Y, Z = AlignOrientationCFrame:ToOrientation()
	local ClampedX = math.rad((math.clamp(math.deg(X), -10, 10)))
	
	if MoveVector.Z == 0 then
		ClampedX = 0
	end
	
	AlignOrientation.CFrame = CFrame.Angles(ClampedX, Y, 0)
end)

Primary.CFrame = Primary.CFrame + Vector3.new(0, 10, 0)

Thank you!

1 Like

Correct me if I’m wrong but it looks like the Y axis is rotated along with the AlignOrientation. So when you tilt forward the Y axis points straight up from the tilt as it should

What you actually want to do is rotate around a neutral upwards direction not impacted by the tilt of the helicopter.

I’d probably move the math.rad(-MoveVector.X) portion out of the CFrame.Angles and apply it directly when you set the AlignOrientation’s CFrame to see if that fixes it.

2 Likes

Thank you! I tried what you suggested and it seems to work but it only applies the rotation once (it doesn’t keep on spinning).

RunService.RenderStepped:Connect(function(DeltaTime)
	local MoveVector = ControlModule:GetMoveVector()
	VectorForce.Force = Vector3.new(0, workspace.Gravity * GetMass(), 0)

	local SpeedGoal = math.abs(MoveVector.Z) * MaxSpeed
	CurrentSpeed = CurrentSpeed + (SpeedGoal - CurrentSpeed) * math.min(DeltaTime * AccelerationSpeed, 1)
	
	local NormalizedLookVector = Primary.CFrame.LookVector.Unit
	LinearVelocity.VectorVelocity = Vector3.new(NormalizedLookVector.X, 0, NormalizedLookVector.Z) * -(MoveVector.Z * CurrentSpeed)
	
	local AlignOrientationCFrame = AlignOrientation.CFrame * CFrame.Angles(math.rad(10) * -MoveVector.Z, 0, 0)
	local X, Y, Z = AlignOrientationCFrame:ToOrientation()
	local ClampedX = math.rad((math.clamp(math.deg(X), -10, 10)))
	
	if MoveVector.Z == 0 then
		ClampedX = 0
	end
	
	AlignOrientation.CFrame = CFrame.Angles(ClampedX, 0, 0)
	AlignOrientation.CFrame = AlignOrientation.CFrame * CFrame.Angles(0, math.rad(-MoveVector.X * 10), 0)
end)
1 Like

Hmm a hacky fix I usually use for these issues is just have a variable angleY and do angleY += math.rad(-MoveVector.X * 10) then use angleY instead. Of course make sure the variable is made outside of the RenderStepped event otherwise it will reassign everytime and cause the same issue

1 Like

It seems to fix the problem but now this weird thing happens:

local AngleY = 0
RunService.RenderStepped:Connect(function(DeltaTime)
	local MoveVector = ControlModule:GetMoveVector()
	VectorForce.Force = Vector3.new(0, workspace.Gravity * GetMass(), 0)

	local SpeedGoal = math.abs(MoveVector.Z) * MaxSpeed
	CurrentSpeed = CurrentSpeed + (SpeedGoal - CurrentSpeed) * math.min(DeltaTime * AccelerationSpeed, 1)
	
	local NormalizedLookVector = Primary.CFrame.LookVector.Unit
	LinearVelocity.VectorVelocity = Vector3.new(NormalizedLookVector.X, 0, NormalizedLookVector.Z) * -(MoveVector.Z * CurrentSpeed)
	
	local AlignOrientationCFrame = AlignOrientation.CFrame * CFrame.Angles(math.rad(10) * -MoveVector.Z, 0, 0)
	local X, Y, Z = AlignOrientationCFrame:ToOrientation()
	local ClampedX = math.rad((math.clamp(math.deg(X), -10, 10)))
	
	if MoveVector.Z == 0 then
		ClampedX = 0
	end
	
	AlignOrientation.CFrame = CFrame.Angles(ClampedX, 0, 0)
	AlignOrientation.CFrame = AlignOrientation.CFrame * CFrame.Angles(0, AngleY, 0)
	AngleY += math.rad(-MoveVector.X)
end)
1 Like

Hmm try combining the AlignOrientation.CFrame code at the bottom so it looks like this

AlignOrientation.CFrame = CFrame.Angles(ClampedX, AngleY, 0)
1 Like

I just tried and it does the same thing, is there a way I can “Lock” the Z axis so that it never changes from 0?

SO I think I found a solution. What worked for me in my own little test place was to utilize CFrame.fromAxisAngle which allows us to specify the axis of rotation. So if I am not completely mistaken you should be able to apply this like so

AlignOrientation.CFrame = CFrame.fromAxisAngle(Vector3.new(0, 1, 0), AngleY) * CFrame.Angles(ClampedX, 0, 0)

Docs:
CFrame

1 Like

Thank you so much! It works like a charm!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.