I’m trying to get UI navigation to work with a controller. The way I’m currently trying to implement it is to still use the cursor and use the sticks to move the cursor around and click on UI buttons using a button on the controller. I was able to move the cursor around with the sticks. However, the actual click event I haven’t been able to get to work.
I have an input action set up for when I press the button on the controller. But I can’t figure out how to then get it to register as a left mouse button click so I can trigger the UI button’s on clicked event. I feel like I’m asking a very stupid and easy question but I have been searching for over half a day at this point and just can’t find the answer.
I’m fairly new to Unreal Engine and I’m using blueprints in Unreal Engine 5.3.2
HI, It’s not an odd question. I am currently in the process of implementing this same feature you are trying to do. It is essential if you want your entire game to have full gamepad support. Unfortunately the feature you are looking for is in a .h file with not very many resources as to how to add the Gamepad function to it. I am currently in the process of this and if I successfully add the function I will post it here. Long story short it’s a header file that needs a new implementation (or a new header file) written in C++, so that it can be included with the original.
For new projects it’s probably best to look into leveraging CommonUI that has gamepad support built in, but I had an existing project that wasn’t using this that I had to retrofit. This is a super hacky solution but is working for me to trigger the click and hover functionality, including the sounds set in the widget designer, which is why I had to resort to the synthetic events. For SButton it doesn’t seem to matter what I pass in for the mouse event so I just pass in a default constructed object. I then trigger these from my main widget based on a wrapping index that changes based on d-pad and thumbstick navigation.
For clicking, I needed to set which button was clicked and for good measure trigger mouse up immediately after.
The solution relies on creating a subclass of the UMG UButton:
#include "Widgets/Input/SButton.h"
// Also need to add "Slate" and "SlateCore" and "InputCore" to your module dependencies in YourModule.build.cs
namespace
{
FPointerEvent CreateMouseClick(const FKey& Key)
{
return { 0, { 0.f,0.f }, { 0.f,0.f }, {}, Key, 0, {} };
}
}
void UMyButton::Hover()
{
if (MyButton.IsValid())
{
MyButton->OnMouseEnter(MyButton->GetCachedGeometry(), {});
}
else
{
SlateHandleHovered();
}
}
void UMyButton::ExitHover()
{
if (MyButton.IsValid())
{
MyButton->OnMouseLeave({});
}
else
{
SlateHandleUnhovered();
}
}
void UMyButton::Click()
{
if (MyButton.IsValid())
{
MyButton->OnMouseButtonDown(MyButton->GetCachedGeometry(),
CreateMouseClick(EKeys::LeftMouseButton));
MyButton->OnMouseButtonUp(MyButton->GetCachedGeometry(),
CreateMouseClick(EKeys::LeftMouseButton));
}
// OnClick handlers not called by the mouse events - probably because the events need to be delayed
SlateHandleClicked();
}