Airplane Turning/Roll Is Glitching [Flight System]

Hello. What I’m trying to make here is a banking(turning) function for my fighter plane.

How the plane is the setup:

Every BasePart in the model is welded using Motor6D’s to a MainBodyPart.
The whole model is unanchored
Parented to the MainBodyPart is:

BodyGyroLooking -

BodyGyroLooking.Parent = BodyKit.CriticalStructure.MainBodyPart
BodyGyroLooking.MaxTorque = Vector3.new(math.huge,math.huge,0)
BodyGyroLooking.CFrame = BodyKit.CriticalStructure.MainBodyPart.CFrame

BodyGyroBank

BodyGyroBank.Parent = BodyKit.CriticalStructure.MainBodyPart
BodyGyroBank.MaxTorque = Vector3.new(0,0,math.huge)
BodyGyroBank.CFrame = BodyKit.CriticalStructure.MainBodyPart.CFrame
BodyGyroBank.P = 6000

BodyVelocity

BodyThrustC.Parent = BodyKit.CriticalStructure.MainBodyPart
BodyThrustC.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
BodyThrustC.Velocity = Vector3.new(0,0,0)

A player sits in the seat and a LocalScript is cloned to the Players PlayerGui which is what is used to control the fighter.

The code that performs the movement and banking [Edited to reflect the changes I’ve made, Original Post Version can be found underneath the code segment]:

RSS.RenderStepped:Connect(function(Delta)
	
	if EngineActive then
		local MainBodyPart = script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart
		local MousePosition = Mouse.Hit.p
		local Size = MainBodyPart.Size
		local Target = MainBodyPart.Position + ((MousePosition - MainBodyPart.Position).Unit * 100) 
		
		local Left = MainBodyPart.CFrame * CFrame.new(-Size.X/2, 0, 0).p
		local Right = MainBodyPart.CFrame * CFrame.new(Size.X/2, 0, 0).p
		
		local CheckVar = (Target - MainBodyPart.Position).Magnitude
		local FCheckVar = MainBodyPart.CFrame * CFrame.new(0, 0, -CheckVar).p
		local RotationalVar = ((FCheckVar - Target).Magnitude / 8)
		
		local LeftPoint = (Target - Left).Magnitude 
		local RightPoint = (Target - Right).Magnitude 
		

		BodyGyroLooking.CFrame = Mouse.Hit
		MainThrust.Velocity = script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.CFrame.LookVector * 100
		
		if LeftPoint < RightPoint and LeftPoint > RotationalVar and LeftPoint < 100 then
			print('Turning/Banking to the left')
			C = CFrame.Angles(0,0,math.rad(RotationalVar * 90))
			BodyGyroBank.CFrame = CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
		elseif LeftPoint > RightPoint and RightPoint > RotationalVar and RightPoint < 100 then
			print('Turning/Banking to the right')
			C = CFrame.Angles(0,0,math.rad(-RotationalVar * 90))
			BodyGyroBank.CFrame = CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
		else
			print('Flying Straight')
			BodyGyroBank.CFrame = MainBodyPart.CFrame * CFrame.Angles(MainBodyPart.Orientation.X,MainBodyPart.Orientation.Y,0)
		end
	end



	---- OLD VERSION ---
	--[[if EngineActive then
		
		BodyGyroLooking.CFrame = Mouse.Hit
		MainThrust.Velocity = script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.CFrame.LookVector * 100
		BodyGyroBank.CFrame = CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
				
	end]]
end)

2 Problems

1st Problem:
The 1st problem is when I go turn in any direction and then move forward in a straight line, the banking doesn’t/takes a very long time to realign itself to a straight position.

Video:

2nd Problem:
The 2nd problem is when I 180 the fighter and start going in the opposite direction. Instead of following the bank, the aircraft in the opposite direction once the turn has been completed
Video:

I can provide more information if necessary.
I would divide up the problems into individual posts, but they are too closely related to each other I believe.

Thanks for any help on how to fix them!

