언리얼 C++ 게임 개발의 정석/13. 게임 플레이 제작
13.3 게임 데이터의 관리
ftftgop3
2024. 5. 23. 21:31
새로운 레벨 추가
Gameplay 새로운 레벨 제작 후 네비게이션 크기를 x :100000, y : 100000 확장
게임 스코어
처음에 0으로 시작 NPC를 죽이면 1 상승
현재 프로젝트는 싱글 플레이 게임으로 플레이어 스테이트에 추가 하면 되지만
멀티 플레이를 고려해 게임 스테이트를 이용
ABGameState 생성
스코어 점수 변수 추가 후 데이터 관리
UCLASS()
class ARENABATTLE_API AABGameState : public AGameStateBase
{
GENERATED_BODY()
public:
AABGameState();
public:
//도탈 점수 리턴
int32 GetTotalGameScore() const;
//점수 추가
void AddGameScore();
private:
//점수
UPROPERTY(Transient)
int32 TotalGameScore;
};
#include "ABGameState.h"
AABGameState::AABGameState()
{
TotalGameScore = 0;
}
int32 AABGameState::GetTotalGameScore() const
{
return TotalGameScore;
}
void AABGameState::AddGameScore()
{
TotalGameScore++;
}
Gamemode에 현재 게임 상태로 지정
#include "ABGameState.h"
AABGameMode::AABGameMode()
{
DefaultPawnClass = AABCharacter::StaticClass();
PlayerControllerClass = AABPlayerController::StaticClass();
//플레이어 스테이트 지정
PlayerStateClass = AABPlayerState::StaticClass();
GameStateClass = AABGameState::StaticClass();
}
Section
NPC 사망 시 Secion의 상태를 Complete 변경
NPC 제거 시 마지막에 대미지를 입힌 컨트롤러의 기록은 LastHitBy 속성에 저장
UCLASS()
class ARENABATTLE_API AABSection : public AActor
{
GENERATED_BODY()
private:
//NCP 사망 시 실행 하는 델리게이트 함수에 등록
UFUNCTION()
void OnKeyNPCDestroyed(AActor* DestroyedActor);
}
void AABSection::OnNPCSpawn()
{
//생성 핸들러 초기화
GetWorld()->GetTimerManager().ClearTimer(SpawnNPCTimerHandle);
//현재 섹션의 중앙의 Y 값 88 위치에서 생성
auto KeyNPC = GetWorld()->SpawnActor<AABCharacter>(GetActorLocation() + FVector::UpVector * 88.0f, FRotator::ZeroRotator);
if (nullptr != KeyNPC)
{
//npc 객체 파괴 시 실행하는 델리게이트에 함수 등록
KeyNPC->OnDestroyed.AddDynamic(this, &AABSection::OnKeyNPCDestroyed);
}
}
void AABSection::OnKeyNPCDestroyed(AActor * DestroyedActor)
{
//파괴된 엑터가 캐릭터 객체이면 LastHitBy 플레이어일 경우 COMPLETE 변경
auto ABCharacter = Cast<AABCharacter>(DestroyedActor);
ABCHECK(nullptr != ABCharacter);
auto ABPlayerController = Cast<AABPlayerController>(ABCharacter->LastHitBy);
ABCHECK(nullptr != ABPlayerController);
SetState(ESectionState::COMPLETE);
}
ABPlayState
플레이어의 점수 증가 기능 구현
UCLASS()
class ARENABATTLE_API AABPlayerState : public APlayerState
{
GENERATED_BODY()
public:
//게임 스코어 값 증가
void AddGameScore();
}
void AABPlayerState::AddGameScore()
{
//스코어 증가
GameScore++;
//Playstate 업데이트
OnPlayerStateChanged.Broadcast();
}
ABPlayerController
컨트롤러에서 ABPlayState 접근해 AddGameScore 함수 호출
UCLASS()
class ARENABATTLE_API AABPlayerController : public APlayerController
{
GENERATED_BODY()
public:
//스코어 점수 증가
void AddGameScore() const;
}
//현재 스테이트에서 점수 증가
void AABPlayerController::AddGameScore() const
{
ABPlayerState->AddGameScore();
}
GameMode 전체 스코어 점수 기능 추가
마지막 피격을 가한 플레이어 컨트롤러 정보를 가지고
NPC를 죽인 컨트롤러와 동일한 컨트롤러 검색 해 스코어 증가
전체 스코어 증가 기능 추가
UCLASS()
class ARENABATTLE_API AABGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
AABGameMode();
virtual void PostLogin(APlayerController* NewPlayer) override;
//게임 스테이트 변수에 지정
virtual void PostInitializeComponents() override;
//게임 전체 스코어 증가
void AddScore(class AABPlayerController *ScoredPlayer);
private:
UPROPERTY()
class AABGameState* ABGameState;
};
//ABGameState 변수에 지정
void AABGameMode::PostInitializeComponents()
{
Super::PostInitializeComponents();
ABGameState = Cast<AABGameState>(GameState);
}
//NPC를 죽인 컨트롤러를 매개변수로 검색 해 해당 컨트롤러의 플레이어 스코어 증가
void AABGameMode::AddScore(AABPlayerController* ScoredPlayer)
{
//현재 월드에 있는 모든 플레이어 컨트롤러에 동작
for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It)
{
const auto ABPlayerController = Cast<AABPlayerController>(It->Get());
if ((nullptr != ABPlayerController) && (ScoredPlayer == ABPlayerController))
{
//현재 매개변수로 받은 컨트롤러를 찾은 후 점수 증가
ABPlayerController->AddGameScore();
break;
}
}
//전체 점수 증가
ABGameState->AddGameScore();
}
Section
Complete 상태이면 스코어 증가 호출
#include "ABGameMode.h"
void AABSection::OnKeyNPCDestroyed(AActor * DestroyedActor)
{
//파괴된 엑터가 캐릭터 객체이면 LastHitBy 플레이어일 경우 COMPLETE 변경
auto ABCharacter = Cast<AABCharacter>(DestroyedActor);
ABCHECK(nullptr != ABCharacter);
auto ABPlayerController = Cast<AABPlayerController>(ABCharacter->LastHitBy);
ABCHECK(nullptr != ABPlayerController);
//게임 모드 호출해 스코어 증가
auto ABGameMode = Cast<AABGameMode>(GetWorld()->GetAuthGameMode());
ABCHECK(nullptr != ABGameMode);
ABGameMode->AddScore(ABPlayerController);
SetState(ESectionState::COMPLETE);
}