I’ve been round the houses trying to find a solution to this and just can’t seem to find it.
I’m building out a new project and want to allow the player controller to access the pause menu via the gamepad.
Currently the following code allows me to open and close the pause menu, I can also navigate (up, down, left, right) and select using the D pad and Bottom face key.
I have two questions:
-
Why do the buttons not enter “hovered” state when selecting them with gamepad, and how can I fix this?
-
I have not actually created input actions for menu navigation, this seems to automatically happen whenever I open the pause menu widget. This leads me to believe that my code is having little impact on the menu navigation system, and if so, is there a better way for me to play with the functionality rather than from the player controller?
#include "MyPlayerController.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Blueprint/UserWidget.h"
#include <Kismet/GameplayStatics.h>
AMyPlayerController::AMyPlayerController()
: PauseMenuWidgetInstance(nullptr) // Initialize the widget instance to nullptr
{
// Constructor logic here if needed
}
void AMyPlayerController::BeginPlay()
{
Super::BeginPlay();
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(InputMappingContext, 0);
}
}
void AMyPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
EnhancedInputComponent->BindAction(PauseAction, ETriggerEvent::Triggered, this, &AMyPlayerController::PauseGame);
}
}
void AMyPlayerController::PauseGame(const FInputActionValue& Value)
{
const bool CurrentValue = Value.Get<bool>();
if (CurrentValue)
{
// Toggle game paused state
bool bIsPaused = UGameplayStatics::IsGamePaused(GetWorld());
UGameplayStatics::SetGamePaused(GetWorld(), !bIsPaused);
if (!bIsPaused) // Game is now paused
{
ShowPauseMenu();
}
else // Game is now unpaused
{
RemovePauseMenu();
}
}
}
void AMyPlayerController::ShowPauseMenu()
{
if (PauseMenuWidgetClass)
{
PauseMenuWidgetInstance = CreateWidget<UUserWidget>(GetWorld(), PauseMenuWidgetClass);
if (PauseMenuWidgetInstance)
{
PauseMenuWidgetInstance->AddToViewport(999);
// Set input mode to Game and UI
FInputModeGameAndUI InputMode;
InputMode.SetWidgetToFocus(PauseMenuWidgetInstance->TakeWidget());
InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
SetInputMode(InputMode);
bShowMouseCursor = true; // Show mouse cursor if needed
PauseMenuWidgetInstance->SetKeyboardFocus(); // Set keyboard focus
UE_LOG(LogTemp, Warning, TEXT("Pause menu shown and input mode set."));
}
}
}
void AMyPlayerController::RemovePauseMenu()
{
if (PauseMenuWidgetInstance && PauseMenuWidgetInstance->IsInViewport())
{
PauseMenuWidgetInstance->RemoveFromParent();
PauseMenuWidgetInstance = nullptr;
// Set input mode back to Game Only
FInputModeGameOnly InputMode;
SetInputMode(InputMode);
bShowMouseCursor = false; // Hide mouse cursor
UE_LOG(LogTemp, Warning, TEXT("Pause menu removed and input mode set to Game Only."));
}
}