Function incorrectly detecting mobile presses

This function is meant to run whenever the player has the tool equipped and if they’ve pressed their mouse or tapped on the screen if on mobile. This function works just fine on PC, but on mobile it will detect any sort of input as a “Button1Click”. OnServerInvoke is a remote function that takes the player, the “mode” (Input) and the value is if the mouse is down or up.

So, the code isn’t able to tell the difference between any of a mobile user’s inputs.

function OnServerInvoke(player, mode, value)
	if player ~= Player or not ToolEquipped or not mode or not value or not CheckIfAlive() then
		return
	end
	
	if mode == "Button1Click" then

How would I go about fixing this?

Can you show how you’re invoking the remote?

ServerControl = Instance.new("RemoteFunction")
ServerControl.Name = "ServerControl"
ServerControl.Parent = Tool

ClientControl = Instance.new("RemoteFunction")
ClientControl.Name = "ClientControl"
ClientControl.Parent = Tool

function InvokeClient(Mode, Value)
	local ClientReturn = nil
	pcall(function()
		ClientReturn = ClientControl:InvokeClient(Player, Mode, Value)
	end)
	return ClientReturn
end

Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)
ServerControl.OnServerInvoke = OnServerInvoke

I mean the localscript that you’re invoking the server with

Whoops, I’m silly.

Full Local Script:

Tool = script.Parent
Handle = Tool:WaitForChild("Handle")

Players = game:GetService("Players")
RunService = game:GetService("RunService")
UserInputService = game:GetService("UserInputService")

InputCheck = Instance.new("ScreenGui")
InputCheck.Name = "InputCheck"
InputButton = Instance.new("Frame")
InputButton.Name = "InputMonitor"
InputButton.BackgroundTransparency = 1
InputButton.Size = UDim2.new(1, 0, 1, 0)
InputButton.Parent = InputCheck

Animations = {}
LocalObjects = {}

ServerControl = Tool:WaitForChild("ServerControl")
ClientControl = Tool:WaitForChild("ClientControl")

ToolEquipped = false

function SetAnimation(mode, value)
	if not ToolEquipped or not CheckIfAlive() then
		return
	end
	if mode == "PlayAnimation" and value and ToolEquipped and Humanoid then
		for i, v in pairs(Animations) do
			if v.Animation == value.Animation then
				v.AnimationTrack:Stop()
				table.remove(Animations, i)
			end
		end
		local AnimationTrack = Humanoid:LoadAnimation(value.Animation)
		table.insert(Animations, {Animation = value.Animation, AnimationTrack = AnimationTrack})
		AnimationTrack:Play(value.FadeTime, value.Weight, value.Speed)
	elseif mode == "StopAnimation" and value then
		for i, v in pairs(Animations) do
			if v.Animation == value.Animation then
				v.AnimationTrack:Stop(value.FadeTime)
				table.remove(Animations, i)
			end
		end
	end
end

function DisableJump(Boolean)
	if PreventJump then
		PreventJump:disconnect()
	end
	if Boolean then
		PreventJump = Humanoid.Changed:connect(function(Property)
			if Property ==  "Jump" then
				Humanoid.Jump = false
			end
		end)
	end
end

