Tool=script.Parent Handle=Tool:WaitForChild("\072\097\110\100\108\101")Players=game:GetService("\080\108\097\121\101\114\115")Debris=game:GetService("\068\101\098\114\105\115")UserInputService=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")RbxUtility=LoadLibrary("\082\098\120\085\116\105\108\105\116\121")Create=RbxUtility.Create Animations={Sit={Animation=Tool:WaitForChild("\083\105\116"),FadeTime=nil,Weight=nil;Speed=nil;Duration=nil}}AnimationTracks={}Controls={Forward={Down=false;Keys={Key="\119",ByteKey=17}},Backward={Down=false;Keys={Key="\115",ByteKey=18}},Left={Down=false,Keys={Key="\097",ByteKey=20}},Right={Down=false;Keys={Key="\100",ByteKey=19}}}Rate=.016666666666667 Gravity=196.2 Speed={Acceleration=20,Deceleration=20,MovementSpeed={Min=35;Max=35},TurnSpeed={Speed={Min=3;Max=3};TurnAlpha=.5;AlphaDampening=.2},Pitch={Min=40;Max=40}}MaxSpeed={Movement=Speed.MovementSpeed;Turn=Speed.TurnSpeed.Speed;Pitch=Speed.Pitch,Acceleration=Speed.Acceleration,Deceleration=Speed.Deceleration}CurrentSpeed={Movement=0,Turn=0;Pitch=0}ToolEquipped=false function SetAnimation(S,z)if S=="\080\108\097\121\065\110\105\109\097\116\105\111\110"and(z and(ToolEquipped and Humanoid))then for S,m in pairs(AnimationTracks)do if m.Animation==z.Animation then m.AnimationTrack:Stop()table.remove(Animations,S)end end local S=Humanoid:LoadAnimation(z.Animation)table.insert(AnimationTracks,{Animation=z.Animation,AnimationTrack=S})S:Play(z.FadeTime,z.Weight,z.Speed)elseif S=="\083\116\111\112\065\110\105\109\097\116\105\111\110"and z then for S,m in pairs(AnimationTracks)do if m.Animation==z.Animation then m.AnimationTrack:Stop(z.FadeTime)table.remove(Animations,S)end end end end function ThrustUpdater()Humanoid.WalkSpeed=0 Humanoid.AutoRotate=false Humanoid.PlatformStand=true if Controls.Forward.Down then CurrentSpeed.Pitch=math.min(MaxSpeed.Pitch.Max,CurrentSpeed.Pitch+Speed.TurnSpeed.TurnAlpha)end if Controls.Backward.Down then CurrentSpeed.Pitch=math.min(MaxSpeed.Pitch.Min,CurrentSpeed.Pitch-Speed.TurnSpeed.TurnAlpha)end if Controls.Left.Down then CurrentSpeed.Turn=math.min(MaxSpeed.Turn.Min,CurrentSpeed.Turn+Speed.TurnSpeed.TurnAlpha)end if Controls.Right.Down then CurrentSpeed.Turn=math.max(-MaxSpeed.Turn.Max,CurrentSpeed.Turn-Speed.TurnSpeed.TurnAlpha)end if math.abs(CurrentSpeed.Turn)>Speed.TurnSpeed.AlphaDampening then CurrentSpeed.Turn=CurrentSpeed.Turn-Speed.TurnSpeed.AlphaDampening*(math.abs(CurrentSpeed.Turn)/CurrentSpeed.Turn)else CurrentSpeed.Turn=0 end if math.abs(CurrentSpeed.Pitch)>Speed.TurnSpeed.AlphaDampening then CurrentSpeed.Pitch=CurrentSpeed.Pitch-Speed.TurnSpeed.AlphaDampening*(math.abs(CurrentSpeed.Pitch)/CurrentSpeed.Pitch)else CurrentSpeed.Pitch=0 end local S=(-CurrentSpeed.Turn*(math.pi/6))/1.5 local z=Torso.CFrame.lookVector local m=(Vector3.new(z.X,0,z.Z)).Unit ThrustForce.velocity=z*CurrentSpeed.Movement local r=CFrame.Angles(0,math.pi/2,0)*m if math.abs(z.Y)>.85 then RotationForce.angularvelocity=TurnGyro.cframe*Vector3.new(0,CurrentSpeed.Turn,0)CurrentSpeed.Pitch=0 elseif not Controls.Forward.Down and(not Controls.Backward.Down and(not Controls.Left.Down and not Controls.Right.Down))then local S=CurrentSpeed.Pitch+math.sin(tick()*4)*3 RotationForce.angularvelocity=TurnGyro.cframe*Vector3.new(S*r.X,CurrentSpeed.Turn,S*r.Z)else RotationForce.angularvelocity=TurnGyro.cframe*Vector3.new(CurrentSpeed.Pitch*r.X,CurrentSpeed.Turn,CurrentSpeed.Pitch*r.Z)end TurnGyro.cframe=CFrame.Angles(S*m.X,0,S*m.Z)wait(Rate)end function SetUpMovement()for S,z in pairs(CurrentSpeed)do CurrentSpeed[S]=0 end CurrentSpeed.Movement=MaxSpeed.Movement.Max for S,z in pairs(Controls)do z.Down=false end SetAnimation("\080\108\097\121\065\110\105\109\097\116\105\111\110",Animations.Sit)TurnGyro=(Create("\066\111\100\121\071\121\114\111"))({maxTorque=Vector3.new(math.huge,0,math.huge);Parent=Torso})ThrustForce=(Create("\066\111\100\121\086\101\108\111\099\105\116\121"))({maxForce=Vector3.new(math.huge,math.huge,math.huge);velocity=Vector3.new(0,0,0),Parent=Torso})RotationForce=(Create("\066\111\100\121\065\110\103\117\108\097\114\086\101\108\111\099\105\116\121"))({maxTorque=Vector3.new(math.huge,math.huge,math.huge),angularvelocity=Vector3.new(0,0,0),Parent=Torso})Spawn(function()while CheckIfAlive()and(TurnGyro.Parent and(ThrustForce.Parent and(RotationForce.Parent and ToolEquipped)))do ThrustUpdater()wait()end end)end function KeyPress(S,z)local m=string.byte(S)for r,Y in pairs(Controls)do if Y.Keys.Key==S or Y.Keys.ByteKey==m then Y.Down=z end end end function CheckIfAlive()return(Character and(Character.Parent and(Humanoid and(Humanoid.Parent and(Humanoid.Health>0 and(Torso and(Torso.Parent and(Player and Player.Parent))))))))and true or false end function Equipped(S)Character=Tool.Parent Player=Players:GetPlayerFromCharacter(Character)Humanoid=Character:FindFirstChild("\072\117\109\097\110\111\105\100")Torso=Character:FindFirstChild("\084\111\114\115\111")if not CheckIfAlive()then return end ToolEquipped=true S.KeyDown:connect(function(S)KeyPress(S,true)end)S.KeyUp:connect(function(S)KeyPress(S,false)end)Spawn(SetUpMovement)Humanoid:ChangeState(Enum.HumanoidStateType.None)end function Unequipped()for S,z in pairs(Controls)do z.Down=false end for S,z in pairs(AnimationTracks)do if z and z.AnimationTrack then z.AnimationTrack:Stop()end end for S,z in pairs({TurnGyro,ThrustForce;RotationForce})do if tostring(z)=="\067\111\110\110\101\099\116\105\111\110"then z:disconnect()elseif type(z)=="\117\115\101\114\100\097\116\097"and z.Parent then Debris:AddItem(z,0)end end if CheckIfAlive()then Humanoid.WalkSpeed=16 Humanoid.AutoRotate=true Humanoid.PlatformStand=false Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)end AnimationTracks={}ToolEquipped=false end Tool.Equipped:connect(Equipped)Tool.Unequipped:connect(Unequipped)
--Made by Luckymaxer

