local a={[Enum.UserInputType.Keyboard]=Keyboard,[Enum.UserInputType.MouseButton1]=Keyboard;[Enum.UserInputType.MouseButton2]=Keyboard;[Enum.UserInputType.MouseButton3]=Keyboard;[Enum.UserInputType.MouseWheel]=Keyboard;[Enum.UserInputType.MouseMovement]=Keyboard;[Enum.UserInputType.Gamepad1]=Gamepad,[Enum.UserInputType.Gamepad2]=Gamepad,[Enum.UserInputType.Gamepad3]=Gamepad,[Enum.UserInputType.Gamepad4]=Gamepad}local w function ControlModule.new()local a=setmetatable({},ControlModule)a.controllers={}a.activeControlModule=nil a.activeController=nil a.touchJumpController=nil a.moveFunction=Players.LocalPlayer.Move a.humanoid=nil a.lastInputType=Enum.UserInputType.None a.humanoidSeatedConn=nil a.vehicleController=nil a.touchControlFrame=nil a.vehicleController=VehicleController.new(CONTROL_ACTION_PRIORITY)Players.LocalPlayer.CharacterAdded:Connect(function(w)a:OnCharacterAdded(w)end)Players.LocalPlayer.CharacterRemoving:Connect(function(w)a:OnCharacterRemoving(w)end)if Players.LocalPlayer.Character then a:OnCharacterAdded(Players.LocalPlayer.Character)end RunService:BindToRenderStep("\067\111\110\116\114\111\108\083\099\114\105\112\116\082\101\110\100\101\114\115\116\101\112",Enum.RenderPriority.Input.Value,function(w)a:OnRenderStepped(w)end)UserInputService.LastInputTypeChanged:Connect(function(w)a:OnLastInputTypeChanged(w)end);(UserGameSettings:GetPropertyChangedSignal("\084\111\117\099\104\077\111\118\101\109\101\110\116\077\111\100\101")):Connect(function()a:OnTouchMovementModeChange()end);(Players.LocalPlayer:GetPropertyChangedSignal("\068\101\118\084\111\117\099\104\077\111\118\101\109\101\110\116\077\111\100\101")):Connect(function()a:OnTouchMovementModeChange()end);(UserGameSettings:GetPropertyChangedSignal("\067\111\109\112\117\116\101\114\077\111\118\101\109\101\110\116\077\111\100\101")):Connect(function()a:OnComputerMovementModeChange()end);(Players.LocalPlayer:GetPropertyChangedSignal("\068\101\118\067\111\109\112\117\116\101\114\077\111\118\101\109\101\110\116\077\111\100\101")):Connect(function()a:OnComputerMovementModeChange()end)a.playerGui=nil a.touchGui=nil a.playerGuiAddedConn=nil;(UserInputService:GetPropertyChangedSignal("\077\111\100\097\108\069\110\097\098\108\101\100")):Connect(function()a:UpdateTouchGuiVisibility()end)if UserInputService.TouchEnabled then a.playerGui=Players.LocalPlayer:FindFirstChildOfClass("\080\108\097\121\101\114\071\117\105")if a.playerGui then a:CreateTouchGuiContainer()a:OnLastInputTypeChanged(UserInputService:GetLastInputType())else a.playerGuiAddedConn=Players.LocalPlayer.ChildAdded:Connect(function(w)if w:IsA("\080\108\097\121\101\114\071\117\105")then a.playerGui=w a:CreateTouchGuiContainer()a.playerGuiAddedConn:Disconnect()a.playerGuiAddedConn=nil a:OnLastInputTypeChanged(UserInputService:GetLastInputType())end end)end else a:OnLastInputTypeChanged(UserInputService:GetLastInputType())end return a end
-- Keyboard controller is really keyboard and mouse controller
local computerInputTypeToModuleMap = {
	[Enum.UserInputType.Keyboard] = Keyboard,
	[Enum.UserInputType.MouseButton1] = Keyboard,
	[Enum.UserInputType.MouseButton2] = Keyboard,
	[Enum.UserInputType.MouseButton3] = Keyboard,
	[Enum.UserInputType.MouseWheel] = Keyboard,
	[Enum.UserInputType.MouseMovement] = Keyboard,
	[Enum.UserInputType.Gamepad1] = Gamepad,
	[Enum.UserInputType.Gamepad2] = Gamepad,
	[Enum.UserInputType.Gamepad3] = Gamepad,
	[Enum.UserInputType.Gamepad4] = Gamepad,
}

local lastInputType

function ControlModule.new()
	local self = setmetatable({}, ControlModule)

	-- The Modules above are used to construct controller instances as-needed, and this
	-- table is a map from Module to the instance created from it
	self.controllers = {}

	self.activeControlModule = nil -- Used to prevent unnecessarily expensive checks on each input event
	self.activeController = nil
	self.touchJumpController = nil
	self.moveFunction = Players.LocalPlayer.Move
	self.humanoid = nil
	self.lastInputType = Enum.UserInputType.None

	-- For Roblox self.vehicleController
	self.humanoidSeatedConn = nil
	self.vehicleController = nil

	self.touchControlFrame = nil

	self.vehicleController = VehicleController.new(CONTROL_ACTION_PRIORITY)

	Players.LocalPlayer.CharacterAdded:Connect(function(char)
		self:OnCharacterAdded(char)
	end)
	Players.LocalPlayer.CharacterRemoving:Connect(function(char)
		self:OnCharacterRemoving(char)
	end)
	if Players.LocalPlayer.Character then
		self:OnCharacterAdded(Players.LocalPlayer.Character)
	end

	RunService:BindToRenderStep("ControlScriptRenderstep", Enum.RenderPriority.Input.Value, function(dt)
		self:OnRenderStepped(dt)
	end)

	UserInputService.LastInputTypeChanged:Connect(function(newLastInputType)
		self:OnLastInputTypeChanged(newLastInputType)
	end)

	UserGameSettings:GetPropertyChangedSignal("TouchMovementMode"):Connect(function()
		self:OnTouchMovementModeChange()
	end)
	Players.LocalPlayer:GetPropertyChangedSignal("DevTouchMovementMode"):Connect(function()
		self:OnTouchMovementModeChange()
	end)

	UserGameSettings:GetPropertyChangedSignal("ComputerMovementMode"):Connect(function()
		self:OnComputerMovementModeChange()
	end)
	Players.LocalPlayer:GetPropertyChangedSignal("DevComputerMovementMode"):Connect(function()
		self:OnComputerMovementModeChange()
	end)

	--[[ Touch Device UI ]]
	--
	self.playerGui = nil
	self.touchGui = nil
	self.playerGuiAddedConn = nil

	UserInputService:GetPropertyChangedSignal("ModalEnabled"):Connect(function()
		self:UpdateTouchGuiVisibility()
	end)

	if UserInputService.TouchEnabled then
		self.playerGui = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui")
		if self.playerGui then
			self:CreateTouchGuiContainer()
			self:OnLastInputTypeChanged(UserInputService:GetLastInputType())
		else
			self.playerGuiAddedConn = Players.LocalPlayer.ChildAdded:Connect(function(child)
				if child:IsA("PlayerGui") then
					self.playerGui = child
					self:CreateTouchGuiContainer()
					self.playerGuiAddedConn:Disconnect()
					self.playerGuiAddedConn = nil
					self:OnLastInputTypeChanged(UserInputService:GetLastInputType())
				end
			end)
		end
	else
		self:OnLastInputTypeChanged(UserInputService:GetLastInputType())
	end

	return self
end
