How to make a basic plane, using Roblox physics?

Hello Developers,

How I would able to create a basic plane system, I don’t need any fancy physics, just simple plane system using Roblox physics.

I am currently using BodyGyro and BodyVelocity however they are super unrealistic, they don’t feel like a plane, since they are so sensitive.

Feel free to reply any suggestion, code, idea on how I would able to make simple plane system.

1 Like

There’s two sides to this. You can either go into fancy physics or go with BodyGyro and BodyVelocity. I’m afraid there’s not much of an in between that doesn’t involve aerodynamics and physics.

If you DO want to use BodyGyros and BodyVelocities. You can have the BodyVelocity on both wings and when you turn the plane, turn the BodyGyro and have the Wing thats the highest go forward and the other wing have No force or go Backwards. And the goal velocity should be the Planes lookvector

Edit: Also, what do you mean by “Too Instense”

1 Like

My plane can just stay in air, even tho speed is 0. Also sorry for duplicated post, I didn’t post twice, it something up with forum

1 Like

You need to set MaxForce to 0, 0, 0 since if you set Velocity to 0, 0, 0 it will just stay in the air

Because its trying to keep the Velocity 0, 0, 0

Well then show us the code. We can’t help you with that issue if we have no idea what the code is setting or doing.

--// Services
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

--// Variables
local Plane = workspace:WaitForChild("Plane")
local Throttle = 0
local ThrottleIncrease = false
local ThrottleDecrease = false
local SteerActive = false
local SteerCFrame = workspace.CurrentCamera.CFrame
local inAir = false

--// Mechanisms
Plane.Root.BodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
Plane.Root.BodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if not gameProcessed then
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.W then
				ThrottleIncrease = true
			end
		end
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.S then
				ThrottleDecrease = true
			end
		end
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.E then
				SteerActive = true
			end
		end
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.T then
				if Plane.Settings.LandingGear.Value then
					ReplicatedStorage.PlaneSystem.LandingGear:FireServer(false)
				else
					ReplicatedStorage.PlaneSystem.LandingGear:FireServer(true)
				end
			end
		end
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if not gameProcessed then
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.W then
				ThrottleIncrease = false
			end
		end
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.S then
				ThrottleDecrease = false
			end
		end
		if input.UserInputType == Enum.UserInputType.Keyboard then
			if input.KeyCode == Enum.KeyCode.E then
				SteerActive = false
			end
		end
	end
end)

while wait() do
	if ThrottleIncrease then
		if Throttle <= (Plane.Settings.MaxThrottle.Value - 1) then
			Throttle = Throttle + 1
		end
	end
	if ThrottleDecrease then
		if Throttle >= 1 then
			Throttle = Throttle - 1
		end
	end
	if SteerActive then
		SteerCFrame = workspace.CurrentCamera.CFrame
		Plane.Mechanism.Steers.Left.Part.CylindricalConstraint.LowerAngle = (SteerCFrame.LookVector.X * 100)
		Plane.Mechanism.Steers.Left.Part.CylindricalConstraint.UpperAngle = (SteerCFrame.LookVector.X * 100)
		Plane.Mechanism.Steers.Right.Part.CylindricalConstraint.LowerAngle = (SteerCFrame.LookVector.X * 100)
		Plane.Mechanism.Steers.Right.Part.CylindricalConstraint.UpperAngle = (SteerCFrame.LookVector.X * 100)
	else
		Plane.Mechanism.Steers.Left.Part.CylindricalConstraint.LowerAngle = 0
		Plane.Mechanism.Steers.Left.Part.CylindricalConstraint.UpperAngle = 0
		Plane.Mechanism.Steers.Right.Part.CylindricalConstraint.LowerAngle = 0
		Plane.Mechanism.Steers.Right.Part.CylindricalConstraint.UpperAngle = 0
	end
	if Plane.Root.Velocity.magnitude >= 80 then
		inAir = true
	else
		inAir = false
	end
	if inAir then
		Plane.Root.BodyGyro.CFrame = CFrame.new(SteerCFrame.Position, SteerCFrame.Position + SteerCFrame.LookVector * 20)
	else
		Plane.Root.BodyGyro.CFrame = CFrame.new(SteerCFrame.Position, SteerCFrame.Position + Vector3.new(SteerCFrame.LookVector.X, 0, SteerCFrame.LookVector.Z) * 20)
	end
	Plane.Root.BodyVelocity.Velocity = SteerCFrame.LookVector * Throttle
	Plane.Mechanism.Elevator.Union.CylindricalConstraint.InclinationAngle = -(SteerCFrame.LookVector.Y * 100)
	Plane.Mechanism.Tail.Union.CylindricalConstraint.InclinationAngle = (SteerCFrame.LookVector.X * 50)
	Plane.Mechanism.Propeller.Spinner.CylindricalConstraint.AngularVelocity = math.clamp(Throttle, 0, 125)
	
	-- Steers
	
	Plane.Mechanism.Steers.Left.Part.CylindricalConstraint.InclinationAngle = -(SteerCFrame.LookVector.Y * 100)
	Plane.Mechanism.Steers.Right.Part.CylindricalConstraint.InclinationAngle = -(SteerCFrame.LookVector.Y * 100)
	
	if Plane.PlaneServer.Pilot.Value == nil then
		script:Destroy()
	end
	ReplicatedStorage.PlaneSystem.LocalData:FireServer({
		["Throttle"] = Throttle
	})
end

--[[
	print(math.floor(Plane.Root.Velocity.magnitude))
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		
	end
]]--

Localscript

Oh, uh, I don’t have the time to read through all of that. My apologies. What @LukaDev_0 said might fix the issue though.

Here is a quick view of the basics, rest of the code mostly just moves the constraints.

while wait() do
 SteerCFrame = workspace.CurrentCamera.CFrame
	if ThrottleIncrease then
		if Throttle <= (Plane.Settings.MaxThrottle.Value - 1) then
			Throttle = Throttle + 1
		end
	end
	if ThrottleDecrease then
		if Throttle >= 1 then
			Throttle = Throttle - 1
		end
	end

	Plane.Root.BodyGyro.CFrame = CFrame.new(SteerCFrame.Position, SteerCFrame.Position + SteerCFrame.LookVector * 20)
	Plane.Root.BodyVelocity.Velocity = SteerCFrame.LookVector * Throttle
end
1 Like

A classic (and relatively abrupt) way of solving this is having the velocity cut out when below a certain throttle. What I’d suggest is start scaling the maxforce of the velocity down once you reach this throttle threshold, to smooth it out.

	if Throttle <= 50 then
		Plane.Root.BodyVelocity.Velocity = Vector3.new(0, 0, 0)
		Plane.Root.BodyVelocity.MaxForce = Vector3.new(0, 0, 0)
	else
		Plane.Root.BodyVelocity.Velocity = SteerCFrame.LookVector * Throttle
		Plane.Root.BodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
	end

You mean by that, like this?

1 Like