게임 프로젝트에서 플레이어 캐릭터가 게임 플레이 중에 파괴되고 다시 월드로 리스폰되어야 하는 경우가 있을 수 있습니다.
In this How-To guide, you will learn how to set up a simple respawn system using the Third Person Template, for a single-player, non-replicated game. You will then be tasked with implementing functionality for the Game Mode class, which will respawn a third-person player character back into your Level. 이 튜토리얼에서는 복제되지 않은 게임을 위한 싱글 플레이어용 3인칭 템플릿을 사용하여 간단한 리스폰 시스템을 설정하는 방법을 배우게 될 것입니다. 그런 다음, 게임 모드 클래스에 기능을 구현합니다. 이 기능은 써드 파티 게임 플레이어 캐릭터를 레벨로 다시 리스폰시킬 것입니다.
여기서는 블루프린트 로 싱글 플레이어 게임의 플레이어 캐릭터를 리스폰하는 법을 배워보겠습니다.
플레이어 리스폰 (싱글 플레이어)
싱글 플레이어 게임에서 플레이어가 죽으면 리스폰하는 데 필요한 절차는 다음과 같습니다.
여기서는 블루프린트 삼인칭 템플릿 프로젝트를 기반으로 하지만, 어떤 프로젝트를 사용해도 됩니다.
-
프로젝트 안에서, 게임 모드 블루프린트를 엽니다 (ThirdPersonGameMode 블루프린트를 사용합니다).
-
그래프에 우클릭 한 다음 Event Begin Play 노드를 추가한 뒤, 다시 우클릭 하고 Get Player Character 노드를 추가합니다.
-
Get Player Character 노드의 Return Value 를 끌어놓고 Cast To ThirdPersonCharacter 노드를 추가한 다음 노드를 연결합니다.
플레이어 캐릭터 블루프린트, 여기서는 ThirdPersonCharacter 로 Cast To (형변환)하고 싶습니다. 그러면 그 블루프린트에 접근 및 On Destroyed 이벤트를 사용하여 플레이어 캐릭터의 사망 시점을 알아내고, 새 플레이어 캐릭터를 스폰시킬 수 있습니다.
-
As ThirdPersonCharacter C 핀을 끌어놓고 Assign On Destroyed 노드를 추가합니다.
-
새로 추가된 OnDestroyed_Event 노드에서 Delay 노드를 추가하고 리스폰 지연 시간을 설정합니다 (옵션).
여기서는 한 이벤트를 다른 블루프린트의 이벤트로 바인딩하고 있습니다. 이를 통해 다른 블루프린트의 이벤트 (ThirdPersonCharacter 의 OnDestroy Event)가 발생하면 이 블루프린트의 이벤트를 발동시킬 수 있습니다. 이를 일컬어 Event Dispatcher (이벤트 디스패처)라 하며, 레벨 블루프린트 와의 통신을 통해 월드에 이벤트가 발생했음을 알리는 데도 사용 가능합니다.
자세한 정보는 이벤트 디스패처 문서를 참고하세요.
-
Delay 노드를 (추가했다면) 끌어놓고 SpawnActorFromClass 노드를 추가한 뒤 Class 드롭다운을 ThirdPersonCharacter 로 설정합니다.
-
트랜스폼 변수를 새로 만들고 Spawn Transform 이라 한 뒤, Spawn Actor 노드의 Spawn Transform 에 연결합니다.
-
그래프에 우클릭 한 다음 Possess 노드를 추가합니다.
컨텍스트에 따라 옵션 체크를 해제해야 메뉴에 노드가 나타날 수 있습니다.
-
Spawn Actor 에서 Return Value 를 Possess 노드의 In Pawn 에 연결한 다음 실행 선을 연결합니다.
-
Possess 노드의 Target 핀을 끌어놓고 Get Player Controller 노드를 추가합니다.
-
Event Begin Play 노드 근처에서, 그래프에 우클릭 한 다음 Custom Event 를 추가하고 이름을 Respawn 이라 합니다.
컨텍스트에 따라 옵션 체크를 해제해야 메뉴에 노드가 나타날 수 있습니다.
-
커스텀 이벤트를 Cast To ThirdPersonCharacter 노드에 연결합니다.
-
Possess 노드를 끌어놓고 Respawn 이벤트를 호출, 전체 그래프 모습은 아래와 비슷할 것입니다.
이미지를 클릭하면 원래 크기로 봅니다.
-
컴파일, 저장 후 블루프린트를 닫습니다.
-
ThirdPersonCharacter 블루프린트를 열고, 그래프에 우클릭 한 다음 Event Begin Play 노드를 추가합니다.
-
다시 우클릭 한 다음 Get Game Mode 노드를 추가한 뒤, 거기서 끌어놓고 Cast To MyGame (아니면 별도의 게임 모드)를 추가합니다.
-
As My Game C 핀을 끌어놓고 Set Spawn Transform 노드를 추가합니다.
-
그래프에 우클릭 한 다음 Get Actor Transform 노드를 추가한 뒤 Set Spawn Transform 노드에 연결합니다.
그러면 게임 시작시 플레이어 위치를 구해 리스폰 위치로 설정합니다.
-
그래프에 우클릭 한 뒤 F Key Event 를 추가하고, Pressed 핀에서 Destroy Actor 노드를 연결합니다.
이는 테스팅 목적으로, F 키를 누르면 킬(액터를 Destory, 소멸)합니다. 보통은 플레이어가 일정량의 생명력을 잃거나 보통 플레이어를 사망에 이르게 할만한 이벤트가 생기면 Destroy Actor 노드를 호출하게 됩니다.
컴파일 후 에디터에서 플레이하면, F 키를 누를 때마다 잠깐 사라진 다음 시작 위치에서 리스폰될 것입니다.
프로젝트 설정
먼저 새로운 삼인칭(Third Person) 템플릿을 생성하고 프로젝트 세팅(Project Settings) 에서 입력 매핑을 설정합니다. 입력 매핑은 플레이어 캐릭터를 위해 생성할 리스폰 함수 기능을 사용할 수 있게 합니다.
-
게임(Games) > 삼인칭(Third Person) > C++ 순서로 새 프로젝트를 생성하고, 프로젝트 이름은 RespawnPlayer 로 짓습니다.
클릭하면 최대 크기로 볼 수 있습니다.
-
편집(Edit) > 프로젝트 세팅(Project Settings) > 엔진(Engine) > 입력(Input) 으로 이동한 후 디테일(Details) 패널의 바인딩(Bindings) 카테고리에서 액션 매핑(Action Mappings) 변수 옆에 있는 추가(+) 버튼을 클릭하여 이름이 Restart 인 새 액션 매핑을 생성합니다.
클릭하면 최대 크기로 볼 수 있습니다.
-
Restart 액션 매핑의 키 값을 R 로 설정합니다.
클릭하면 최대 크기로 볼 수 있습니다.
RespawnPlayerGameMode 클래스 구현
이 예시에서 게임 모드 클래스는 플레이어 캐릭터가 게임플레이 중에 소멸되었을 때 리스폰하는 역할을 합니다. 델리게이트를 사용하여 이 함수 기능을 구현해야 합니다.
-
콘텐츠 브라우저(Content Browser) 에서 C++ 클래스(C++ Classes) 폴더로 이동한 다음 RespawnPlayerGameMode 를 더블클릭하여
RespawnPlayerGameMode.h
파일을 엽니다. -
RespawnPlayerGameMode.h
파일에 있는 라이브러리 include 선언 아래에 다음 코드를 선언합니다.DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);
이 액션은 플레이어 캐릭터가 죽을 때 게임 모드(Game Mode) 클래스가 바인딩할 다이내믹 멀티캐스트 델리게이트 FOnPlayerDiedSignature를 생성합니다.
-
그런 다음 아래의 클래스 선언을 선언합니다.
public: const FOnPlayerDiedSignature& GetOnPlayerDied() const { return OnPlayerDied; } //플레이어의 폰을 스폰 시도. virtual void RestartPlayer(AController* NewPlayer) override; protected: virtual void BeginPlay() override; //플레이어 캐릭터가 죽으면 호출. UFUNCTION() virtual void PlayerDied(ACharacter* Character); //델리게이트를 바인딩할 시그니처. UPROPERTY() FOnPlayerDiedSignature OnPlayerDied;
RestartPlayer는 GameModeBase 클래스 내에 이미 존재하는 메서드입니다. FindPlayerStart로 반환된 위치에 플레이어 폰의 스폰을 시도합니다.
-
RespawnPlayerGameMode.cpp
파일로 이동하여 아래의 클래스 메서드를 구현합니다.void ARespawnPlayerGameMode::BeginPlay() { Super::BeginPlay(); //PlayerDied 델리게이트를 게임 모드의 PlayerDied 함수에 바인딩. if (!OnPlayerDied.IsBound()) { OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied); } } void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer) { Super::RestartPlayer(NewPlayer); } void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character) { //캐릭터의 플레이어 컨트롤러에 대한 레퍼런스 구하기 AController* CharacterController = Character->GetController(); RestartPlayer(CharacterController); }
-
코드를 컴파일합니다.
완성된 코드
RespawnPlayerGameMode.h
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "RespawnPlayerGameMode.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);
UCLASS(minimalapi)
class ARespawnPlayerGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ARespawnPlayerGameMode();
const FOnPlayerDiedSignature& GetOnPlayerDied() const { return OnPlayerDied; }
//플레이어의 폰을 스폰 시도.
virtual void RestartPlayer(AController* NewPlayer) override;
protected:
virtual void BeginPlay() override;
//플레이어 캐릭터가 죽으면 호출.
UFUNCTION()
virtual void PlayerDied(ACharacter* Character);
//델리게이트를 바인딩할 시그니처.
UPROPERTY()
FOnPlayerDiedSignature OnPlayerDied;
};
RespawnPlayerGameMode.cpp
#include "RespawnPlayerGameMode.h"
#include "RespawnPlayerCharacter.h"
#include "UObject/ConstructorHelpers.h"
ARespawnPlayerGameMode::ARespawnPlayerGameMode()
{
// 디폴트 폰 클래스를 블루프린트 캐릭터로 설정
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
}
void ARespawnPlayerGameMode::BeginPlay()
{
Super::BeginPlay();
//PlayerDied 델리게이트를 게임 모드의 PlayerDied 함수에 바인딩.
if (!OnPlayerDied.IsBound())
{
OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied);
}
}
void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer)
{
Super::RestartPlayer(NewPlayer);
}
void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character)
{
//캐릭터의 플레이어 컨트롤러에 대한 레퍼런스 구하기
AController* CharacterController = Character->GetController();
RestartPlayer(CharacterController);
}
RespawnPlayerCharacter 구현
이제 RespawnPlayerCharacter를 소멸시키고 RespawnPlayerGameMode
의 클래스를 통해 리스폰을 구현해야 합니다.
-
콘텐츠 브라우저(Content Browser) 에서 C++ 클래스(C++ Classes) 폴더로 이동한 다음 RespawnPlayerCharacter 를 더블클릭하여
RespawnPlayerCharacter.h
파일을 엽니다. -
RespawnPlayerCharacter.h
파일 내에 다음 코드를 선언합니다.protected: //게임플레이 중 액터가 소멸되었을 때 호출. virtual void Destroyed(); //플레이어 캐릭터를 재시작할 게임 모드 클래스 호출. void CallRestartPlayer();
이 선언에서 소멸된 메서드는
virtual
로 표시됩니다. 캐릭터 클래스가 소멸된 메서드를 가진 액터 클래스로부터 상속받기 때문입니다. -
RespawnPlayerCharacter.cpp
파일로 이동하여 아래의 클래스 라이브러리 include를 선언합니다.#include "RespawnPlayerGameMode.h"
나중에 플레이어 캐릭터 클래스에서 클래스 함수 기능을 호출하기 위한 게임 모드 라이브러리 선언을 포함해야 합니다.
-
그리고 다음
RespawnPlayerCharacter
클래스 메서드를 추가합니다.void ARespawnPlayerCharacter::Destroyed() { Super::Destroyed(); //게임 모드에서 OnPlayerDied 이벤트에 바인딩한 예 if (UWorld* World = GetWorld()) { if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode())) { GameMode->GetOnPlayerDied().Broadcast(this); } } } void ARespawnPlayerCharacter::CallRestartPlayer() { //폰 컨트롤러에 대한 레퍼런스 구하기 AController* CortollerRef = GetController(); //플레이어 소멸. Destroy(); //월드와 월드의 게임 모드가 RestartPlayer 함수를 호출하도록 함. if (UWorld* World = GetWorld()) { if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode())) { GameMode->RestartPlayer(CortollerRef); } } }
R 을 누르면
CallRestartPlayer
함수가 플레이어 캐릭터를 소멸시키고 호출됩니다.Destroy
메서드는 게임플레이 이벤트에서 플레이어가 일정량 이상의 체력을 잃어 플레이어 캐릭터가 디스폰될 때 주로 호출됩니다. -
SetupPlayerInputComponent
메서드로 이동하여 다음 코드를 선언합니다.void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) { //입력 키 액션이 RestartPlayer를 호출하도록 설정. PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer); }
-
코드를 컴파일합니다.
완성된 코드
RespawnPlayerCharacter.h
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "RespawnPlayerCharacter.generated.h"
UCLASS(config=Game)
class ARespawnPlayerCharacter : public ACharacter
{
GENERATED_BODY()
/** 캐릭터 뒤에 카메라를 배치하는 카메라 붐 */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** 카메라 따라가기 */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
public:
ARespawnPlayerCharacter();
/** 베이스 회전 속도, 단위는 도(º)/초. 다른 스케일 값 조절로 인해 최종 회전 속도가 영향을 받을 수 있습니다. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Input)
float TurnRateGamepad;
protected:
/** 앞뒤 입력으로 호출 */
void MoveForward(float Value);
/** 좌우 입력으로 호출 */
void MoveRight(float Value);
/**
* 입력을 통해 호출되어 지정된 속도로 회전
* @param Rate 정규화된 비율이며, 1.0인 경우 지정된 회전 속도의 100%를 의미합니다.
*/
void TurnAtRate(float Rate);
/**
* 입력을 통해 호출되어 지정된 속도로 올려다보기/내려다보기
* @param Rate 정규화된 비율이며, 1.0인 경우 지정된 회전 속도의 100%를 의미합니다.
*/
void LookUpAtRate(float Rate);
/** 터치 입력 시작 시 핸들러 */
void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
/** 터치 입력 중지 시 핸들러 */
void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
protected:
// APawn 인터페이스
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// APawn 인터페이스 종료
public:
/** CameraBoom 서브오브젝트 반환 **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** FollowCamera 서브오브젝트 반환 **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
protected:
//게임플레이 중 액터가 소멸되었을 때 호출.
virtual void Destroyed();
//플레이어 캐릭터를 재시작할 게임 모드 클래스 호출.
void CallRestartPlayer();
};
RespawnPlayer.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "RespawnPlayerTestCharacter.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "RespawnPlayerTestGameMode.h"
//////////////////////////////////////////////////////////////////////////
// ARespawnPlayerCharacter
ARespawnPlayerCharacter::ARespawnPlayerCharacter()
{
// 콜리전 캡슐 크기 설정
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// 입력에 대한 회전 속도 설정
TurnRateGamepad = 50.f;
// 컨트롤러 회전 시 회전하지 않습니다. 카메라에만 영향을 미치도록 합니다.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// 캐릭터 무브먼트 환경설정
GetCharacterMovement()->bOrientRotationToMovement = true; // 캐릭터가 입력 방향으로 이동
GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // 위의 캐릭터가 이동하는 회전 속도
// 참고: 이 변수를 비롯한 많은 변수는 조정하기 위해 다시 컴파일하지 않고도
// 캐릭터 블루프린트에서 미세조정하여 반복작업 시간을 단축할 수 있습니다.
GetCharacterMovement()->JumpZVelocity = 700.f;
GetCharacterMovement()->AirControl = 0.35f;
GetCharacterMovement()->MaxWalkSpeed = 500.f;
GetCharacterMovement()->MinAnalogWalkSpeed = 20.f;
GetCharacterMovement()->BrakingDecelerationWalking = 2000.f;
// 카메라 붐 생성(콜리전 있을 시 플레이어 쪽으로 들어옴)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 400.0f; // 캐릭터 뒤의 카메라가 이 거리에서 따라옴
CameraBoom->bUsePawnControlRotation = true; // 컨트롤러 기반으로 암 회전
// 카메라 따라가기 생성
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // 카메라를 붐 끝에 어태치하여 붐이 컨트롤러 오리엔테이션에 맞추어 조절되도록 함
FollowCamera->bUsePawnControlRotation = false; // 카메라가 암 기준으로 회전하지 않음
// 참고: 캐릭터로부터 상속받는 메시 컴포넌트에 대한 스켈레탈 메시와 애님 블루프린트 레퍼런스는
// C++ 직접 콘텐츠 레퍼런스를 방지하기 위해 이름이 ThirdPersonCharacter인 파생 블루프린트 에셋에서 설정됨
}
//////////////////////////////////////////////////////////////////////////
// 입력
void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// 게임플레이 키 바인딩 설정
check(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("Move Forward / Backward", this, &ARespawnPlayerCharacter::MoveForward);
PlayerInputComponent->BindAxis("Move Right / Left", this, &ARespawnPlayerCharacter::MoveRight);
// 2가지 버전의 회전 바인딩이 있어 서로 다른 종류의 디바이스를 다양한 방식으로 처리할 수 있습니다.
// 'turn'은 마우스와 같은 절대 델타를 제공하는 디바이스를 처리합니다.
// 'turnrate'는 아날로그 조이스틱과 같이 변화의 속도를 취급할 디바이스에 사용합니다.
PlayerInputComponent->BindAxis("Turn Right / Left Mouse", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("Turn Right / Left Gamepad", this, &ARespawnPlayerCharacter::TurnAtRate);
PlayerInputComponent->BindAxis("Look Up / Down Mouse", this, &APawn::AddControllerPitchInput);
PlayerInputComponent->BindAxis("Look Up / Down Gamepad", this, &ARespawnPlayerCharacter::LookUpAtRate);
// 터치 디바이스 처리
PlayerInputComponent->BindTouch(IE_Pressed, this, &ARespawnPlayerCharacter::TouchStarted);
PlayerInputComponent->BindTouch(IE_Released, this, &ARespawnPlayerCharacter::TouchStopped);
//입력 키 액션이 RestartPlayer를 호출하도록 설정.
PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer);
}
void ARespawnPlayerCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
Jump();
}
void ARespawnPlayerCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
StopJumping();
}
void ARespawnPlayerCharacter::TurnAtRate(float Rate)
{
// 속도 정보로부터 이 프레임에 대한 델타 계산
AddControllerYawInput(Rate * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}
void ARespawnPlayerCharacter::LookUpAtRate(float Rate)
{
// 속도 정보로부터 이 프레임에 대한 델타 계산
AddControllerPitchInput(Rate * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}
void ARespawnPlayerCharacter::MoveForward(float Value)
{
if ((Controller != nullptr) && (Value != 0.0f))
{
// 앞쪽 찾기
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// 앞쪽 벡터 구하기
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
}
void ARespawnPlayerCharacter::MoveRight(float Value)
{
if ( (Controller != nullptr) && (Value != 0.0f) )
{
// 오른쪽 찾기
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// 오른쪽 벡터 구하기
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// 해당 방향으로 이동 추가
AddMovementInput(Direction, Value);
}
}
void ARespawnPlayerCharacter::Destroyed()
{
Super::Destroyed();
//게임 모드에서 OnPlayerDied 이벤트에 바인딩한 예
if (UWorld* World = GetWorld())
{
if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
{
GameMode->GetOnPlayerDied().Broadcast(this);
}
}
}
void ARespawnPlayerCharacter::CallRestartPlayer()
{
//폰 컨트롤러에 대한 레퍼런스 구하기
AController* CortollerRef = GetController();
//플레이어 소멸.
Destroy();
//월드와 월드의 게임 모드가 RestartPlayer 함수를 호출하도록 함.
if (UWorld* World = GetWorld())
{
if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))
{
GameMode->RestartPlayer(CortollerRef);
}
}
}
최종 결과물
에디터로 돌아가서 에디터에서 플레이(Play in Editor, PIE) 를 클릭합니다.
맵에서 W , A , S , D 로 캐릭터 이동을 제어할 수 있습니다.
R 을 누르면 플레이어 캐릭터가 소멸되어 잠깐 사라졌다가 플레이어 시작 위치(Player Start Location) 에서 리스폰됩니다.