Note: Also, I want to call out that when testing the method SetAllUserFocusToGameViewport() mentioned a few times in this thread, I found my PIE sessions bugged out with 2 or more players (causing some amount of mouse input to send to all windows). That might not be an issue for your players, but obviously obstructed reliable testing.
For anyone still running into this problem where hiding the mouse cursor doesn’t work while using a gamepad (I still am on 5.6), you can try running this command after you show/hide the mouse cursor (or if you are just changing input modes–run it after that):
// Run your code to hide the mouse cursor
PlayerController->SetShowMouseCursor(false);
// ... or ... PlayerController->SetInputMode(FInputModeGameOnly());
// Then run this function
FSlateApplication::Get().UsePlatformCursorForCursorUser(true);
In my case, I was switching between FInputModeGameAndUI and FInputModeGameOnly when the user pauses/unpauses (to allow keyboard/mouse control for the menus), and if you try to switch the input mode or hide the cursor while a gamepad is active, it won’t update the cursor until the mouse is moved.
The “UsePlatformCursorForCursorUser” is the same call that is made when you run the console command “CommonInput.EnableGamepadPlatformCursor 1” and so far it seems to work well for me in both PIE and packaged builds!
Also, if you happen to be using a mode like FInputModeGameAndUI or FInputModeUIOnly and SetShowMouseCursor is still not working, then you can try this:
// Inside my custom player controller
SetShowMouseCursor(false);
// The following code will "undo" the `SlateOperations.ReleaseMouseCapture();` call that
// FInputModeGameAndUI and FInputModeUIOnly invokes
// ... you could also make a custom input mode for this
const TSharedPtr<SViewport> ViewportWidget = GetWorld()->GetGameViewport()->GetGameViewportWidget();
if (ViewportWidget.IsValid())
{
const TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.ToSharedRef();
GetLocalPlayer()->GetSlateOperations().UseHighPrecisionMouseMovement(ViewportWidgetRef);
}
FSlateApplication::Get().UsePlatformCursorForCursorUser(true);
In my case, when I open my UI menu screen, I’ll check if the user is using a gamepad (using CommonInput via the CommonUI plug-in), and then if so I’ll run the code above from within my player controller to hide the cursor. It seems to work reliably for me.