Make plane go down slowly depending on speed

So I’m trying to make the plane go down slowly depending on the speed. For example, if the speed is 50, then the plane goes down like -5 velocity or if the speed is 10, it would go down -20.

I tried doing:

if FlyPart.AssemblyLinearVelocity.Magnitude <= 50 then
	FlyPart.AssemblyLinearVelocity = Vector3.new(0, -5, 0)
end

but it would still make it sink into the ground.

Any better ways?

1 Like

Correct me if I’m wrong but I believe the plane is supposed to keep moving forward while it’s going down. My code also decides the vertical velocity based on the horizontal speed, not the whole 3-dimensional speed. Also, instead of directly setting AssemblyLinearVelocity, I recommend using BasePart:ApplyImpulse(). Impulse is the change of momentum. Momentum is mass times velocity. Thus, impulse is mass times velocity change (because mass is constant).

while task.wait() do
	local currentVelocity = FlyPart.AssemblyLinearVelovity
	local horizontalSpeed = Vector2.new(currentVelocity.X, currentVelocity.Z).Magnitude
	local desiredVerticalVelocity = 0
	if horizontalSpeed <= 10 then
		desiredVerticalVelocity = -20
	elseif horizontalSpeed <= 50 then
		desiredVerticalVelocity = -5
	end
	local desiredVerticalVelocityChange = desiredVerticalVelocity - currentVelocity.Y
	FlyPart:ApplyImpulse(part:GetMass() * Vector3.new(0, desiredVerticalVelocityChange, 0))
end

If you want to decide the vertical velocity based on the 3-dimensional speed, use this instead:

while task.wait() do
	local currentVelocity = FlyPart.AssemblyLinearVelovity
	local speed = currentVelocity.Magnitude
	local desiredVerticalVelocity = 0
	if speed <= 10 then
		desiredVerticalVelocity = -20
	elseif speed <= 50 then
		desiredVerticalVelocity = -5
	end
	local desiredVerticalVelocityChange = desiredVerticalVelocity - currentVelocity.Y
	FlyPart:ApplyImpulse(part:GetMass() * Vector3.new(0, desiredVerticalVelocityChange, 0))
end
1 Like

I don’t really understand this code.

Also, my plane just launches up.

RunService.Heartbeat:Connect(function(delta)
	if isOn.Value == true then
		--FlyPart.AssemblyLinearVelocity = FlyPart.CFrame.LookVector * speed.Value
	end
	
	local currentVelocity = FlyPart.AssemblyLinearVelocity
	local speed = currentVelocity.Magnitude
	local desiredVerticalVelocity = 0
	local mass = getModelMass()
	
	if speed <= 10 then
		desiredVerticalVelocity = -20
	elseif speed <= 50 then
		desiredVerticalVelocity = -5
	end
	
	local desiredVerticalVelocityChange = desiredVerticalVelocity - currentVelocity.Y
	FlyPart:ApplyImpulse(mass * Vector3.new(0, desiredVerticalVelocityChange, 0))
end)

I decided to try another approach using a LinearVelocity and an AlignOrientation. Perhaps this code will help, although you’ll have to edit it (you should set speedValueObject, isOn and FlyPart correctly and do some other changes as well).

local RunService = game:GetService("RunService")

local initialOffsetFromGround = 20

local speedValueObject = Instance.new("NumberValue")
speedValueObject.Value = 7

local isOn = Instance.new("BoolValue")
isOn.Value = true

local FlyPart = Instance.new("Part")
FlyPart.Name = "FlyPart"
FlyPart.Size = Vector3.new(7, 5, 10)
FlyPart.Position = workspace.Baseplate.Position + Vector3.new(-10, workspace.Baseplate.Size.y / 2 + FlyPart.Size.Y / 2 + initialOffsetFromGround, 0)
FlyPart.Anchored = true
FlyPart.Parent = workspace

local attachment = Instance.new("Attachment")
attachment.Parent = FlyPart

local alignOrientation = Instance.new("AlignOrientation")
alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
alignOrientation.CFrame = FlyPart.CFrame
alignOrientation.RigidityEnabled = true
alignOrientation.Attachment0 = attachment
alignOrientation.Parent = FlyPart

