게임 안에서 ESC 누르면 오디오, 그래픽 설정할 수 있는 정지메뉴 만들기
- Setting (Audio (+ PlayerVolume), Graphics)
- Continue
- MainMenu (-> ConfirmationDialogue)

위젯은 CommonActivatableWidget / 버튼은 CommonButtonBase로 만들기
Setting 안에는 ChangePanel로 만들어야하니까
기존 MainMenu에서 썼던 WBP_Audio, WBP_Graphics 가져오기

함수 안 만들면 Setting 눌러도 OptionPanel이 안 나온다!


void HandleMainMenuConfirmed(bool bYes);
C++ 먼저 만들기

UITags.h 와 UITags.cpp 에서 Request와 Layer 설정하기



에디터 설정을 계속해도 ESC 누르면 자꾸 PIE 정지로 연결돼서 임시로 P
키에 연결
// LNCharacter.h
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "LN|Input")
TObjectPtr<UInputAction> PauseAction; // ESC 키 Input Action
void OnPauseInput(const FInputActionValue& Value); // 일시정지 입력 처리 함수
// LNCharacter.cpp
void ALNCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (Controller && Controller->IsLocalController())
{
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
// ...
EnhancedInputComponent->BindAction(PauseAction, ETriggerEvent::Started, this, &ThisClass::OnPauseInput);
}
}
}
void ALNCharacter::OnPauseInput(const FInputActionValue& Value)
{
if (UGameInstance* GI = GetGameInstance())
{
if (ULNUIManageSubsystem* UIManager = GI->GetSubsystem<ULNUIManageSubsystem>())
{
static FGameplayTag OverlayLayer = FGameplayTag::RequestGameplayTag(TEXT("UI.Layer.Overlay"));
UCommonActivatableWidget* ActiveWidget = UIManager->GetActiveWidgetFromLayer(OverlayLayer);
if (ActiveWidget)
{
return;
}
static FGameplayTag PauseRequestTag = FGameplayTag::RequestGameplayTag(TEXT("UI.Request.PauseMenu"));
UIManager->ShowWidget(PauseRequestTag);
if (APlayerController* PC = Cast<APlayerController>(GetController()))
{
UIManager->SetInputModeUIOnly(PC);
}
}
}
}
캐릭터 블루프린트 디테일 창에서 IA_Input 할당하기

// PauseMenuWidget.h
protected:
virtual void NativeOnActivated() override;
virtual void NativeOnDeactivated() override;
ULNUIManageSubsystem* GetUIManager() const;
UFUNCTION(BlueprintCallable, Category = "LN|UI|Pause")
void HandleMainMenuConfirmed(bool bYes);
// PauseMenuWidget.cpp
#include "UI/Subsystem/LNUIManageSubsystem.h"
#include "Kismet/GameplayStatics.h"
void UPauseMenuWidget::NativeOnActivated()
{
Super::NativeOnActivated();
SetVisibility(ESlateVisibility::Visible);
if (UWorld* World = GetWorld())
{
APlayerController* PC = GetOwningPlayer();
if (!PC)
{
return;
}
if (ULNUIManageSubsystem* UIManager = GetUIManager())
{
UIManager->SetInputModeUIOnly(PC, this, false);
}
UGameplayStatics::SetGamePaused(World, true);
}
}
void UPauseMenuWidget::NativeOnDeactivated()
{
Super::NativeOnDeactivated();
SetVisibility(ESlateVisibility::Collapsed);
if (UWorld* World = GetWorld())
{
APlayerController* PC = GetOwningPlayer();
if (!PC)
{
return;
}
if (ULNUIManageSubsystem* UIManager = GetUIManager())
{
UIManager->SetInputModeGameOnly(PC);
}
UGameplayStatics::SetGamePaused(World, false);
}
}
ULNUIManageSubsystem* UPauseMenuWidget::GetUIManager() const
{
if (UGameInstance* GI = GetGameInstance())
{
return GI->GetSubsystem<ULNUIManageSubsystem>();
}
return nullptr;
}
void UPauseMenuWidget::HandleMainMenuConfirmed(bool bYes)
{
if (!bYes)
{
return;
}
if (UGameInstance* GI = GetGameInstance())
{
if (ULNUIManageSubsystem* UIManager = GI->GetSubsystem<ULNUIManageSubsystem>())
{
DeactivateWidget();
static FGameplayTag MainMenuTag = FGameplayTag::RequestGameplayTag("UI.Request.MainMenu");
UIManager->ShowWidget(MainMenuTag);
}
}
UGameplayStatics::OpenLevel(this, FName("LV_MainMenu"));
}
P → ESC Is Back Handler : True로 체크Display in Action Bar : True로 체크하면 하단 액션바에 "돌아가기" 표시됨