null nil false ControlScript PlayerScripts. // Required Modules: ClickToMove DPad KeyboardMovement Thumbpad Thumbstick TouchJump MasterControl VehicleController --]] local canUseNewControlScript = pcall(function() game:GetService('UserInputService'):GetLastInputType() end) local success, value = pcall(function() return UserSettings():IsUserFeatureEnabled("UserUseNewControlScript") end) local shouldUseNewControlScript = success and value if not canUseNewControlScript or not shouldUseNewControlScript then --[[ Services ]]-- local ContextActionService = game:GetService('ContextActionService') local Players = game:GetService('Players') local UserInputService = game:GetService('UserInputService') -- Settings and GameSettings are read only local Settings = UserSettings() local GameSettings = Settings.GameSettings -- Issue with play solo? (F6) while not UserInputService.KeyboardEnabled and not UserInputService.TouchEnabled and not UserInputService.GamepadEnabled do wait() end --[[ Script Variables ]]-- while not Players.LocalPlayer do wait() end local LocalPlayer = Players.LocalPlayer local PlayerGui = LocalPlayer:WaitForChild('PlayerGui') local IsTouchDevice = UserInputService.TouchEnabled local IsKeyboardDevice = UserInputService.KeyboardEnabled local UserMovementMode = IsTouchDevice and GameSettings.TouchMovementMode or GameSettings.ComputerMovementMode local DevMovementMode = IsTouchDevice and LocalPlayer.DevTouchMovementMode or LocalPlayer.DevComputerMovementMode local IsUserChoice = (IsTouchDevice and DevMovementMode == Enum.DevTouchMovementMode.UserChoice) or DevMovementMode == Enum.DevComputerMovementMode.UserChoice local TouchGui = nil local TouchControlFrame = nil local TouchJumpModule = nil local IsModalEnabled = UserInputService.ModalEnabled local BindableEvent_OnFailStateChanged = nil local BindableEvent_EnableTouchJump = nil local isJumpEnabled = false --[[ Modules ]]-- local CurrentControlModule = nil local ClickToMoveTouchControls = nil local ControlModules = {} local MasterControl = require(script:WaitForChild('MasterControl')) if IsTouchDevice then ControlModules.Thumbstick = require(script.MasterControl:WaitForChild('Thumbstick')) ControlModules.Thumbpad = require(script.MasterControl:WaitForChild('Thumbpad')) ControlModules.DPad = require(script.MasterControl:WaitForChild('DPad')) ControlModules.Default = ControlModules.Thumbstick TouchJumpModule = require(script.MasterControl:WaitForChild('TouchJump')) BindableEvent_OnFailStateChanged = script.Parent:WaitForChild('OnClickToMoveFailStateChange') BindableEvent_EnableTouchJump = script.Parent:WaitForChild('EnableTouchJump') elseif IsKeyboardDevice then ControlModules.Keyboard = require(script.MasterControl:WaitForChild('KeyboardMovement')) end ControlModules.Gamepad = require(script.MasterControl:WaitForChild('Gamepad')) local success, value = pcall(function() return UserSettings():IsUserFeatureEnabled("UserUseLuaVehicleController") end) if success and value then local VehicleController = require(script.MasterControl:WaitForChild('VehicleController')) -- Not used, but needs to be required end --[[ Initialization/Setup ]]-- local function createTouchGuiContainer() if TouchGui then TouchGui:Destroy() end -- Container for all touch device guis TouchGui = Instance.new('ScreenGui') TouchGui.Name = "TouchGui" TouchGui.Parent = PlayerGui TouchControlFrame = Instance.new('Frame') TouchControlFrame.Name = "TouchControlFrame" TouchControlFrame.Size = UDim2.new(1, 0, 1, 0) TouchControlFrame.BackgroundTransparency = 1 TouchControlFrame.Parent = TouchGui ControlModules.Thumbstick:Create(TouchControlFrame) ControlModules.DPad:Create(TouchControlFrame) ControlModules.Thumbpad:Create(TouchControlFrame) TouchJumpModule:Create(TouchControlFrame) end --[[ Local Functions ]]-- local function setJumpModule(isEnabled) if not isEnabled then TouchJumpModule:Disable() elseif CurrentControlModule == ControlModules.Thumbpad or CurrentControlModule == ControlModules.Thumbstick or CurrentControlModule == ControlModules.Default then -- TouchJumpModule:Enable() end end local function setClickToMove() if DevMovementMode == Enum.DevTouchMovementMode.ClickToMove or DevMovementMode == Enum.DevComputerMovementMode.ClickToMove or UserMovementMode == Enum.ComputerMovementMode.ClickToMove or UserMovementMode == Enum.TouchMovementMode.ClickToMove then -- if IsTouchDevice then ClickToMoveTouchControls = CurrentControlModule or ControlModules.Default end else if IsTouchDevice and ClickToMoveTouchControls then ClickToMoveTouchControls:Disable() ClickToMoveTouchControls = nil end end end --[[ Controls State Management ]]-- local onControlsChanged = nil if IsTouchDevice then createTouchGuiContainer() onControlsChanged = function() local newModuleToEnable = nil if not IsUserChoice then if DevMovementMode == Enum.DevTouchMovementMode.Thumbstick then newModuleToEnable = ControlModules.Thumbstick isJumpEnabled = true elseif DevMovementMode == Enum.DevTouchMovementMode.Thumbpad then newModuleToEnable = ControlModules.Thumbpad isJumpEnabled = true elseif DevMovementMode == Enum.DevTouchMovementMode.DPad then newModuleToEnable = ControlModules.DPad isJumpEnabled = false elseif DevMovementMode == Enum.DevTouchMovementMode.ClickToMove then -- Managed by CameraScript newModuleToEnable = nil elseif DevMovementMode == Enum.DevTouchMovementMode.Scriptable then newModuleToEnable = nil end else if UserMovementMode == Enum.TouchMovementMode.Default or UserMovementMode == Enum.TouchMovementMode.Thumbstick then newModuleToEnable = ControlModules.Thumbstick isJumpEnabled = true elseif UserMovementMode == Enum.TouchMovementMode.Thumbpad then newModuleToEnable = ControlModules.Thumbpad isJumpEnabled = true elseif UserMovementMode == Enum.TouchMovementMode.DPad then newModuleToEnable = ControlModules.DPad isJumpEnabled = false elseif UserMovementMode == Enum.TouchMovementMode.ClickToMove then -- Managed by CameraScript newModuleToEnable = nil end end setClickToMove() if newModuleToEnable ~= CurrentControlModule then if CurrentControlModule then CurrentControlModule:Disable() end setJumpModule(isJumpEnabled) CurrentControlModule = newModuleToEnable if CurrentControlModule and not IsModalEnabled then CurrentControlModule:Enable() if isJumpEnabled then TouchJumpModule:Enable() end end end end elseif UserInputService.KeyboardEnabled then onControlsChanged = function() -- NOTE: Click to move still uses keyboard. Leaving cases in case this ever changes. local newModuleToEnable = nil if not IsUserChoice then if DevMovementMode == Enum.DevComputerMovementMode.KeyboardMouse then newModuleToEnable = ControlModules.Keyboard elseif DevMovementMode == Enum.DevComputerMovementMode.ClickToMove then -- Managed by CameraScript newModuleToEnable = ControlModules.Keyboard end else if UserMovementMode == Enum.ComputerMovementMode.KeyboardMouse or UserMovementMode == Enum.ComputerMovementMode.Default then newModuleToEnable = ControlModules.Keyboard elseif UserMovementMode == Enum.ComputerMovementMode.ClickToMove then -- Managed by CameraScript newModuleToEnable = ControlModules.Keyboard end end if newModuleToEnable ~= CurrentControlModule then if CurrentControlModule then CurrentControlModule:Disable() end CurrentControlModule = newModuleToEnable if CurrentControlModule then CurrentControlModule:Enable() end end end elseif UserInputService.GamepadEnabled then onControlsChanged = function() -- nil for now, probably needs some stuff later end end --[[ Settings Changed Connections ]]-- LocalPlayer.Changed:connect(function(property) if IsTouchDevice and property == 'DevTouchMovementMode' then DevMovementMode = LocalPlayer.DevTouchMovementMode IsUserChoice = DevMovementMode == Enum.DevTouchMovementMode.UserChoice if IsUserChoice then UserMovementMode = GameSettings.TouchMovementMode end onControlsChanged() elseif not IsTouchDevice and property == 'DevComputerMovementMode' then DevMovementMode = LocalPlayer.DevComputerMovementMode IsUserChoice = DevMovementMode == Enum.DevComputerMovementMode.UserChoice if IsUserChoice then UserMovementMode = GameSettings.ComputerMovementMode end onControlsChanged() end end) GameSettings.Changed:connect(function(property) if not IsUserChoice then return end if property == 'TouchMovementMode' or property == 'ComputerMovementMode' then UserMovementMode = GameSettings[property] onControlsChanged() end end) --[[ Touch Events ]]-- if IsTouchDevice then -- On touch devices we need to recreate the guis on character load. LocalPlayer.CharacterAdded:connect(function(character) createTouchGuiContainer() if CurrentControlModule then CurrentControlModule:Disable() CurrentControlModule = nil end onControlsChanged() end) UserInputService.Changed:connect(function(property) if property == 'ModalEnabled' then IsModalEnabled = UserInputService.ModalEnabled setJumpModule(not UserInputService.ModalEnabled) if UserInputService.ModalEnabled then if CurrentControlModule then CurrentControlModule:Disable() end else if CurrentControlModule then CurrentControlModule:Enable() end end end end) BindableEvent_OnFailStateChanged.Event:connect(function(isOn) if ClickToMoveTouchControls then if isOn then ClickToMoveTouchControls:Enable() else ClickToMoveTouchControls:Disable() end if ClickToMoveTouchControls == ControlModules.Thumbpad or ClickToMoveTouchControls == ControlModules.Thumbstick or ClickToMoveTouchControls == ControlModules.Default then -- if isOn then TouchJumpModule:Enable() else TouchJumpModule:Disable() end end end end) BindableEvent_EnableTouchJump.Event:connect(function(enable) if enable then TouchJumpModule:Enable() else TouchJumpModule:Disable() end end) end MasterControl:Init() onControlsChanged() -- why do I need a wait here?!?!?!? Sometimes touch controls don't disappear without this wait() if UserInputService.GamepadEnabled then if CurrentControlModule and IsTouchDevice then CurrentControlModule:Disable() end if isJumpEnabled and IsTouchDevice then TouchJumpModule:Disable() end ControlModules.Gamepad:Enable() end UserInputService.GamepadDisconnected:connect(function(gamepadEnum) if UserInputService.GamepadEnabled then return end if CurrentControlModule and IsTouchDevice then CurrentControlModule:Enable() end if isJumpEnabled and IsTouchDevice then TouchJumpModule:Enable() end ControlModules.Gamepad:Disable() end) UserInputService.GamepadConnected:connect(function(gamepadEnum) if gamepadEnum ~= Enum.UserInputType.Gamepad1 then return end if CurrentControlModule and IsTouchDevice then CurrentControlModule:Disable() end if isJumpEnabled and IsTouchDevice then TouchJumpModule:Disable() end ControlModules.Gamepad:Enable() end) -- new version of ControlScript below else --[[ Services ]]-- local ContextActionService = game:GetService('ContextActionService') local Players = game:GetService('Players') local UserInputService = game:GetService('UserInputService') -- Settings and GameSettings are read only local Settings = UserSettings() local GameSettings = Settings.GameSettings -- Issue with play solo? (F6) while not UserInputService.KeyboardEnabled and not UserInputService.TouchEnabled and not UserInputService.GamepadEnabled do wait() end --[[ Script Variables ]]-- while not Players.LocalPlayer do wait() end local lastInputType = nil local LocalPlayer = Players.LocalPlayer local PlayerGui = LocalPlayer:WaitForChild('PlayerGui') local IsTouchDevice = UserInputService.TouchEnabled local UserMovementMode = IsTouchDevice and GameSettings.TouchMovementMode or GameSettings.ComputerMovementMode local DevMovementMode = IsTouchDevice and LocalPlayer.DevTouchMovementMode or LocalPlayer.DevComputerMovementMode local IsUserChoice = (IsTouchDevice and DevMovementMode == Enum.DevTouchMovementMode.UserChoice) or (DevMovementMode == Enum.DevComputerMovementMode.UserChoice) local TouchGui = nil local TouchControlFrame = nil local IsModalEnabled = UserInputService.ModalEnabled local BindableEvent_OnFailStateChanged = nil local isJumpEnabled = false local ControlState = {} ControlState.Current = nil function ControlState:SwitchTo(newControl) if ControlState.Current == newControl then return end if ControlState.Current then ControlState.Current:Disable() end ControlState.Current = newControl if ControlState.Current then ControlState.Current:Enable() end end --[[ Modules ]]-- local ClickToMoveTouchControls = nil local ControlModules = {} local MasterControl = require(script:WaitForChild('MasterControl')) local ThumbstickModule = require(script.MasterControl:WaitForChild('Thumbstick')) local ThumbpadModule = require(script.MasterControl:WaitForChild('Thumbpad')) local DPadModule = require(script.MasterControl:WaitForChild('DPad')) local DefaultModule = ControlModules.Thumbstick local TouchJumpModule = require(script.MasterControl:WaitForChild('TouchJump')) local keyboardModule = require(script.MasterControl:WaitForChild('KeyboardMovement')) ControlModules.Gamepad = require(script.MasterControl:WaitForChild('Gamepad')) function getTouchModule() local module = nil if not IsUserChoice then if DevMovementMode == Enum.DevTouchMovementMode.Thumbstick then module = ThumbstickModule isJumpEnabled = true elseif DevMovementMode == Enum.DevTouchMovementMode.Thumbpad then module = ThumbpadModule isJumpEnabled = true elseif DevMovementMode == Enum.DevTouchMovementMode.DPad then module = DPadModule isJumpEnabled = false elseif DevMovementMode == Enum.DevTouchMovementMode.ClickToMove then -- Managed by CameraScript module = nil elseif DevMovementMode == Enum.DevTouchMovementMode.Scriptable then module = nil end else if UserMovementMode == Enum.TouchMovementMode.Default or UserMovementMode == Enum.TouchMovementMode.Thumbstick then module = ThumbstickModule isJumpEnabled = true elseif UserMovementMode == Enum.TouchMovementMode.Thumbpad then module = ThumbpadModule isJumpEnabled = true elseif UserMovementMode == Enum.TouchMovementMode.DPad then module = DPadModule isJumpEnabled = false elseif UserMovementMode == Enum.TouchMovementMode.ClickToMove then -- Managed by CameraScript module = nil end end return module end function setJumpModule(isEnabled) if not isEnabled then TouchJumpModule:Disable() elseif ControlState.Current == ControlModules.Touch then TouchJumpModule:Enable() end end function setClickToMove() if DevMovementMode == Enum.DevTouchMovementMode.ClickToMove or DevMovementMode == Enum.DevComputerMovementMode.ClickToMove or UserMovementMode == Enum.ComputerMovementMode.ClickToMove or UserMovementMode == Enum.TouchMovementMode.ClickToMove then -- if lastInputType == Enum.UserInputType.Touch then ClickToMoveTouchControls = ControlState.Current end elseif ClickToMoveTouchControls then ClickToMoveTouchControls:Disable() ClickToMoveTouchControls = nil end end ControlModules.Touch = {} ControlModules.Touch.Current = nil ControlModules.Touch.LocalPlayerChangedCon = nil ControlModules.Touch.GameSettingsChangedCon = nil function ControlModules.Touch:RefreshControlStyle() ControlModules.Touch.Current:Disable() setJumpModule(false) TouchJumpModule:Disable() ControlModules.Touch:Enable() end function ControlModules.Touch:DisconnectEvents() if ControlModules.Touch.LocalPlayerChangedCon then ControlModules.Touch.LocalPlayerChangedCon:disconnect() ControlModules.Touch.LocalPlayerChangedCon = nil end if ControlModules.Touch.GameSettingsChangedCon then ControlModules.Touch.GameSettingsChangedCon:disconnect() ControlModules.Touch.GameSettingsChangedCon = nil end end function ControlModules.Touch:Enable() DevMovementMode = LocalPlayer.DevTouchMovementMode IsUserChoice = DevMovementMode == Enum.DevTouchMovementMode.UserChoice if IsUserChoice then UserMovementMode = GameSettings.TouchMovementMode end local newModuleToEnable = getTouchModule() if newModuleToEnable then setClickToMove() setJumpModule(isJumpEnabled) newModuleToEnable:Enable() ControlModules.Touch.Current = newModuleToEnable ControlModules.Touch:DisconnectEvents() ControlModules.Touch.LocalPlayerChangedCon = LocalPlayer.Changed:connect(function(property) if property == 'DevTouchMovementMode' then ControlModules.Touch:RefreshControlStyle() end end) ControlModules.Touch.GameSettingsChangedCon = GameSettings.Changed:connect(function(property) if property == 'TouchMovementMode' then ControlModules.Touch:RefreshControlStyle() end end) if isJumpEnabled then TouchJumpModule:Enable() end end end function ControlModules.Touch:Disable() ControlModules.Touch:DisconnectEvents() local newModuleToDisable = getTouchModule() if newModuleToDisable == ThumbstickModule or newModuleToDisable == DPadModule or newModuleToDisable == ThumbpadModule then newModuleToDisable:Disable() setJumpModule(false) TouchJumpModule:Disable() end end local function getKeyboardModule() -- NOTE: Click to move still uses keyboard. Leaving cases in case this ever changes. local whichModule = nil if not IsUserChoice then if DevMovementMode == Enum.DevComputerMovementMode.KeyboardMouse then whichModule = keyboardModule elseif DevMovementMode == Enum.DevComputerMovementMode.ClickToMove then -- Managed by CameraScript whichModule = keyboardModule end else if UserMovementMode == Enum.ComputerMovementMode.KeyboardMouse or UserMovementMode == Enum.ComputerMovementMode.Default then whichModule = keyboardModule elseif UserMovementMode == Enum.ComputerMovementMode.ClickToMove then -- Managed by CameraScript whichModule = keyboardModule end end return whichModule end ControlModules.Keyboard = {} function ControlModules.Keyboard:Enable() DevMovementMode = LocalPlayer.DevComputerMovementMode IsUserChoice = DevMovementMode == Enum.DevComputerMovementMode.UserChoice if IsUserChoice then UserMovementMode = GameSettings.ComputerMovementMode end local newModuleToEnable = getKeyboardModule() if newModuleToEnable then if newModuleToEnable then newModuleToEnable:Enable() end end end function ControlModules.Keyboard:Disable() local newModuleToDisable = getKeyboardModule() if newModuleToDisable then newModuleToDisable:Disable() end end if IsTouchDevice then BindableEvent_OnFailStateChanged = script.Parent:WaitForChild('OnClickToMoveFailStateChange') end -- not used, but needs to be required local VehicleController = require(script.MasterControl:WaitForChild('VehicleController')) --[[ Initialization/Setup ]]-- local function createTouchGuiContainer() if TouchGui then TouchGui:Destroy() end -- Container for all touch device guis TouchGui = Instance.new('ScreenGui') TouchGui.Name = "TouchGui" TouchGui.Parent = PlayerGui TouchControlFrame = Instance.new('Frame') TouchControlFrame.Name = "TouchControlFrame" TouchControlFrame.Size = UDim2.new(1, 0, 1, 0) TouchControlFrame.BackgroundTransparency = 1 TouchControlFrame.Parent = TouchGui ThumbstickModule:Create(TouchControlFrame) DPadModule:Create(TouchControlFrame) ThumbpadModule:Create(TouchControlFrame) TouchJumpModule:Create(TouchControlFrame) end --[[ Settings Changed Connections ]]-- LocalPlayer.Changed:connect(function(property) if lastInputType == Enum.UserInputType.Touch and property == 'DevTouchMovementMode' then ControlState:SwitchTo(ControlModules.Touch) elseif UserInputService.KeyboardEnabled and property == 'DevComputerMovementMode' then ControlState:SwitchTo(ControlModules.Keyboard) end end) GameSettings.Changed:connect(function(property) if not IsUserChoice then return end if property == 'TouchMovementMode' or property == 'ComputerMovementMode' then UserMovementMode = GameSettings[property] if property == 'TouchMovementMode' then ControlState:SwitchTo(ControlModules.Touch) elseif property == 'ComputerMovementMode' then ControlState:SwitchTo(ControlModules.Keyboard) end end end) --[[ Touch Events ]]-- -- On touch devices we need to recreate the guis on character load. local lastControlState = nil LocalPlayer.CharacterAdded:connect(function(character) if UserInputService.TouchEnabled then createTouchGuiContainer() end if ControlState.Current == nil then ControlState:SwitchTo(lastControlState) end end) LocalPlayer.CharacterRemoving:connect(function(character) lastControlState = ControlState.Current ControlState:SwitchTo(nil) end) UserInputService.Changed:connect(function(property) if property == 'ModalEnabled' then IsModalEnabled = UserInputService.ModalEnabled if lastInputType == Enum.UserInputType.Touch then if ControlState.Current == ControlModules.Touch and IsModalEnabled then ControlState:SwitchTo(nil) elseif ControlState.Current == nil and not IsModalEnabled then ControlState:SwitchTo(ControlModules.Touch) end end end end) if BindableEvent_OnFailStateChanged then BindableEvent_OnFailStateChanged.Event:connect(function(isOn) if lastInputType == Enum.UserInputType.Touch and ClickToMoveTouchControls then if isOn then ControlState:SwitchTo(ClickToMoveTouchControls) else ControlState:SwitchTo(nil) end end end) end local switchToInputType = function(newLastInputType) lastInputType = newLastInputType if lastInputType == Enum.UserInputType.Touch then ControlState:SwitchTo(ControlModules.Touch) elseif lastInputType == Enum.UserInputType.Keyboard or lastInputType == Enum.UserInputType.MouseButton1 or lastInputType == Enum.UserInputType.MouseButton2 or lastInputType == Enum.UserInputType.MouseButton3 or lastInputType == Enum.UserInputType.MouseWheel or lastInputType == Enum.UserInputType.MouseMovement then ControlState:SwitchTo(ControlModules.Keyboard) elseif lastInputType == Enum.UserInputType.Gamepad1 or lastInputType == Enum.UserInputType.Gamepad2 or lastInputType == Enum.UserInputType.Gamepad3 or lastInputType == Enum.UserInputType.Gamepad4 then ControlState:SwitchTo(ControlModules.Gamepad) end end if IsTouchDevice then createTouchGuiContainer() end MasterControl:Init() UserInputService.GamepadDisconnected:connect(function(gamepadEnum) local connectedGamepads = UserInputService:GetConnectedGamepads() if #connectedGamepads > 0 then return end if UserInputService.KeyboardEnabled then ControlState:SwitchTo(ControlModules.Keyboard) elseif IsTouchDevice then ControlState:SwitchTo(ControlModules.Touch) end end) UserInputService.GamepadConnected:connect(function(gamepadEnum) ControlState:SwitchTo(ControlModules.Gamepad) end) switchToInputType(UserInputService:GetLastInputType()) UserInputService.LastInputTypeChanged:connect(switchToInputType) end -- end of control script flag switch]]> MasterControl DPad jumpRadius then local angle = ATAN2(direction.y, direction.x) local octant = (FLOOR(8 * angle / (2 * PI) + 8.5)%8) + 1 movementVector = COMPASS_DIR[octant] end if not flBtn.Visible and movementVector == COMPASS_DIR[7] then flBtn.Visible = true frBtn.Visible = true end end DPadFrame.InputBegan:connect(function(inputObject) if TouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch then return end MasterControl:AddToPlayerMovement(-movementVector) TouchObject = inputObject normalizeDirection(TouchObject.Position) MasterControl:AddToPlayerMovement(movementVector) end) DPadFrame.InputChanged:connect(function(inputObject) if inputObject == TouchObject then MasterControl:AddToPlayerMovement(-movementVector) normalizeDirection(TouchObject.Position) MasterControl:AddToPlayerMovement(movementVector) MasterControl:SetIsJumping(false) end end) OnInputEnded = function() TouchObject = nil flBtn.Visible = false frBtn.Visible = false MasterControl:AddToPlayerMovement(-movementVector) movementVector = Vector3.new(0, 0, 0) end DPadFrame.InputEnded:connect(function(inputObject) if inputObject == TouchObject then OnInputEnded() end end) DPadFrame.Parent = parentFrame end return DPad ]]> Gamepad 0 then for i = 1, #connectedGamepads do if activateGamepad == nil then activateGamepad = connectedGamepads[i] elseif connectedGamepads[i].Value < activateGamepad.Value then activateGamepad = connectedGamepads[i] end end end if activateGamepad == nil then -- nothing is connected, at least set up for gamepad1 activateGamepad = Enum.UserInputType.Gamepad1 end end --[[ Public API ]]-- function Gamepad:Enable() local forwardValue = 0 local backwardValue = 0 local leftValue = 0 local rightValue = 0 local moveFunc = LocalPlayer.Move local gamepadSupports = UserInputService.GamepadSupports local controlCharacterGamepad = function(actionName, inputState, inputObject) if activateGamepad ~= inputObject.UserInputType then return end if inputObject.KeyCode ~= Enum.KeyCode.Thumbstick1 then return end if inputState == Enum.UserInputState.Cancel then MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) return end if inputObject.Position.magnitude > thumbstickDeadzone then MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(inputObject.Position.X, 0, -inputObject.Position.Y) MasterControl:AddToPlayerMovement(currentMoveVector) else MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) end end local jumpCharacterGamepad = function(actionName, inputState, inputObject) if activateGamepad ~= inputObject.UserInputType then return end if inputObject.KeyCode ~= Enum.KeyCode.ButtonA then return end if inputState == Enum.UserInputState.Cancel then MasterControl:SetIsJumping(false) return end MasterControl:SetIsJumping(inputObject.UserInputState == Enum.UserInputState.Begin) end local doDpadMoveUpdate = function(userInputType) if not gamepadSupports(UserInputService, userInputType, Enum.KeyCode.Thumbstick1) then if LocalPlayer and LocalPlayer.Character then MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(leftValue + rightValue,0,forwardValue + backwardValue) MasterControl:AddToPlayerMovement(currentMoveVector) end end end local moveForwardFunc = function(actionName, inputState, inputObject) if inputState == Enum.UserInputState.End then forwardValue = -1 elseif inputState == Enum.UserInputState.Begin or inputState == Enum.UserInputState.Cancel then forwardValue = 0 end doDpadMoveUpdate(inputObject.UserInputType) end local moveBackwardFunc = function(actionName, inputState, inputObject) if inputState == Enum.UserInputState.End then backwardValue = 1 elseif inputState == Enum.UserInputState.Begin or inputState == Enum.UserInputState.Cancel then backwardValue = 0 end doDpadMoveUpdate(inputObject.UserInputType) end local moveLeftFunc = function(actionName, inputState, inputObject) if inputState == Enum.UserInputState.End then leftValue = -1 elseif inputState == Enum.UserInputState.Begin or inputState == Enum.UserInputState.Cancel then leftValue = 0 end doDpadMoveUpdate(inputObject.UserInputType) end local moveRightFunc = function(actionName, inputState, inputObject) if inputState == Enum.UserInputState.End then rightValue = 1 elseif inputState == Enum.UserInputState.Begin or inputState == Enum.UserInputState.Cancel then rightValue = 0 end doDpadMoveUpdate(inputObject.UserInputType) end local function setActivateGamepad() if activateGamepad then ContextActionService:UnbindActivate(activateGamepad, Enum.KeyCode.ButtonR2) end assignActivateGamepad() if activateGamepad then ContextActionService:BindActivate(activateGamepad, Enum.KeyCode.ButtonR2) end end ContextActionService:BindAction("JumpButton",jumpCharacterGamepad, false, Enum.KeyCode.ButtonA) ContextActionService:BindAction("MoveThumbstick",controlCharacterGamepad, false, Enum.KeyCode.Thumbstick1) ContextActionService:BindAction("forwardDpad", moveForwardFunc, false, Enum.KeyCode.DPadUp) ContextActionService:BindAction("backwardDpad", moveBackwardFunc, false, Enum.KeyCode.DPadDown) ContextActionService:BindAction("leftDpad", moveLeftFunc, false, Enum.KeyCode.DPadLeft) ContextActionService:BindAction("rightDpad", moveRightFunc, false, Enum.KeyCode.DPadRight) setActivateGamepad() gamepadConnectedCon = UserInputService.GamepadDisconnected:connect(function(gamepadEnum) if activateGamepad ~= gamepadEnum then return end MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) activateGamepad = nil setActivateGamepad() end) gamepadDisconnectedCon = UserInputService.GamepadConnected:connect(function(gamepadEnum) if activateGamepad == nil then setActivateGamepad() end end) end function Gamepad:Disable() ContextActionService:UnbindAction("forwardDpad") ContextActionService:UnbindAction("backwardDpad") ContextActionService:UnbindAction("leftDpad") ContextActionService:UnbindAction("rightDpad") ContextActionService:UnbindAction("MoveThumbstick") ContextActionService:UnbindAction("JumpButton") ContextActionService:UnbindActivate(activateGamepad, Enum.KeyCode.ButtonR2) if gamepadConnectedCon then gamepadConnectedCon:disconnect() end if gamepadDisconnectedCon then gamepadDisconnectedCon:disconnect() end activateGamepad = nil MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) MasterControl:SetIsJumping(false) end return Gamepad ]]> KeyboardMovement Thumbpad 0.5 then -- UP if not isUp then isUp, isDown = true, false doTween(uArrow, lgArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset, 0, smImgOffset - smArrowSize.Y.Offset * 1.5)) doTween(dArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 1, lgImgOffset)) end elseif forwardDot < -0.5 then -- DOWN if not isDown then isDown, isUp = true, false doTween(dArrow, lgArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset, 1, lgImgOffset + smArrowSize.Y.Offset/2)) doTween(uArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 0, smImgOffset)) end else isUp, isDown = false, false doTween(dArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 1, lgImgOffset)) doTween(uArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 0, smImgOffset)) end if rightDot > 0.5 then if not isRight then isRight, isLeft = true, false doTween(rArrow, lgArrowSize, UDim2.new(1, lgImgOffset + smArrowSize.X.Offset/2, 0.5, -smArrowSize.Y.Offset)) doTween(lArrow, smArrowSize, UDim2.new(0, smImgOffset, 0.5, -smArrowSize.Y.Offset/2)) end elseif rightDot < -0.5 then if not isLeft then isLeft, isRight = true, false doTween(lArrow, lgArrowSize, UDim2.new(0, smImgOffset - smArrowSize.X.Offset * 1.5, 0.5, -smArrowSize.Y.Offset)) doTween(rArrow, smArrowSize, UDim2.new(1, lgImgOffset, 0.5, -smArrowSize.Y.Offset/2)) end else isRight, isLeft = false, false doTween(lArrow, smArrowSize, UDim2.new(0, smImgOffset, 0.5, -smArrowSize.Y.Offset/2)) doTween(rArrow, smArrowSize, UDim2.new(1, lgImgOffset, 0.5, -smArrowSize.Y.Offset/2)) end end --input connections ThumbpadFrame.InputBegan:connect(function(inputObject) if TouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch then return end ThumbpadFrame.Position = UDim2.new(0, inputObject.Position.x - ThumbpadFrame.AbsoluteSize.x/2, 0, inputObject.Position.y - ThumbpadFrame.Size.Y.Offset/2) padOrigin = Vector2.new(ThumbpadFrame.AbsolutePosition.x + ThumbpadFrame.AbsoluteSize.x/2, ThumbpadFrame.AbsolutePosition.y + ThumbpadFrame.AbsoluteSize.y/2) doMove(inputObject.Position) TouchObject = inputObject end) OnTouchChangedCn = UserInputService.TouchMoved:connect(function(inputObject, isProcessed) if inputObject == TouchObject then doMove(TouchObject.Position) end end) OnInputEnded = function() MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) MasterControl:SetIsJumping(false) ThumbpadFrame.Position = position TouchObject = nil isUp, isDown, isLeft, isRight = false, false, false, false doTween(dArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 1, lgImgOffset)) doTween(uArrow, smArrowSize, UDim2.new(0.5, -smArrowSize.X.Offset/2, 0, smImgOffset)) doTween(lArrow, smArrowSize, UDim2.new(0, smImgOffset, 0.5, -smArrowSize.Y.Offset/2)) doTween(rArrow, smArrowSize, UDim2.new(1, lgImgOffset, 0.5, -smArrowSize.Y.Offset/2)) end OnTouchEndedCn = UserInputService.TouchEnded:connect(function(inputObject) if inputObject == TouchObject then OnInputEnded() end end) ThumbpadFrame.Parent = parentFrame end return Thumbpad ]]> Thumbstick maxLength then local offset = relativePosition.unit * maxLength ThumbstickFrame.Position = UDim2.new( 0, pos.x - ThumbstickFrame.AbsoluteSize.x/2 - offset.x, 0, pos.y - ThumbstickFrame.AbsoluteSize.y/2 - offset.y) else length = math.min(length, maxLength) relativePosition = relativePosition.unit * length end StickImage.Position = UDim2.new(0, relativePosition.x + StickImage.AbsoluteSize.x/2, 0, relativePosition.y + StickImage.AbsoluteSize.y/2) end -- input connections ThumbstickFrame.InputBegan:connect(function(inputObject) if MoveTouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch then return end MoveTouchObject = inputObject ThumbstickFrame.Position = UDim2.new(0, inputObject.Position.x - ThumbstickFrame.Size.X.Offset/2, 0, inputObject.Position.y - ThumbstickFrame.Size.Y.Offset/2) centerPosition = Vector2.new(ThumbstickFrame.AbsolutePosition.x + ThumbstickFrame.AbsoluteSize.x/2, ThumbstickFrame.AbsolutePosition.y + ThumbstickFrame.AbsoluteSize.y/2) local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y) moveStick(inputObject.Position) end) OnTouchMovedCn = UserInputService.TouchMoved:connect(function(inputObject, isProcessed) if inputObject == MoveTouchObject then centerPosition = Vector2.new(ThumbstickFrame.AbsolutePosition.x + ThumbstickFrame.AbsoluteSize.x/2, ThumbstickFrame.AbsolutePosition.y + ThumbstickFrame.AbsoluteSize.y/2) local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y) doMove(direction) moveStick(inputObject.Position) end end) OnTouchEnded = function() ThumbstickFrame.Position = position StickImage.Position = UDim2.new(0, ThumbstickFrame.Size.X.Offset/2 - thumbstickSize/4, 0, ThumbstickFrame.Size.Y.Offset/2 - thumbstickSize/4) MoveTouchObject = nil MasterControl:AddToPlayerMovement(-currentMoveVector) currentMoveVector = Vector3.new(0,0,0) MasterControl:SetIsJumping(false) end OnTouchEndedCn = UserInputService.TouchEnded:connect(function(inputObject, isProcessed) if inputObject == MoveTouchObject then OnTouchEnded() end end) ThumbstickFrame.Parent = parentFrame end return Thumbstick ]]> TouchJump VehicleController 0.5 then return 1 elseif value < -0.5 then return -1 end return 0 end local function onRenderStepped() if CurrentVehicleSeat then local moveValue = MasterControl:GetMoveVector() if game:GetService("UserInputService"):GetGamepadConnected(Enum.UserInputType.Gamepad1) and onlyTriggersForThrottle and useTriggersForThrottle then CurrentVehicleSeat.Throttle = -CurrentThrottle else CurrentVehicleSeat.Throttle = getClosestFittingValue(-moveValue.z) end CurrentVehicleSeat.Steer = getClosestFittingValue(moveValue.x) end end local function onSeated(active, currentSeatPart) if active then if currentSeatPart and currentSeatPart:IsA('VehicleSeat') then CurrentVehicleSeat = currentSeatPart if useTriggersForThrottle then ContextActionService:BindAction("throttleAccel", onThrottleAccel, false, Enum.KeyCode.ButtonR2) ContextActionService:BindAction("throttleDeccel", onThrottleDeccel, false, Enum.KeyCode.ButtonL2) end ContextActionService:BindAction("arrowSteerRight", onSteerRight, false, Enum.KeyCode.Right) ContextActionService:BindAction("arrowSteerLeft", onSteerLeft, false, Enum.KeyCode.Left) local success = pcall(function() RunService:BindToRenderStep("VehicleControlStep", Enum.RenderPriority.Input.Value, onRenderStepped) end) if not success then if RenderSteppedCn then return end RenderSteppedCn = RunService.RenderStepped:connect(onRenderStepped) end end else CurrentVehicleSeat = nil if useTriggersForThrottle then ContextActionService:UnbindAction("throttleAccel") ContextActionService:UnbindAction("throttleDeccel") end ContextActionService:UnbindAction("arrowSteerRight") ContextActionService:UnbindAction("arrowSteerLeft") MasterControl:AddToPlayerMovement(Vector3.new(-CurrentSteer, 0, -CurrentThrottle)) CurrentThrottle = 0 CurrentSteer = 0 local success = pcall(function() RunService:UnbindFromRenderStep("VehicleControlStep") end) if not success and RenderSteppedCn then RenderSteppedCn:disconnect() RenderSteppedCn = nil end end end local function CharacterAdded(character) local humanoid = getHumanoid() while not humanoid do wait() humanoid = getHumanoid() end -- if HumanoidSeatedCn then HumanoidSeatedCn:disconnect() HumanoidSeatedCn = nil end HumanoidSeatedCn = humanoid.Seated:connect(onSeated) end if LocalPlayer.Character then CharacterAdded(LocalPlayer.Character) end LocalPlayer.CharacterAdded:connect(CharacterAdded) return VehicleController ]]>