local linearVelocity = Instance.new("LinearVelocity")
linearVelocity.MaxForce = math.huge
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelocity.Attachment0 = attachment
linearVelocity.Parent = FlyPart

local function getEngineVelocity()
	if isOn.Value == true then
		return FlyPart.CFrame.LookVector * speedValueObject.Value
	end
	return Vector3.new(0, 0, 0)
end

local function getDesiredVelocity()
	local speed = FlyPart.AssemblyLinearVelocity.Magnitude
	
	local desiredVerticalVelocityDifferenceFromEngineVelocity = 0
	if speed <= 10 then
		desiredVerticalVelocityDifferenceFromEngineVelocity = -20
	elseif speed <= 50 then
		desiredVerticalVelocityDifferenceFromEngineVelocity = -5
	end
	local desiredVelocity = getEngineVelocity() + Vector3.new	(0, desiredVerticalVelocityDifferenceFromEngineVelocity, 0)
	return desiredVelocity
end

RunService.Heartbeat:Connect(function(delta)
	if FlyPart.Parent == nil or FlyPart.Anchored then
		return
	end
	FlyPart:SetNetworkOwner(nil)
	local desiredVelocity= getDesiredVelocity()
	linearVelocity.VectorVelocity = desiredVelocity
end)

task.wait(5)
print("starting flight")
FlyPart.Anchored = false

The best option is to use a VectorForce.

This would allow you to add a variable force every frame, so you could update the force every frame depending on the speed of your plane.

More on Vector Forces here.

I have tried that but the plane wouldn’t move.

VectorForce.Force = FlyPart.CFrame.LookVector * speed.Value

I also tried to multiply the mass but that would launch the plane so fast.

VectorForce.Force = mass * FlyPart.CFrame.LookVector * speed.Value

Here is a file so you can see.
Plane Testing.rbxl (93.5 KB)

Controls:

  • F to fly
  • E or Q to speed or slow down
  • WASD to move around

When you replace the code in the script “Handler” with the code below, is the behavior of the plane the behavior you want? This is an edited version of the handler script in the place file.

local plane = script.Parent
local VehicleSeat = plane:WaitForChild("VehicleSeat")
local Base = plane:WaitForChild("Base")
local FlyPart = plane:WaitForChild("FlyPart")
--local VectorForce = FlyPart:WaitForChild("VectorForce")
local AngularVelocity = FlyPart:WaitForChild("AngularVelocity")

local Configurations = plane:WaitForChild("Configurations")
local PropellerMotor = script:WaitForChild("PropellerMotor")

local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local speed = Configurations.Speed
local maxSpeed = Configurations.MaxSpeed
local isOn = Configurations.IsOn

local turnOnPropellerTween
local turnOffPropellerTween
local turnOnTween
local turnOffTween

local function getModelMass()
	local mass = 0
	for i,v in ipairs(plane:GetDescendants()) do
		if v:IsA("BasePart") then
			--mass += v.AssemblyMass
			mass += v:GetMass()
		end
	end
	return mass
end

