Hello,
I’d like to know the most efficient way to handle the mouse cursor in Game, specifically hide/show it on demand.
What I can see so far is that in our menus, calling PlayerController->SetShowMouseCursor(true) will effectively show the cursor, but SetShowMouseCursor(false) won’t hide it. (Our game is paused in menus)
I can also see that there is some functions in FViewport related to Cursor and SoftwareCursor that don’t seem to work in our case either.
What we need to do is hide the cursor on Gamepad events and show it on keyboard/mouse input. This doesn’t seem to be a complexe feature, but as far as I can see on the Internet, it’s not so trivial to make this work in UE.
Thank you for your help,
Hey Simon, firstly regarding detecting any Gamepad input vs. any Keyboard/Mouse input the approach I recommend is creating a custom IInputProcessor (actually preprocessor) class that can be registered via FSlateApplication::RegisterInputPreProcessor(). Some discussion on that can be [read [Content removed] You’d override
virtual bool HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& InKeyEvent) override
to categorize the InKeyEvent as gamepad or mouse/keyboard and execute the mouse showing/hiding logic.
As for SetShowMouseCursor(false) not consistently hiding the mouse, it’s because that setting applies only when the GameViewport currently has the mouse focus rather than UI. Recall that for a PlayerController you can set its input mode to Game Only, Game and UI, or UI Only. In the latter two modes, if the last mouse click was on a UI element the UI layer will be focused causing the mouse to show. You can hide the mouse by focusing on the game viewport, which (apparently, I found out) also requires an explicit call to refresh the hardware cursor. Here is how it looks:
- Edit: Add “Slate” to your Project.Build.cs PublicDependencyModules.
`UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
// Hide cursor when game viewport has cursor focus
APlayerController* PC = World->GetFirstPlayerController();
PC->bShowMouseCursor = false;
// Set cursor focus to game viewport
FSlateApplication::Get().SetAllUserFocusToGameViewport(EFocusCause::Cleared);
// Refresh the harware cursor
FSlateApplication::Get().OnCursorSet();`Then the mouse will be hidden, without having to set a specific input mode:
- You’ll receive all inputs via your IInputProcessor which can handle input before game or UI can.
- Once UI is focused again because you click a widget, the mouse is shown again.
- I believe widget navigation via gamepad input should still work, though correct me if you run into issues
If this doesn’t solve your needs, can you state the Input Mode that you’re trying to get mouse hiding to work with? A screen recording of repro steps where the mouse stays visible with console command ‘showdebug INPUT’ would be helpful too!
Hey there, I’m happy to hear my previous answer helped! Closing this question.
Hey Zhi Kang,
Thanks for all the details, the InputProcessor system to detect mouse/gamepad inputs works like a charm.
Though I’m still having issues hidding the software cursor in our menus.
I have some code that looks like this:
SetShowMouseCursor(NewMode == EInputMode::MouseAndKeyboard); if (!ShouldShowMouseCursor()) { FSlateApplication::Get().SetAllUserFocusToGameViewport(EFocusCause::Cleared); FSlateApplication::Get().OnCursorSet(); }
I previously set FInputModeUIOnly.
Yet when ShouldShowMouseCursor() is false, we still have our software cursor visible.
Something I’m missing with the input mode ?
Cheers,
Hey there, I only tested with the hardware cursor so my previous suggestion is incomplete if you’re using a software cursor in-game. How are you setting the software cursor?
Perhaps explicitly setting the PlayerController’s CurrentMouseCursor enum helps:
// Hide cursor when game viewport has cursor focus APlayerController* PC = World->GetFirstPlayerController(); PC->bShowMouseCursor = false; PC->CurrentMouseCursor = EMouseCursor::Type::None;
Otherwise, can you provide some Project Settings or CPP/BP repro steps for setting the software cursor? And can you confirm that having last clicked UI is what causes the cursor to stay visible even after setting bShowMouseCursor = false?
Hey there,
After doing a few tests with a custom SoftwareCursor I manage to make it work with the first piece of code you wrote.
Thanks for your help !