Tool = script.Parent
Handle = Tool:WaitForChild("Handle")

Players = game:GetService("Players")
Debris = game:GetService("Debris")
UserInputService = game:GetService("UserInputService")

RbxUtility = LoadLibrary("RbxUtility")
Create = RbxUtility.Create

Animations = {
	Sit = { Animation = Tool:WaitForChild("Sit"), FadeTime = nil, Weight = nil, Speed = nil, Duration = nil },
}

AnimationTracks = {}

Controls = {
	Forward = {
		Down = false,
		Keys = { Key = "w", ByteKey = 17 },
	},
	Backward = {
		Down = false,
		Keys = { Key = "s", ByteKey = 18 },
	},
	Left = {
		Down = false,
		Keys = { Key = "a", ByteKey = 20 },
	},
	Right = {
		Down = false,
		Keys = { Key = "d", ByteKey = 19 },
	},
}

Rate = (1 / 60)

Gravity = 196.20

Speed = {
	Acceleration = 20,
	Deceleration = 20,
	MovementSpeed = { Min = 35, Max = 35 },
	TurnSpeed = {
		Speed = { Min = 3, Max = 3 },
		TurnAlpha = 0.5,
		AlphaDampening = 0.2,
	},
	Pitch = { Min = 40, Max = 40 },
}

