How To: Gamepad Cursor "Mouse Click" VS UMG Buttons - No plugin, CommonUI or C++

For those who have an existing project since UE4, here’s a tacky hack. If you are starting a new project, Ignore this and maybe go for CommonUI.


I’ve been pulling my hair for a solution that allows the following:

Using the gamepad as a cursor (easy enough, it’s well documented) - BUT clicking UMG Buttons is also possible, without focus on the buttons themselves.

The following is assuming you have basic understanding of Blueprint Interfaces. There are a lot of tutorials on youtube if you’re not sure.

INGREDIENTS:

  • Blueprint Interface (I called mine GamepadButtonBPI)
    • I created 2 events. One is GamepadButtonClick and the other GamepadButtonSend. In the input of the latter, I added one “Widget Object Reference”.
  • Each buttons must ideally be part of a Custom Widget, and one Button per Custom Widget (If you have a canvas with 20+ Buttons already, you can add a “ButtonID” integer to GamepadButtonSend, so on hovering of buttons it sends an ID which you then apply from the GamepadButtonClick using an int switch, worked for me)
  • A GameMode where you store your usual references / game logic. (I prefer this way, but if you can do everything in the PlayerController, feel free to bypass the GameMode)
  • A PlayerController where your GameMode is referenced already

RECEPIE:

  • Uncheck “Is Focusable” in all of your Custom Widget’s Buttons, this will prevent the hardcoded behavior for gamepad to occur when trying to navigate focused elements.
  • Implement the BPI to both the GameMode and your Custom Widgets that have the single Button, also implement the GamepadButtonClick events to your custom widgets, plug it where your usual OnPressed / OnClicked logic fires.
  • From the Custom Widgets, create a OnHovered event for when the Button is hovered. Plug this event to send a SELF reference (don’t forget to plug it!) of your Custom Widget via GamepadButtonSend to your GameMode (You can simply do “Get Gamemode” to get a reference to it, assuming it’s assigned by default in your project)
  • In the GameMode, Implement the GamepadButtonSend event and promote the “Widget Object Reference” to something like ActiveGamepadButton.
  • In the PlayerController, choose your desired input for “clicking”. Should normally be “Gamepad Face Bottom” for most games.
  • From the Desired input event mentioned in the step above, get your GameMode reference and check if ActiveGamepadButton is valid. If true, send a GamepadButtonClick message to it. Then sent the reference of ActiveGamepadButton to none so users can’t continuously re-enter the same menu from the next submenu.
  • For the rest you can create UnHover events to clear the ActiveGamepadButton so it’s no longer valid when you’re not hovering. Depending on your spacing between button you may have Unhover events clear the reference immediately after it was added from a new button hover, this can be avoided by having the Unhover event only remove its reference if compared with itself - if the object is a new one, then we shouldn’t clear it.

I hope that helps, because I searched for way too long for a solution until I came up with this.

In the end it looks something like this:

Inside the GameMode

Inside Custom Widgets


Inside PlayerController (DirectorRef = GameMode in my case, I already referenced it)

And lastly, for the Cursor movement (inside the PlayerController) if you’re wondering about that:

1 Like