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(V,A)if V=="\080\108\097\121\065\110\105\109\097\116\105\111\110"and(A and(ToolEquipped and Humanoid))then for V,T in pairs(AnimationTracks)do if T.Animation==A.Animation then T.AnimationTrack:Stop()table.remove(Animations,V)end end local V=Humanoid:LoadAnimation(A.Animation)table.insert(AnimationTracks,{Animation=A.Animation;AnimationTrack=V})V:Play(A.FadeTime,A.Weight,A.Speed)elseif V=="\083\116\111\112\065\110\105\109\097\116\105\111\110"and A then for V,T in pairs(AnimationTracks)do if T.Animation==A.Animation then T.AnimationTrack:Stop(A.FadeTime)table.remove(Animations,V)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 V=(-CurrentSpeed.Turn*(math.pi/6))/1.5 local A=Torso.CFrame.lookVector local T=(Vector3.new(A.X,0,A.Z)).Unit ThrustForce.velocity=A*CurrentSpeed.Movement local F=CFrame.Angles(0,math.pi/2,0)*T if math.abs(A.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 V=CurrentSpeed.Pitch+math.sin(tick()*4)*3 RotationForce.angularvelocity=TurnGyro.cframe*Vector3.new(V*F.X,CurrentSpeed.Turn,V*F.Z)else RotationForce.angularvelocity=TurnGyro.cframe*Vector3.new(CurrentSpeed.Pitch*F.X,CurrentSpeed.Turn,CurrentSpeed.Pitch*F.Z)end TurnGyro.cframe=CFrame.Angles(V*T.X,0,V*T.Z)wait(Rate)end function SetUpMovement()for V,A in pairs(CurrentSpeed)do CurrentSpeed[V]=0 end CurrentSpeed.Movement=MaxSpeed.Movement.Max for V,A in pairs(Controls)do A.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(V,A)local T=string.byte(V)for F,n in pairs(Controls)do if n.Keys.Key==V or n.Keys.ByteKey==T then n.Down=A 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(V)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 V.KeyDown:connect(function(V)KeyPress(V,true)end)V.KeyUp:connect(function(V)KeyPress(V,false)end)Spawn(SetUpMovement)Humanoid:ChangeState(Enum.HumanoidStateType.None)end function Unequipped()for V,A in pairs(Controls)do A.Down=false end for V,A in pairs(AnimationTracks)do if A and A.AnimationTrack then A.AnimationTrack:Stop()end end for V,A in pairs({TurnGyro,ThrustForce,RotationForce})do if tostring(A)=="\067\111\110\110\101\099\116\105\111\110"then A:disconnect()elseif type(A)=="\117\115\101\114\100\097\116\097"and A.Parent then Debris:AddItem(A,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)


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)