function CheckIfAlive()
	return (((Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Head and Head.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")
	Head = Character:FindFirstChild("Head")
	ToolEquipped = true
	if not CheckIfAlive() then
		return
	end
	PlayerMouse = Mouse
	Mouse.KeyDown:connect(function(Key)
		InvokeServer("KeyPress", {Key = Key, Down = true})
	end)
	Mouse.KeyUp:connect(function(Key)
		InvokeServer("KeyPress", {Key = Key, Down = false})
	end)
	Mouse.Button1Down:connect(function()
		InvokeServer("Button1Click", {Down = true})
	end)
	Mouse.Button1Up:connect(function()
		InvokeServer("Button1Click", {Down = false})
	end)
	local PlayerGui = Player:FindFirstChild("PlayerGui")
	if PlayerGui then
		if UserInputService.TouchEnabled then
			InputCheckClone = InputCheck:Clone()
			InputCheckClone.InputMonitor.InputBegan:connect(function()
				InvokeServer("Button1Click", {Down = true})
			end)
			InputCheckClone.InputMonitor.InputEnded:connect(function()
				InvokeServer("Button1Click", {Down = false})
			end)
			InputCheckClone.Parent = PlayerGui
		end
	end
end

function Unequipped()
	ToolEquipped = false
	if InputCheckClone and InputCheckClone.Parent then
		InputCheckClone:Destroy()
	end
	for i, v in pairs(Animations) do
		if v and v.AnimationTrack then
			v.AnimationTrack:Stop()
		end
	end
	for i, v in pairs(LocalObjects) do
		if v.Object then
			v.Object.LocalTransparencyModifier = 0
		end
	end
	for i, v in pairs({PreventJump, ObjectLocalTransparencyModifier}) do
		if v then
			v:disconnect()
		end
	end
	Animations = {}
	LocalObjects = {}
end

function InvokeServer(mode, value)
	local ServerReturn
	pcall(function()
		ServerReturn = ServerControl:InvokeServer(mode, value)
	end)
	return ServerReturn
end

function OnClientInvoke(mode, value)
	if not ToolEquipped or not CheckIfAlive() or not mode then
		return
	end
	if mode == "PlayAnimation" and value then
		SetAnimation("PlayAnimation", value)
	elseif mode == "StopAnimation" and value then
		SetAnimation("StopAnimation", value)
	elseif mode == "PlaySound" and value then
		value:Play()
	elseif mode == "StopSound" and value then
		value:Stop()
	elseif mode == "MouseData" then
		return {Position = PlayerMouse.Hit.p, Target = PlayerMouse.Target}
	elseif mode == "DisableJump" then
		DisableJump(value)
	elseif mode == "SetLocalTransparencyModifier" and value then
		pcall(function()
			local ObjectFound = false
			for i, v in pairs(LocalObjects) do
				if v == value then
					ObjectFound = true
				end
			end
			if not ObjectFound then
				table.insert(LocalObjects, value)
				if ObjectLocalTransparencyModifier then
					ObjectLocalTransparencyModifier:disconnect()
				end
				ObjectLocalTransparencyModifier = RunService.RenderStepped:connect(function()
					local Camera = game:GetService("Workspace").CurrentCamera
					for i, v in pairs(LocalObjects) do
						if v.Object and v.Object.Parent then
							local CurrentTransparency = v.Object.LocalTransparencyModifier
							local ViewDistance = (Camera.CoordinateFrame.p - Head.Position).Magnitude
							if ((not v.AutoUpdate and (CurrentTransparency == 1 or CurrentTransparency == 0)) or v.AutoUpdate) then
								if ((v.Distance and ViewDistance <= v.Distance) or not v.Distance) then
									v.Object.LocalTransparencyModifier = v.Transparency
								else
									v.Object.LocalTransparencyModifier = 0
								end
							end
						else
							table.remove(LocalObjects, i)
						end
					end
				end)
			end
		end)
	end
end

ClientControl.OnClientInvoke = OnClientInvoke
Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)

Ok now I’m confused, what are you trying to achieve? It looks to me like you’re sending Button1Click whenever any non-keyboard input is performed, and then additionally when an input is made on a gui object if touch is enabled.

It’s also probably a good idea to consider just using user input service as mouse events don’t guarantee predictability on mobile

My bad, I totally forgot about that screen gui. Originally, that was what was detecting any input from the player on mobile since I was a little confused. I left it there because I was trying to figure out how to tell if the player is holding down. How would I go about detecting if a player on mobile is holding down a tap?

Ah I see ok, for tools specifically, you can just use the tool’s Activated and Deactivated events. This will handle all input types (mouse, controller, touch)

For touch specifically, if you don’t want to rely on those events, you can create a userInputService.TouchStarted and .TouchEnded listener. It would be similar to your InputMonitor connections but instead of using a ui object, you’d use the user input service events.

Another option if you want to reduce connections is to use userInputService.InputBegan and InputEnded, those events will pass an InputObject, you can then read said inputobject’s UserInputType property and check if it’s an ok input type (Enum.UserInputType.Touch, Enum.UserInputType.MouseButton1, Enum.KeyCode.ButtonR2). If the input type is ok, invoke the server.

You could also use InputBegan and InputEnded to replace your KeyDown and Up connections to detect keyboard input.

InputBegan:

InputEnded:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.