MaxSpeed = { --Maximum speed which the vehicle can move and turn at.
	Movement = Speed.MovementSpeed,
	Turn = Speed.TurnSpeed.Speed,
	Pitch = Speed.Pitch,
	Acceleration = Speed.Acceleration,
	Deceleration = Speed.Deceleration,
}

CurrentSpeed = { --The speed which the vehicle is moving and turning at.
	Movement = 0,
	Turn = 0,
	Pitch = 0,
}

ToolEquipped = false

function SetAnimation(mode, value)
	if mode == "PlayAnimation" and value and ToolEquipped and Humanoid then
		for i, v in pairs(AnimationTracks) do
			if v.Animation == value.Animation then
				v.AnimationTrack:Stop()
				table.remove(Animations, i)
			end
		end
		local AnimationTrack = Humanoid:LoadAnimation(value.Animation)
		table.insert(AnimationTracks, { Animation = value.Animation, AnimationTrack = AnimationTrack })
		AnimationTrack:Play(value.FadeTime, value.Weight, value.Speed)
	elseif mode == "StopAnimation" and value then
		for i, v in pairs(AnimationTracks) do
			if v.Animation == value.Animation then
				v.AnimationTrack:Stop(value.FadeTime)
				table.remove(Animations, i)
			end
		end
	end
end

function ThrustUpdater()
	Humanoid.WalkSpeed = 0
	Humanoid.AutoRotate = false
	Humanoid.PlatformStand = true

	if Controls.Forward.Down then --Handle acceleration
		CurrentSpeed.Pitch = math.min(MaxSpeed.Pitch.Max, (CurrentSpeed.Pitch + Speed.TurnSpeed.TurnAlpha))
	end
	if Controls.Backward.Down then --Handle deceleration, if speed is more than 0, decrease quicker.
		CurrentSpeed.Pitch = math.min(MaxSpeed.Pitch.Min, (CurrentSpeed.Pitch - Speed.TurnSpeed.TurnAlpha))
	end

	if Controls.Left.Down then --Handle left turn speed
		CurrentSpeed.Turn = math.min(MaxSpeed.Turn.Min, (CurrentSpeed.Turn + Speed.TurnSpeed.TurnAlpha))
	end
	if Controls.Right.Down then --Handle right turn speed
		CurrentSpeed.Turn = math.max(-MaxSpeed.Turn.Max, (CurrentSpeed.Turn - Speed.TurnSpeed.TurnAlpha))
	end
	if math.abs(CurrentSpeed.Turn) > Speed.TurnSpeed.AlphaDampening then
		CurrentSpeed.Turn = (
			CurrentSpeed.Turn - (Speed.TurnSpeed.AlphaDampening * (math.abs(CurrentSpeed.Turn) / CurrentSpeed.Turn))
		)
	else
		CurrentSpeed.Turn = 0
	end
	if math.abs(CurrentSpeed.Pitch) > Speed.TurnSpeed.AlphaDampening then
		CurrentSpeed.Pitch = (
			CurrentSpeed.Pitch - (Speed.TurnSpeed.AlphaDampening * (math.abs(CurrentSpeed.Pitch) / CurrentSpeed.Pitch))
		)
	else
		CurrentSpeed.Pitch = 0
	end
	local LeanAmount = (-CurrentSpeed.Turn * (math.pi / 6) / 1.5)
	local Direction = Torso.CFrame.lookVector
	local XZDirection = Vector3.new(Direction.X, 0, Direction.Z).Unit
	ThrustForce.velocity = (Direction * CurrentSpeed.Movement)
	local XZNormal = (CFrame.Angles(0, (math.pi / 2), 0) * XZDirection)
	if math.abs(Direction.Y) > 0.85 then
		RotationForce.angularvelocity = (TurnGyro.cframe * Vector3.new(0, CurrentSpeed.Turn, 0))
		CurrentSpeed.Pitch = 0
	elseif
		not Controls.Forward.Down
		and not Controls.Backward.Down
		and not Controls.Left.Down
		and not Controls.Right.Down
	then
		local TurnForce = (CurrentSpeed.Pitch + (math.sin(tick() * 4) * 3))
		RotationForce.angularvelocity = (
			TurnGyro.cframe * Vector3.new((TurnForce * XZNormal.X), CurrentSpeed.Turn, (TurnForce * XZNormal.Z))
		)
	else
		RotationForce.angularvelocity = (
			TurnGyro.cframe
			* Vector3.new((CurrentSpeed.Pitch * XZNormal.X), CurrentSpeed.Turn, (CurrentSpeed.Pitch * XZNormal.Z))
		)
	end
	TurnGyro.cframe = CFrame.Angles((LeanAmount * XZDirection.X), 0, (LeanAmount * XZDirection.Z))
	wait(Rate)
