Turn off or instantly change momentum for a plane

I have created a very simple plane using bodyforce to apply an upward lift. That part works perfectly. However, when flying the vehicle can rotate in circle freely because the wings arent pulling forwards. To fix this, I just added a bodythrust and set it to pull forwards. This ALMOST works, and it does pull the vehicle forward, but it also creates a LOT of momentum. So if the plane rotates in mid air, it takes a very long time for it to slow down and go the right direction.

Is there a better way to do what I am doing? is there a way to kill the momentum of a vehicle and force it to go in a set path smoothly?

Play around with the forces on the BodyThrust. You can also apply an impulsive motion to a part to slow it down. BasePart | Roblox Creator Documentation

Do you think grabbing the vehicles direction and speed magnitude, and applying it to the vehicle in a negative value would instantly cancel out the momentum? If so, would immediately applying a different impulse in the direction the wings are facing would create proper wing physics? I’m asking because I don’t know what’s the proper way of making planes with independent wings

I don’t deal with the physics engine like this very often so I’m probably the wrong person to ask. I assume applying an impulse in the opposite direction will change the momentum by that amount. If you apply smaller impulses, it will probably slow down more gradually.

I had an issue like this very recently. I’m not sure if we had the same goal, however. Are you trying to make it to when the plane abruptly stops, a player can get out of their seat and walk about the plane and not get flung halfway across the map?

Like, do you want to cancel the actual part velocities?

No. I simply want to make sure the plane doesn’t spin in mid-air and follow the set direction of the wings

It does not work after testing.

I just want to make sure I got everything right, you want to lock the plane from turning/banking but instead fly straight ahead??

I applied force upwards to float the plane upwards, but thats it. So if the plane spins in mid air, it wont go in any set direction. Thats the problem. If i apply force going forwards, it will take too long to change the momentum and force the wings to glide. I got the lift down correctly, just not the gliding.

To me it sounds like you need to use BodyVelocity instead.

Force is an acceleration. So if you have a constant force your model will be accelerating forever.

The other alternative is to make some drag force. Drag is easy to code.

local DragCoefficient = 1000 -- The coefficient of the drag. The higher = more drag
local function Stepped(runTime,deltaTime)
    Force = BasePart.AssemblyLinearVelocity * -DragCoefficient -- You can apply the force however you like to
end

You will need to find the coefficient for yourself

I have worked with forces a lot and found that using constraints is way better as you can have better customizability.

I agree with this. Try using BodyVelocity in relation to the acceleration.

Sorry for the late response, but I will try that out now

is there any way to apply a drag before the force is applied? also, i added bodyvelocity with body thrust. the thrust applies the 0g upwards, but the bodyvelocity is very violent on how it applies its forces. the entire vehicle would go a single direction forward exponentially. The reason why I dont just hard-program the entire plane as a cframe model is because the plane is completely dynamic along with the wings. if you know how to accomplish the proper wing physics, i made a $150 commission in the hiddendev disc because I just cant seem to figure this out

BodyVelocity and BodyThrust do not work together.

Also,

Drag is a force. And it is proportional to Velocity. Drag only stops a Part from moving. If the part is not moving then there will be no drag force to begin with.

All you have to do is use BodyVelocity or the LinearVelocity constraint by itself for the movement. You can then simply set the Velocity to the forward direction of the plane to make sure it moves forward.

If you want to code proper wing physics I did a small project a couple of months back which uses the drag formula to calculate lift. Here is the code. I’m not going to explain it since I don’t even remember fully what I did.
–asAS
https://gyazo.com/308208bb1d2611561454a53b35fa42f2

THE CODE
BodyGyro.MaxTorque = IDENTITY_VECTOR3
		BodyPosition.MaxForce = IDENTITY_VECTOR3
		AssemblyLinearVelocity = PrimaryPart.AssemblyLinearVelocity
		AssembleLinearVelocityMagnitude = AssemblyLinearVelocity.Magnitude
		if AssembleLinearVelocityMagnitude ~= 0 then
			DotProduct = -PrimaryPart.CFrame.UpVector:Dot(AssemblyLinearVelocity.Unit)
			VectorForce.Force = Vector3new(0,DotProduct * AssemblyLinearVelocity.Magnitude * DRAG_COEFFICIENT * CharacterMass,0)
			AngularVelocity.AngularVelocity = Vector3new(-MoveVector.Z,-MoveVector.X,Rotation) * VindicroyController.RotationSpeed
		end

