How to capture/cancel a click event on the button

The Unity UI Button click is fired if the pointer down and up events are both registered on the button GameObject. I’d like to prevent this click event because a different custom UI control has “stole the focus” in-between pointer down and up.

Basically, I have this scenario:

  • Pointer down on button
  • Mouse is moved away from button and a drag is detected on a different element
  • Drag event fires a different action and the button click should be cancelled
  • Mouse is moved back over button and released
  • Now a click event is triggered, but I wanted to cancel it because the drag control took over

Is something like this possible in a clean way? Like, for example, I’ve tried to call AbstractEventData.Use() on the PointerEventData that is passed to the drag control, but it didn’t do anything. I kind of expected this to work like IMGUI Use() or StopPropagation in other UI systems.

As for hacky ideas, sure I could disable the button when the drag is detected, but I’m actually trying to implement this in a generic way that adheres to the IPointerEventHandlers and so I’m not trying to hardcode any relationships to concrete Buttons, Sliders etc. Ideally, capturing the event should steal it away from all other controls.

So it looks like Use() isn’t really doing anything but along that trail, I found that I could basically set any other variable on the passed event data and it will impact other systems. For example, I can set eligibleForClick to false when a drag starts and it will prevent any further button clicks, which is exactly what I want. In this case, it’s pretty useful that everything is editable, although I imagine I can break a lot of things if I start modifying the passed data too much.

Old topic but I found out that setting multiple event systems and switching (enabling/disabling) them accordingly to the panels they control works out pretty well !

I have to bump this because I’ve been facing this problem for weeks and no keyword combination on google gives me a useful answer.

For a second I thought Drag Threshold in the Event System would help but Buttons simply don’t care about anything other than the down/up positions…

Have you tried this? Worked pretty well for me.

After I ran into this issue a couple of times I also discovered: Input.ResetInputAxes

Although there is not much documentation about how EventSystem stuff and Unity input actually related, I can say from experimentation, that the EventSystem used the legacy input class (at least if the new input system is not used in the project) and so this call actually works to cancel buttons. Yes, even if it is names “Axes” it also prevents mouse and controller buttons.

This feels really hacky, but for prototyping it’s a pretty handy “just fix this, I don’t care” solution when I want to prevent any further click input after it a special event. For example: players can click a tile to move there, but drag a tile to move the tile itself. If everything is managed on the same GameObject via OnPointerClickHandler and IDragHandler, I believe it is possible to set PointerEventData.eligibleForClick, but if two different systems use separate input that won’t work. In this situation Input.ResetInputAxes will cancel any started button presses.