GUI that changes for each device type, using UserInputService?

Hello developers,

Currently, I am adding the following to my game: Gamepad & Mobile support. Though, I have ran into an issue. My first method was using UserInputService.LastInputTypeChanged, but this option is not suitable for my needs as it does not work as intended. Maybe I am doing something wrong?

Here’s the code in the module that controls this behavior:

Package.CurrentDeviceUserInputTypes = { }

function Package.GetPlatform(): "Mobile" | "Desktop" | "Gamepad" | "Unknown"
	local LatestInputType = UserInputService:GetLastInputType()
	
	if LatestInputType == Enum.UserInputType.Keyboard or string.find(LatestInputType.Name, "Mouse") then
		table.clear(Package.CurrentDeviceUserInputTypes)
		for index, value in Enum.UserInputType:GetEnumItems() do
			if string.find(value.Name, "Mouse") or value == Enum.UserInputType.Keyboard then
				table.insert(Package.CurrentDeviceUserInputTypes, value)
			end
		end
		return "Desktop"
	elseif LatestInputType == Enum.UserInputType.Touch or LatestInputType == Enum.UserInputType.Accelerometer or LatestInputType == Enum.UserInputType.Gyro then
		table.clear(Package.CurrentDeviceUserInputTypes)
		for index, value in Enum.UserInputType:GetEnumItems() do
			if value == Enum.UserInputType.Touch or value == Enum.UserInputType.Accelerometer or value == Enum.UserInputType.Gyro then
				table.insert(Package.CurrentDeviceUserInputTypes, value)
			end
		end
		return "Mobile"
	elseif string.find(LatestInputType.Name, "Gamepad") then
		table.clear(Package.CurrentDeviceUserInputTypes)
		for index, value in Enum.UserInputType:GetEnumItems() do
			if string.find(value.Name, "Gamepad") then
				table.insert(Package.CurrentDeviceUserInputTypes, value)
			end
		end
		return "Gamepad"
	end
	
	return "Unknown"
end

function Package.AssignLocalPlayer(userInputType: Enum.UserInputType?, oldGui: ScreenGui?): ScreenGui
	local InputType
	
	if not userInputType then
		InputType = Package.GetPlatform()
	else
		InputType = userInputType
	end
	
	if oldGui then
		oldGui.Enabled = false
	end
	
	if InputType == "Unknown" then
		error("Could not get user device platform, resolved to Unknown")
	end
	
	local RequestedGui = USER_GUI_LIST[InputType]
	
	RequestedGui.Parent = EngineClient.LocalObjects.PlayerGui
	
	return RequestedGui
end

It’s honestly really bad and I need it changed. I know I’m probably using the event wrong, so are there any easier solutions than doing this? It’s really annoying. The reason I insert the enums into a table is so I could check if the latest input was in it and stop the event from firing further.

UserInputService.LastInputTypeChanged:Connect(function(newLatestInputType)
	if table.find(DeviceGuiManager.CurrentDeviceUserInputTypes, newLatestInputType) then
		return
	end
	
	local NewUI = DeviceGuiManager.AssignLocalPlayer(newLatestInputType, Package.UserGui)
	Package.UserGui = NewUI
end)

A really basic way to check for device type that I use in my games is to do this:

if UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled then
-- Mobile user
elseif UserInputService.GamepadEnabled then
-- Controller user
elseif UserInputService.MouseEnabled and UserInputService.KeyboardEnabled then
-- PC user
else
-- Other
end

According to UserInputService documentation, you can detect platform player is using with following properties: TouchEnabled, MouseEnabled, KeyboardEnabled, GamepadEnabled. You will also need to check if player for example is using gamepad an keyboard at the same time (you can connect them both to your pc).

1 Like