Ok. While I was testing the body velocity, it didn’t seem to have enough power to lift the plane despite body thrust being able to. I will experiment further with velocity

I tried digesting it here but it may be wrong:

BodyGyro.MaxTorque = IDENTITY_VECTOR3 --unknown what IDENTITY VECTOR3 is
BodyPosition.MaxForce = IDENTITY_VECTOR3
AssemblyLinearVelocity = PrimaryPart.AssemblyLinearVelocity --get Primary part's Linear Assembly Velocity to find speed and direction of part
AssembleLinearVelocityMagnitude = AssemblyLinearVelocity.Magnitude
if AssembleLinearVelocityMagnitude ~= 0 then --check to make sure vehicle is actually moving
	DotProduct = -PrimaryPart.CFrame.UpVector:Dot(AssemblyLinearVelocity.Unit) --Coudn't find documentation on "dot". I imagine this finds the Y axis of the assembly, aka a direction to go to 
	VectorForce.Force = Vector3new(0,DotProduct * AssemblyLinearVelocity.Magnitude * DRAG_COEFFICIENT * CharacterMass,0) --take the direction, apply it to the part after you run it through a drag forumla
	AngularVelocity.AngularVelocity = Vector3new(-MoveVector.Z,-MoveVector.X,Rotation) * VindicroyController.RotationSpeed --gyro?
end

looking at the code, I dont think you actually used Body Velocity. Only VectorForce and Angular Velocity

No this was the code for proper wing physics.

If BodyVelocity doesn’t life the plane you need to increase MaxForce.

1 Like

I am really trying here, but all im gettting is the same problem but different styles of outcomes. either way, the plane is able to spin in circles freely as if 0g. Applying a speed coefficient makes the plane go ludicrous speed

Is it possible if I could see your code?

local Wing = script.Parent:WaitForChild("LargeWing") --The actual wing Part
local FlightAttachment = Wing:WaitForChild("FlightAttachment") --attachment used to get the wing's current position, and offset the Y
local Flight = Wing:WaitForChild("Flight") --A BodyVelocity
local VehicleMass
local Chair = script.Parent.Parent:WaitForChild("Chair"):WaitForChild("Chair")--Master controller for entire vehicle
local Drag = script.Parent:GetAttribute("Drag")--Arbitrary attribute value. currently at 20
local LiftPower = script.Parent:GetAttribute("LiftPower") --Arbitrary attribute value, used to increase the amount of gliding the plane can do. More lift power = less speed plane needs to fly. currently at 1.06
local FlyingModule = require(script.Parent.Parent:WaitForChild("FlyingModule"))
local GlideAttachment = Wing:WaitForChild("GlideAttachment")--Same thing as Flight Attachment, but offsets the Z instead of Y
local Glide = Wing:WaitForChild("Glide")--A BodyVelocity
local function CalculateMassAndWings()
	VehicleMass = FlyingModule.VehicleFlyingStats("Get","Mass")
end
CalculateMassAndWings() --Gets the mass of the vehicle
script.Parent.Parent.ChildAdded:Connect(CalculateMassAndWings)
script.Parent.Parent.ChildRemoved:Connect(CalculateMassAndWings)--If any part of the vehicle breaks off, recalculate mass
function CalculateNumberOfActiveWings()--Calculates the amount of wings that are current applying physics
	local NumberOfActiveWings=0
	local Wings = FlyingModule.VehicleFlyingStats("Get","Wings")
	for x=1,#Wings do
		if Wings[x]:GetAttribute("Active") then
			NumberOfActiveWings=NumberOfActiveWings+1
		end
	end
	return NumberOfActiveWings
end

