Make button drag deselection in ContextActionService fire an End UserInputState

I’ve been using the ContextActionService for some time now due to its utility, specially when implementing mobile compatible behavior.

I have discovered that (or at least during debugging in studio) when the user selects a button, then moves away from it (cursor), it fires a single Change UserInputState, but does not fire a End UserInputState, despite the button not being used anymore.

You can reproduce this with this code:

local CAS = game:GetService('ContextActionService')

function TestFunction(Action, State)
	if State ~= Enum.UserInputState.Begin then return end
	
	print(State)
end

CAS:BindAction("Test", TestFunction, true, "")
CAS:SetPosition("Test", UDim2.new(0.1, 0, 0.1, 0))

After adding a LocalScript containing this code under StarterPlayerScripts (you could use the Backpack or PlayerGui, but I’d recommend placing this code under StarterPlayerScripts), all you have to do is enable mobile emulation and play solo:
image

When you enter the debug session, you’ll be able to see the mobile button.

The issue lies here. If you hold it down like you’d expect someone to do normally, you’ll see Change being fired in the output. This is normal. If you stop holding it, it will fire End.

However, if you instead press it, but drag out of it instead of stopping when hovering the button, it will fire a last Change but not any End.

This can be problematic, specially when you rely on the End being fired behavior for your code.

In my case, I’m working on a gun system. I’ve implemented mobile compatibility to it, and tried making so that while you’re holding down the button it shoots, and when you aren’t, it doesn’t.
However, this has became a problem, because you can simply drag your touch out of the button, and it will keep firing, as no End UserInputState is fired.

It is worth to note that this happens during actual mobile gameplay, and not just studio emulation.

I’d really love to see the End UserInputState being passed when users drag their touch / cursor out of the button and cancel the action. It is not as rare as it seems, specially during gun fights.

7 Likes