199 lines
6.6 KiB
Lua
199 lines
6.6 KiB
Lua
--[[
|
|
// FileName: Gamepad
|
|
// Written by: jeditkacheff
|
|
// Description: Implements movement controls for gamepad devices (XBox, PS4, MFi, etc.)
|
|
--]]
|
|
local Gamepad = {}
|
|
|
|
local MasterControl = require(script.Parent)
|
|
|
|
local Players = game:GetService('Players')
|
|
local RunService = game:GetService('RunService')
|
|
local UserInputService = game:GetService('UserInputService')
|
|
local ContextActionService = game:GetService('ContextActionService')
|
|
local StarterPlayer = game:GetService('StarterPlayer')
|
|
local Settings = UserSettings()
|
|
local GameSettings = Settings.GameSettings
|
|
local currentMoveVector = Vector3.new(0,0,0)
|
|
local activateGamepad = nil
|
|
|
|
local gamepadConnectedCon = nil
|
|
local gamepadDisconnectedCon = nil
|
|
|
|
while not Players.LocalPlayer do
|
|
wait()
|
|
end
|
|
local LocalPlayer = Players.LocalPlayer
|
|
|
|
--[[ Constants ]]--
|
|
local thumbstickDeadzone = 0.22 --raised from 14% on 3/1/16 to accommodate looser XB360 controllers
|
|
|
|
function assignActivateGamepad()
|
|
local connectedGamepads = UserInputService:GetConnectedGamepads()
|
|
if #connectedGamepads > 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 inputState == Enum.UserInputState.Cancel then
|
|
MasterControl:AddToPlayerMovement(-currentMoveVector)
|
|
currentMoveVector = Vector3.new(0,0,0)
|
|
return
|
|
end
|
|
|
|
if activateGamepad ~= inputObject.UserInputType then return end
|
|
if inputObject.KeyCode ~= Enum.KeyCode.Thumbstick1 then 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 inputState == Enum.UserInputState.Cancel then
|
|
MasterControl:SetIsJumping(false)
|
|
return
|
|
end
|
|
|
|
if activateGamepad ~= inputObject.UserInputType then return end
|
|
if inputObject.KeyCode ~= Enum.KeyCode.ButtonA then return end
|
|
|
|
MasterControl:SetIsJumping(inputObject.UserInputState == Enum.UserInputState.Begin)
|
|
end
|
|
|
|
local doDpadMoveUpdate = function(userInputType)
|
|
if LocalPlayer and LocalPlayer.Character then
|
|
MasterControl:AddToPlayerMovement(-currentMoveVector)
|
|
currentMoveVector = Vector3.new(leftValue + rightValue,0,forwardValue + backwardValue)
|
|
MasterControl:AddToPlayerMovement(currentMoveVector)
|
|
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)
|
|
|
|
setActivateGamepad()
|
|
|
|
if not gamepadSupports(UserInputService, activateGamepad, Enum.KeyCode.Thumbstick1) then
|
|
-- if the gamepad supports thumbsticks, theres no point in having the dpad buttons getting eaten up by these actions
|
|
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)
|
|
end
|
|
|
|
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
|