Situation
On old and worn-out controllers, sometimes pressing down a button a single time will result in multiple button presses. I'm aware of ways to handle that issue when it comes to my own game logic.
However, I'm unaware of a clean solution when it comes to this for Unity UI components, particularly buttons. For those unaware, debouncing is removing unwanted input noise from user input in order to prevent extra activations from triggering too often. In this case: one button press should be one button press (but a faulty controller may result in it reading button down, button up, button down for a single button press.) A way to workaround this issue is to ignore inputs for a short period of time (e.g. 0.2 seconds) after a button press (at least for the UI and specific actions, definitely a bad idea to do for all input.)
Motivation
I have menus with buttons that use the UnityEngine.UI.Button.onClick event to call GameObject.SetActive(). I use the Inspector window to drag different GameObjects to the On Click ()
event section of each of my buttons' Button component so that different sub-menus open and close depending on what the user selected. This can be done in code, but it's certainly more convenient to use the Inspector window in this case.
However, due to a lack of debouncing, instead of going to a single submenu, with my old worn-out Xbox One controller, it is going through two submenus and sometimes even triggering an action on the 3rd one.
This usually isn't a problem in most commercial games. And for my game, it is not an issue for all menus, as when a menu takes you to a different screen, there is a fade effect and the new menu has to be instantiated, so the lack of debouncing doesn't matter because there's nothing else to even immediately trigger. But there's no fading or instantiating done for submenus.
Solutions I've thought of seem unideal
I'm aware that I can just set in the onClick event section in the Inspector window to call my own custom OnButtonClick()
method where I implement debouncing. But that's certainly less convenient and this seems like some basic functionality, so if there's a cleaner way of doing this, I'd prefer to.
My idea was to override UnityEngine.UI.Button.onClick. And that can be done, but I'm pretty sure I'd have to replace all of my Button components with my new DebounceButton components. That also doesn't seem like a clean way of going about this.
Anyone have any better ideas? In case it matters, I'm using Unity 2021.3.6f1 and Rewired v1.1.44.0.