
1. Resume 버튼 = Resume_BTN
SetPause(false)PauseMenuWidgetInstance->RemoveFromParent();SetInputMode(FInputModeGameOnly())2. BackToMainMenu 버튼 = Return_BTN
OpenLevel("MainMenuLevel") 호출3. PauseMenuWidget - PlayerController에 연결
C++ 클래스를 먼저 만들고 블루프린트로 만들어야 하는데 블루프린트 먼저 만들었다
그래서 C++ 클래스 만들어준다.

File → New C++ Class 클릭
부모 클래스로 UserWidget 선택
클래스 이름은 PauseMenuWidget으로 입력
// PauseMenuWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/Button.h"
#include "PauseMenuWidget.generated.h"
/**
* @class UPauseMenuWidget
* @brief 게임의 일시 정지 메뉴를 관리하는 위젯 클래스입니다.
* by Team4 (yeoul)
*/
UCLASS()
class PPP_API UPauseMenuWidget : public UUserWidget
{
GENERATED_BODY()
protected:
virtual void NativeConstruct() override;
UPROPERTY(meta = (BindWidget))
UButton* Resume_BTN;
UPROPERTY(meta = (BindWidget))
UButton* Return_BTN;
UFUNCTION()
void OnResumeClicked();
UFUNCTION()
void OnReturnClicked();
};
// PauseMenuWidget.cpp
#include "PauseMenuWidget.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
#include "../Characters/PppPlayerController.h"
void UPauseMenuWidget::NativeConstruct()
{
// 부모 함수 먼저 호출
// 이 위젯이 만들어질 때 버튼을 눌렀을 때 호출할 이벤트 연결
Super::NativeConstruct();
if (Resume_BTN)
{
Resume_BTN->OnClicked.AddDynamic(this, &UPauseMenuWidget::OnResumeClicked);
}
if (Return_BTN)
{
Return_BTN->OnClicked.AddDynamic(this, &UPauseMenuWidget::OnReturnClicked);
}
}
void UPauseMenuWidget::OnResumeClicked()
{
UE_LOG(LogTemp, Log, TEXT("Resume Clicked"));
if (APppPlayerController* PC = Cast<APppPlayerController>(UGameplayStatics::GetPlayerController(this, 0)))
{
PC->SetPause(false); // 게임 재개
PC->bShowMouseCursor = false;
PC->SetInputMode(FInputModeGameOnly());
this->RemoveFromParent(); // 정지 UI 닫기
}
}
void UPauseMenuWidget::OnReturnClicked()
{
if (APppPlayerController* PC = Cast<APppPlayerController>(UGameplayStatics::GetPlayerController(this, 0)))
{
PC->ShowMainMenu(true); // MainMenu로 복귀
}
UE_LOG(LogTemp, Log, TEXT("Return Clicked"));
}
만들어뒀던 블루프린트 위젯의 부모를 C++ 클래스로 설정해준다.
콘텐츠 브라우저에서 MainMenuWidget_BP 우클릭
Asset Actions → Create Blueprint class based on this ← 이거 아님!!
아니면 그냥 우클릭 하고 “Edit Blueprint Options” 또는 “Reparent Blueprint” 선택
💡 "Reparent Blueprint" 메뉴 안 보이면 에디터 상단 메뉴바
→ Window > Developer Tools > Class Viewer 켜고 거기서 직접 설정 가능
MainMenuWidget_BP 열기
상단 메뉴에서 Class Settings 클릭
우측 Details 패널 아래로 내리고 “Parent Class”에 직접 UMainMenuWidget 입력
Input Action :
PauseMenuAction → P 키에 매핑됨
IMC :
IMC_PauseMenu → PauseMenuAction 포함
❗나중에 캐릭터의 IMC로 이동❗
Input 등록 위치 :
PlayerController의 BeginPlay() 나 SetupInputComponent()
UI 표시 :
PauseMenuWidgetClass로 CreateWidget + AddToViewport
💡 Input Mode 전환 (UIOnly <-> GameOnly) 꼭 해줘야 메뉴 상태가 잘 전환됨
// PlayerController.h
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI")
TSubclassOf<UUserWidget> PauseMenuWidgetClass;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UI")
UUserWidget* PauseMenuWidgetInstance;
UFUNCTION(BlueprintCallable, Category = "UI")
void ShowPauseMenu();
private:
UFUNCTION()
void HandlePauseKey();
// PlayerController.cpp
void APppPlayerController::BeginPlay()
{
Super::BeginPlay();
EnableInput(this); // ESC나 메뉴 입력용
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
if (UEnhancedInputLocalPlayerSubsystem* SubSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
if (PauseMenuIMC)
{
SubSystem->AddMappingContext(PauseMenuIMC, 0);
UE_LOG(LogTemp, Warning, TEXT("PauseMenuIMC 등록 완료"));
}
if (PauseMenuIMC)
{
SubSystem->AddMappingContext(PauseMenuIMC, 0);
UE_LOG(LogTemp, Warning, TEXT("PauseMenuIMC 등록 완료: %s"), *PauseMenuIMC->GetName());
}
else
{
UE_LOG(LogTemp, Error, TEXT("PauseMenuIMC가 NULL입니다!"));
}
}
}
void APppPlayerController::ShowPauseMenu()
{
if (PauseMenuWidgetInstance)
{
PauseMenuWidgetInstance->RemoveFromParent();
PauseMenuWidgetInstance = nullptr;
}
if (PauseMenuWidgetClass)
{
PauseMenuWidgetInstance = CreateWidget<UUserWidget>(this, PauseMenuWidgetClass);
if (PauseMenuWidgetInstance)
{
PauseMenuWidgetInstance->AddToViewport();
PauseMenuWidgetInstance->SetIsFocusable(false);
FInputModeGameAndUI InputMode;
InputMode.SetWidgetToFocus(PauseMenuWidgetInstance->TakeWidget());
InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
SetInputMode(InputMode);
bShowMouseCursor = true;
}
}
if (!IsPaused())
{
SetPause(true);
}
}
void APppPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(InputComponent))
{
if (PauseMenuAction)
{
EnhancedInput->BindAction(PauseMenuAction, ETriggerEvent::Started, this, &APppPlayerController::HandlePauseKey);
}
}
}
void APppPlayerController::HandlePauseKey()
{
ShowPauseMenu();
}
EnhancedInputComponent → PauseMenuAction → HandlePauseKey()로 처리
ESC 키로 입력하면 에디터 실행창이 꺼져서 P 키로 변경했음