EDIT 1: Using :ToWorldSpace() changes nothing. The same problem is produced.
EDIT 2: Changing the multiplication of the the RotVelocity.Y still produces the same problem, if not a quicker one.
EDIT 3: Using an integer as a replacement for using RotVelocity.Y still brings the same problem when you turn the aircraft in the opposite direction
EDIT 4: I have a feeling it is because of the BodyGyroBank.CFrame is not relative to the part?
EDIT 5: Even when using a different system that uses a set value as the angle, the same problem of the aircraft rolling even when flying straight continues.
EDIT 6: I’ve come to the conclusion that the problem has something to do with the orientation and its relativity to the world instead of the part. Why it continues to rotate I do not know.
EDIT 7: I should have probably mentioned this, but I have a BodyVelocity that moves according to MainBodyPart.LookVector * 100.
EDIT 8: Edited the code to reflect the changes I made.
EDIT 9: Code has changes that determines whenever the aircraft is turning right,left or flying straight.

have you tried using PID?

It basically calculates what force it would do

here is a link to it

1 Like

If I understand it right, you have a large delay between the player rotating the camera and the plane changing the orientation.

This could possibly happen due to network ownership

What you should do to solve this, is set the network owner of the plane, to the player that is riding it, using SetNetworkOwner(player) on each basepart in the plane.

However, I should mention that this would allow exploiters to change the plane’s position to whatever they want, because if a player has network ownership of something, then their client calculates the physics of the part they have the ownership of (This is also the reason why exploiters can change their character’s position). So, you need to make an anti-exploit that will make sure the plane doesn’t change the speed to impossible amounts.

Instead of writing an anti-exploit, you could also try implementing client-side prediction server authoritative model. Though, that would probably be hard to make.

1 Like

Thanks for replying!

The camera is still connected to the humanoid and is offset.
NetworkOwnership of the model is set to the player in a ServerScript.

Thanks for the reply,
I’ll make sure to check it out!

Wasn’t really what I needed. BodyGyro CFrame Rotation is what I need.

The Problem was that the BodyGyroLooking was interfering with the BankGyro. I instead switched it over the BodyGyroLooking and removed the other BodyGyro.

Final Code if anyone has a similar problem in the future:

RSS.RenderStepped:Connect(function(Delta)	
	
	if EngineActive then
		local MainBodyPart = script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart
		local MousePosition = Mouse.Hit.p
		local Size = MainBodyPart.Size
		local Target = MainBodyPart.Position + ((MousePosition - MainBodyPart.Position).Unit * 100) 
		
		local Left = MainBodyPart.CFrame * CFrame.new(-Size.X/2, 0, 0).p
		local Right = MainBodyPart.CFrame * CFrame.new(Size.X/2, 0, 0).p
		
		local CheckVar = (Target - MainBodyPart.Position).Magnitude
		local FCheckVar = MainBodyPart.CFrame * CFrame.new(0, 0, -CheckVar).p
		local RotationalVar = ((FCheckVar - Target).Magnitude / 8)
		
		local LeftPoint = (Target - Left).Magnitude 
		local RightPoint = (Target - Right).Magnitude 
		
		--BodyGyroLooking.CFrame = Mouse.Hit
		MainThrust.Velocity = script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.CFrame.LookVector * ThrustAmount
		
		if LeftPoint < RightPoint and LeftPoint > RotationalVar and LeftPoint < 100 then
			--print('Turning/Banking to the left')
			C = CFrame.Angles(0,0,math.rad(RotationalVar * 90))
			--BodyGyroBank.CFrame = BodyGyroBank.CFrame * CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
			print(RotationalVar)
			BodyGyroLooking.CFrame = Mouse.Hit * CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
			--BodyGyroBank.CFrame = CFrame.Angles(0,0,math.rad(45))
		elseif LeftPoint > RightPoint and RightPoint > RotationalVar and RightPoint < 100 then
			--print('Turning/Banking to the right')
			C = CFrame.Angles(0,0,math.rad(-RotationalVar * 90))
			--BodyGyroBank.CFrame = CFrame.Angles(0,0,math.rad(45))
			--BodyGyroBank.CFrame = BodyGyroBank.CFrame * CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
			BodyGyroLooking.CFrame = Mouse.Hit * CFrame.Angles(0,0,math.rad(script.Engines.Value.Parent.Parent.CriticalStructure.MainBodyPart.RotVelocity.Y * 10))
		else
			--print('Flying Straight')
			BodyGyroLooking.CFrame = Mouse.Hit
			--BodyGyroBank.CFrame = MainBodyPart.CFrame * CFrame.Angles(MainBodyPart.Orientation.X,MainBodyPart.Orientation.Y,0)
		end
	end
end)