local function turnOnPropeller()
	local tweenInfo = TweenInfo.new(6, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
	turnOnPropellerTween = TweenService:Create(speed, tweenInfo, {Value = maxSpeed.Value})
	turnOnPropellerTween:Play()
end

local function turnOffPropeller()
	local tweenInfo = TweenInfo.new(6, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
	turnOffPropellerTween = TweenService:Create(speed, tweenInfo, {Value = 0})
	turnOffPropellerTween:Play()
end

local function turnOff()
	local tweenInfo = TweenInfo.new(4, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
	turnOffTween = TweenService:Create(speed, tweenInfo, {Value = 0})
	turnOffTween:Play()
end

local function turnOffAllTweens()
	if turnOffTween then
		turnOffTween:Pause()
		turnOffTween = nil
	end

	if turnOnTween then
		turnOnTween:Pause()
		turnOnTween = nil
	end

	if turnOffPropellerTween then
		turnOffPropellerTween:Pause()
		turnOffPropellerTween = nil
	end

	if turnOnPropellerTween then
		turnOnPropellerTween:Pause()
		turnOnPropellerTween = nil
	end
end

local function getCurrentHorizontalSpeed()
	local currentVelocity = FlyPart.AssemblyLinearVelocity
	local horizontalSpeed = Vector2.new(currentVelocity.X, currentVelocity.Z).Magnitude
	return horizontalSpeed
end

local attachment = Instance.new("Attachment")
attachment.Name = "LinearVelocityAttachment"
attachment.Parent = FlyPart

local linearVelocity = Instance.new("LinearVelocity")
--linearVelocity.MaxForce = getModelMass() * 10
linearVelocity.LineDirection = Vector3.new(0, 1, 0)
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelocity.Attachment0 = attachment
linearVelocity.Parent = FlyPart

local function getEngineVelocity()
	return FlyPart.CFrame.LookVector * speed.Value
end

local function getHorizontalSpeed()
	local velocity = FlyPart.AssemblyLinearVelocity
	return Vector2.new(velocity.X, velocity.Z).Magnitude
end

-- If the check was made using the actual speed of the plane (not just its horizontal speed) then
-- fallVelocity could only briefly be -20 because when vertical velocity is -20, the speed of the plane
-- must be at least 20 which is more than 10.
local function getFallVelocity()
	local horizontalSpeed = getHorizontalSpeed()
	if horizontalSpeed <= 10 then
		return -20
	elseif horizontalSpeed <= 50 then
		return -5
	else
		return 0
	end
end

local function updateLinearVelocity()
	if isOn.Value == true then
		linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
		linearVelocity.VectorVelocity = getEngineVelocity() + Vector3.new(0, getFallVelocity(), 0)
	else
		linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
		linearVelocity.LineDirection = Vector3.new(0, 1, 0)
		linearVelocity.LineVelocity = getFallVelocity()
	end
	linearVelocity.MaxForce = getModelMass() * 1000
end

RunService.Heartbeat:Connect(function(delta)
	--[[
	if isOn.Value == true then
		local mass = getModelMass()
		--print((mass * FlyPart.CFrame.LookVector * speed.Value).Magnitude, (FlyPart.CFrame.LookVector * speed.Value).Magnitude)
		VectorForce.Force = FlyPart.CFrame.LookVector * speed.Value
		
	end
	--]]
	attachment.Position = FlyPart.CFrame:Inverse() * FlyPart.AssemblyCenterOfMass
	updateLinearVelocity()
end)

speed:GetPropertyChangedSignal("Value"):Connect(function()
	PropellerMotor.AngularVelocity = speed.Value
end)

VehicleSeat:GetPropertyChangedSignal("Steer"):Connect(function()
	if isOn.Value == true then
		AngularVelocity.AngularVelocity = Vector3.new(AngularVelocity.AngularVelocity.X, -1 * VehicleSeat.Steer, AngularVelocity.AngularVelocity.Z)
	end
end)

VehicleSeat:GetPropertyChangedSignal("Throttle"):Connect(function()
	if isOn.Value == true then
		AngularVelocity.AngularVelocity = Vector3.new(1 * VehicleSeat.Throttle, AngularVelocity.AngularVelocity.Y, AngularVelocity.AngularVelocity.Z)
	end
end)

script.ChangeSpeed.OnServerEvent:Connect(function(player, text)
	if text == "Add" then
		speed.Value += 1
	elseif text == "Subtract" then
		speed.Value -= 1
	end
end)

script.TurnOn.OnServerEvent:Connect(function(player, bool)
	isOn.Value = bool
	AngularVelocity.Enabled = bool
	
	if bool == false then
		turnOffAllTweens()
		
		turnOff()
		turnOffPropeller()
		
	else
		turnOffAllTweens()
		turnOnPropeller()
	end
end)


if FlyPart.AssemblyLinearVelocity.Magnitude <= 50 then
	FlyPart.AssemblyLinearVelocity = Vector3.new(0, -5, 0)
end
2 Likes

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