end

function SetUpMovement()
	for i, v in pairs(CurrentSpeed) do
		CurrentSpeed[i] = 0
	end
	CurrentSpeed.Movement = MaxSpeed.Movement.Max
	for i, v in pairs(Controls) do
		v.Down = false
	end
	SetAnimation("PlayAnimation", Animations.Sit)
	TurnGyro = Create("BodyGyro")({
		maxTorque = Vector3.new(math.huge, 0, math.huge),
		Parent = Torso,
	})
	ThrustForce = Create("BodyVelocity")({
		maxForce = Vector3.new(math.huge, math.huge, math.huge),
		velocity = Vector3.new(0, 0, 0),
		Parent = Torso,
	})
	RotationForce = Create("BodyAngularVelocity")({
		maxTorque = Vector3.new(math.huge, math.huge, math.huge),
		angularvelocity = Vector3.new(0, 0, 0),
		Parent = Torso,
	})
	Spawn(function()
		while CheckIfAlive() and TurnGyro.Parent and ThrustForce.Parent and RotationForce.Parent and ToolEquipped do
			ThrustUpdater()
			wait()
		end
	end)
end

function KeyPress(Key, Down)
	local ByteKey = string.byte(Key)
	for i, v in pairs(Controls) do
		if v.Keys.Key == Key or v.Keys.ByteKey == ByteKey then
			v.Down = Down
		end
	end
end

function CheckIfAlive()
	return (
		(
			(
				Character
				and Character.Parent
				and Humanoid
				and Humanoid.Parent
				and Humanoid.Health > 0
				and Torso
				and Torso.Parent
				and Player
				and Player.Parent
			) and true
		) or false
	)
end

function Equipped(Mouse)
	Character = Tool.Parent
	Player = Players:GetPlayerFromCharacter(Character)
	Humanoid = Character:FindFirstChild("Humanoid")
	Torso = Character:FindFirstChild("Torso")
	if not CheckIfAlive() then
		return
	end
	ToolEquipped = true
	Mouse.KeyDown:connect(function(Key)
		KeyPress(Key, true)
	end)
	Mouse.KeyUp:connect(function(Key)
		KeyPress(Key, false)
	end)
	Spawn(SetUpMovement)
	Humanoid:ChangeState(Enum.HumanoidStateType.None)
end

function Unequipped()
	for i, v in pairs(Controls) do
		v.Down = false
	end
	for i, v in pairs(AnimationTracks) do
		if v and v.AnimationTrack then
			v.AnimationTrack:Stop()
		end
	end
	for i, v in pairs({ TurnGyro, ThrustForce, RotationForce }) do
		if tostring(v) == "Connection" then
			v:disconnect()
		elseif type(v) == "userdata" and v.Parent then
			Debris:AddItem(v, 0)
		end
	end
	if CheckIfAlive() then
		Humanoid.WalkSpeed = 16
		Humanoid.AutoRotate = true
		Humanoid.PlatformStand = false
		Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
	end
	AnimationTracks = {}
	ToolEquipped = false
end

Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)
