이번에는 게임오버 UI, Restart 버튼, Quit 버튼의 기능을 C++로 만들어보았다.
#pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "GameOverWidget.generated.h" UCLASS() class MYSHOOTINGCPP_API UGameOverWidget : public UUserWidget { GENERATED_BODY() public: virtual void NativeConstruct() override; // BeginPlay()처럼 사용 UPROPERTY(EditAnywhere, meta = (BindWidget)) class UButton* Button_Restart; UPROPERTY(EditAnywhere, meta = (BindWidget)) class UButton* Button_Quit; UFUNCTION() void OnRestart(); UFUNCTION() void OnQuit(); };
#include "GameOverWidget.h" #include <Kismet/GameplayStatics.h> #include <Components/Button.h> #include <Kismet/KismetSystemLibrary.h> void UGameOverWidget::NativeConstruct() { Super::NativeConstruct(); // 함수 바인딩 Button_Restart->OnClicked.AddDynamic(this, &UGameOverWidget::OnRestart); Button_Quit->OnClicked.AddDynamic(this, &UGameOverWidget::OnQuit); } void UGameOverWidget::OnRestart() { FString levelName = UGameplayStatics::GetCurrentLevelName(GetWorld()); UGameplayStatics::OpenLevel(GetWorld(), FName(*levelName)); } void UGameOverWidget::OnQuit() { UKismetSystemLibrary::QuitGame(GetWorld(), GetWorld()->GetFirstPlayerController(), EQuitPreference::Quit, false); }
#pragma once #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "MyShootingCppGameModeBase.generated.h" UCLASS() class MYSHOOTINGCPP_API AMyShootingCppGameModeBase : public AGameModeBase { GENERATED_BODY() protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: int score = 0; void AddScore(int value); UPROPERTY(EditAnywhere) TSubclassOf<class UScoreWidget> scoreWidgetFactory; class UScoreWidget* scoreWidget; UPROPERTY(EditAnywhere) TSubclassOf<class UGameOverWidget> gameOverWidgetFactory; // 생성할 위젯의 설계도 class UGameOverWidget* gameOverWidget; // 위젯을 담아둘 그릇 void ShowGameOverUI(); };
#include "MyShootingCppGameModeBase.h" #include <Blueprint/UserWidget.h> #include "ScoreWidget.h" #include <Components/TextBlock.h> #include "GameOverWidget.h" void AMyShootingCppGameModeBase::BeginPlay() { scoreWidget = CreateWidget<UScoreWidget>(GetWorld(), scoreWidgetFactory); scoreWidget->AddToViewport(); // 게임오버 위젯을 미리 만들어둔다 (아직 화면에 띄우지는 않음) gameOverWidget = CreateWidget<UGameOverWidget>(GetWorld(), gameOverWidgetFactory); // 마우스 커서를 숨기고, 입력 모드를 GameOnly로 GetWorld()->GetFirstPlayerController()->SetShowMouseCursor(false); GetWorld()->GetFirstPlayerController()->SetInputMode(FInputModeGameOnly()); } void AMyShootingCppGameModeBase::AddScore(int value) { score = score + value; scoreWidget->TextBlock_Score->SetText(FText::AsNumber(score)); } void AMyShootingCppGameModeBase::ShowGameOverUI() { // 게임오버 위젯을 화면에 띄운다 gameOverWidget->AddToViewport(); // 마우스 커서를 띄우고, 입력 모드를 UIOnly로 GetWorld()->GetFirstPlayerController()->SetShowMouseCursor(true); GetWorld()->GetFirstPlayerController()->SetInputMode(FInputModeUIOnly()); // 일시정지 GetWorld()->GetFirstPlayerController()->SetPause(true); }
void APlayerPawn::OnAttacked(int damage) { currentHp -= damage; OnUpdateHealth(currentHp); if (currentHp <= 0) { // 게임모드를 가져와서 게임오버 UI 띄우는 함수를 호출 auto gameMode = Cast<AMyShootingCppGameModeBase>(GetWorld()->GetAuthGameMode()); gameMode->ShowGameOverUI(); this->Destroy(); } }