언리얼 게임 종료 구현하기 c++

250x250

언리얼 게임 종료 구현하기 c++

게임을 하다 보면 반드시 있어야 할 것 중 하나가 종료 버튼입니다.

이 글에서는 모든 게임에서 필수적인 요소인 게임 종료를 언리얼엔진의 'UKismetSystemLibrary'에서 제공하는 'QuitGame'함수를 사용해 c++에서 게임 종료를 구현해 보겠습니다. 

UKismetSystemLibrary.

'UKismetSystemLibrary'클래스는 게임 플레이, 하드웨어 정보, 월드 관리 등 다양한 시스템 관련 기능을 제공하는 유틸리티 클래스입니다. 이 클래스를 통해 언리얼 엔진에서 게임 종료(QuitGame), 타이머 설정(Delay), 객체 유효성 검사(IsValid), 디버그 메시지(PrintString) 등 여러 작업을 손쉽게 처리할 수 있습니다.

이 클래스는 주로 블루프린트에서 사용되던 기능을 C++ 코드에서도 쉽게 사용할 수 있도록 도와줍니다.

UKismetSystemLibrary::QuitGame 함수.

'UKismetSystemLibrary'클래스는 다양한 기능을 제공하지만, 이번 글에서는 게임을 종료하는 데 사용되는 'QuitGame'함수에 집중하겠습니다.

아래 코드는 'UKismetSystemLibary'클래스에서 'QuitGame'함수만 가져왔습니다.

void UKismetSystemLibrary::QuitGame(const UObject* WorldContextObject, class APlayerController* SpecificPlayer, TEnumAsByte<EQuitPreference::Type> QuitPreference, bool bIgnorePlatformRestrictions)
{
	APlayerController* TargetPC = SpecificPlayer ? SpecificPlayer : UGameplayStatics::GetPlayerController(WorldContextObject, 0);
	if( TargetPC )
	{
		if ( QuitPreference == EQuitPreference::Background)
		{
			TargetPC->ConsoleCommand("quit background");
		}
		else
		{
			if (bIgnorePlatformRestrictions)
			{
				TargetPC->ConsoleCommand("quit force");
			}
			else
			{
				TargetPC->ConsoleCommand("quit");
			}
		}
	}
}

'QuitGame' 함수의 주요 매개변수에 대한 설명.

1. WorldContextObejct : 함수가 실행될 월드 정보를 제공하며, 일반적으로 GetWorld()를 사용합니다

2. SpecificPlayer : 종료할 플레이어 컨트롤러를 지정할 대 사용합니다.

3. QuitPreference : 게임 종료할지 또는 백그라운드로 전환할지 결정합니다.

4. bIgnorePlatformRestrictions : 'true'로 설정하면 플랫폼 제한을 무시하고 게임을 강제로 종료합니다. 'false'로 설정하면 플랫폼 제약을 따르고 일반적인 종료 절차를 수행합니다.

게임 종료 예제.

아래 InputMappingContext를 보면 아시겠지만 Space Bar를 누르면 게임이 종료되도록 만들었습니다.

Pawn.h (헤더 파일)

아래는 'UKismetSystemLibrary::QuitGame' 함수를 사용하여 게임을 종료하도록 구현한 예제코드의 헤더파일입니다.

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "GameTestCharacter.generated.h"

class UInputAction;
class UInputMappingContext;
class UCameraComponent;
UCLASS()
class MINIGAME_API AGameTestCharacter : public ACharacter
{
	GENERATED_BODY()

protected:
	AGameTestCharacter();
	virtual void BeginPlay() override;
	virtual void Tick(float DeltaTime) override;
	
	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<UStaticMeshComponent> BodyMesh;
	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<UCameraComponent> MainCamera;
#pragma region ExitGame
public:
protected:
	UPROPERTY()
	TObjectPtr<UInputMappingContext> ExitTestContext;
	UPROPERTY()
	TObjectPtr<UInputAction> ExitAction;
private:
	void ExitGame();
#pragma endregion
};
Pawn.cpp (소스 파일)

UKismetSystemLibrary::QuitGame(GetWorld(), nullptrEQuitPreference::Quitfalse);

매개변수 1.  'GetWorld()'를 사용해 현재 월드에서 게임 종료하도록 했습니다.

매개변수 2.  'nullptr'을 선택했습니다. 모든 플레이어에게 적용됩니다.

(UGameplayStatics::GetPlayerController(WorldContextObject, 0)을 통해 얻을 수 있는 첫 번째 플레이어 컨트롤러)

매개변수 3. 게임을 즉시 종료하기 위해 EQuitPreference::Quit를 선택했습니다.

매개변수 4. 일반적인 종료가 되도록 false를 선택했습니다.

// Fill out your copyright notice in the Description page of Project Settings.

#include "Character/GameTestCharacter.h"
//input
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputAction.h"
#include "InputMappingContext.h"
//Camera
#include "Camera\CameraComponent.h"
#include "Camera\CameraActor.h"
//유틸리티
#include "Kismet\KismetSystemLibrary.h"

#include "Kismet\GameplayStatics.h"

// Sets default values
AGameTestCharacter::AGameTestCharacter():bToggleCam(1)
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
	BodyMesh->SetupAttachment(GetRootComponent());
	SetRootComponent(BodyMesh);
	//메인 카메라.
	MainCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MainCam"));
	MainCamera->SetupAttachment(GetRootComponent());
	//InputSettings
	static ConstructorHelpers::FObjectFinder<UInputMappingContext> FIndTestMappingContext(TEXT("InputMappingContext'/Game/Blueprints/Input/IMC_Test.IMC_Test'"));
	if (FIndTestMappingContext.Succeeded()) {
		ExitTestContext = FIndTestMappingContext.Object;
	}
	static ConstructorHelpers::FObjectFinder<UInputAction> FindTestAction(TEXT("InputAction'/Game/Blueprints/Input/InputAction/Test/IA_TestSpace.IA_TestSpace'"));
	if (FindTestAction.Succeeded()) {
		ExitAction = FindTestAction.Object;
	}
}
// Called when the game starts or when spawned
void AGameTestCharacter::BeginPlay()
{
	Super::BeginPlay();
	UEnhancedInputLocalPlayerSubsystem* SubSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetWorld()->GetFirstPlayerController()->GetLocalPlayer());
	if (IsValid(SubSystem)) {
		SubSystem->AddMappingContext(ExitTestContext, 0);
	}
	//시작하고 화면을 클릭하지 않아도 키보드 동작이 가능하도록.
	FInputModeGameOnly InputMode;
	GetWorld()->GetFirstPlayerController()->SetInputMode(InputMode);
}
// Called every frame
void AGameTestCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void AGameTestCharacter::ExitGame()
{
	UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}
// Called to bind functionality to input
void AGameTestCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	if (IsValid( EnhancedInputComponent)) {
		EnhancedInputComponent->BindAction(ExitAction, ETriggerEvent::Started, this, &AGameTestCharacter::ExitGame);
	}
}

UI부분도 붙여서 같이 올릴까 했는데 어차피 사용 방법 자체는 똑같아서 빼고 올렸습니다.

그래서 그냥 UI사용하는 부분은 나중에 따로 올릴 예정입니다.

Designed by JB FACTORY