while script.Parent:GetAttribute("Health")>0 do
	wait()
	local XOri= Wing.Orientation.X--Grabs X and Z orientation, and runs it through logic. The resulting outcome is a percentage of how useful the wing is. The more tilted a wing is, the less efficient it is
	local ZOri=Wing.Orientation.Z
	local ZE,XE=0,0
	if ZOri <=180 and ZOri>=120 then
		ZE=math.abs((ZOri-120)/(180-120))
	elseif ZOri<=60 and ZOri>=0 then
		ZE=math.abs((ZOri-60)/(0-60))
	elseif ZOri>=-60 and ZOri <=-.000003 then
		ZE=math.abs((ZOri-(-60))/(-000003-(-60)))
	elseif ZOri>=-180 and ZOri<=-120 then
		ZE=math.abs((ZOri-(-120))/(-180-(-120)))
	else
		print("Wing is too tilted to fly on z axis: ",ZOri)
	end
	if XOri <=0  and XOri>= -60 then
		XE=math.abs((XOri-(-60))/(0-(-60)))
	elseif XOri>=0 and XOri<=60 then
		XE=math.abs((XOri-60)/(0-60))
	else
		print("Wing is too tilted to fly on the x axis: ",XOri)
	end 
	local WingEfficiency 
	if XE>ZE then --Finally, the lowest value is chosen as the WingEfficiency to be used in the formula
		WingEfficiency=ZE
	else
		WingEfficiency=XE
	end
	local Speed = Chair.Velocity.magnitude
	if WingEfficiency>0 and Speed >= 40 then --If the vehicle is fast enough (40), and the wings aren't at completely terrible angles, apply physics
		script.Parent:SetAttribute("Active",true)--Report the wing to be active
		local NumberOfActiveWings=CalculateNumberOfActiveWings() --Find out how many other wings are also applying physics
		local MaxForce = VehicleMass/NumberOfActiveWings--The maximum force a wing should apply UPWARDS. Too little, the plane will fall out of the sky. too much, and the wings will actually LIFT the plane striaght up
		local Power=(20+(1.1*LiftPower)^(Speed-20))*WingEfficiency--exponential formula that compares speed and wing efficiency. 
		local NewSpeed = -Speed/NumberOfActiveWings--The speed of the vehicle, divided by the amount of wings currently active. Its set negative because this value is what propells the plane forwards, not backwards 
		if NewSpeed<-Drag then --if the value is big enough to handle drag, take drag from value. this is to prevent the vehicle from immediately flying backwards
			NewSpeed=NewSpeed+Drag
		end
		if Power > MaxForce then --the Power cannot exceed MaxForce
			Power=MaxForce
		end
		FlightAttachment.WorldPosition = Vector3.new(Wing.Position.X,Wing.Position.Y+Power,Wing.Position.Z)--Offset the Flight Attachment by itself and the Power. This allows the wings to engage anti-gravity. 
		
		GlideAttachment.Position=Vector3.new(0,0,NewSpeed)--Same thing as Flight Attachment, but instead of Y, its Z. This is to pull the plane forwards and prevent it from spinning aimlessly
		Glide.Velocity = Vector3.new(0,0,GlideAttachment.WorldPosition.Z)--Idk what velocity even means. So I set it to Glide's Z position. Hopefully, the BodyVelocity pulls towards that point constant. (it doesnt.)
		Flight.Velocity= Vector3.new(0,FlightAttachment.WorldPosition.Y,GlideAttachment.WorldPosition.Z)--Pull the plane upwards? Kinda works.
		Glide.MaxForce=Vector3.new(0,0,Power)--Idk whats the real difference between this and P, but P seems to break the universe, so I'll stick with MaxForce
		Flight.MaxForce=Vector3.new(0,Power,Power/NumberOfActiveWings)
	else
		script.Parent:SetAttribute("Active",false)--turn off wing is its too tilted or slow
		Flight.MaxForce = Vector3.new(0,0,0)
		Glide.MaxForce=Vector3.new(0,0,0)
	end
end

I commentated as much as I could so you didn’t have to decipher anything.
The flying upwards part (lift) seems to work fine enough. But if the plane bumps into anything, it spins aimlessly. It basically makes planes drift in mid air. AND, flying straight for too long makes the plane exponentially go faster. I imagine this is because Im pulling the plane forwards by its own speed, which makes it go faster and faster. But idk what would be a proper substitute!