Unreal Engine 멀티플레이LESSON 10
GameMode, GameState, PlayerState에 데이터를 어디에 둘까
난이도입문 → 초급
예상 시간80분
선수지식9강의 RepNotify 상태
10강. GameMode, GameState, PlayerState에 데이터를 어디에 둘까
1. 이번 강의에서 해결할 문제
점수를 GameMode에만 저장해 클라이언트 HUD에서 읽지 못하거나 Character에 저장해 Respawn마다 사라집니다. 모든 값을 GameState에 넣으면 개인 정보와 전체 경기 규칙이 뒤섞입니다. 클래스의 수명·복제 범위와 접근 주체를 기준으로 상태를 배치해야 합니다.
2. 학습 목표
3. 핵심 개념
| 상태·규칙 | 위치 | 이유 |
|---|---|---|
| 접속 승인, Spawn 규칙, 승리 판정 | GameMode | 서버에만 있어야 하는 권위 규칙 |
| 팀 점수, 경기 단계, 서버 시간 | GameState | 모든 클라이언트가 알아야 하는 경기 상태 |
| 플레이어 팀, 개인 점수, 킬 | PlayerState | Pawn 교체와 사망 뒤에도 유지되는 플레이어 상태 |
| 체력, 이동, 무기 장착 | Pawn·Component | 현재 조종하는 월드 개체의 상태 |
GameState와 PlayerState는 “클라이언트가 써도 되는 값”이 아니라 “서버가 쓰고 클라이언트가 읽을 수 있게 복제하는 값”입니다.
4. 단계별 실습
CaptureArenaGameState.h
UENUM(BlueprintType)
enum class ECaptureMatchPhase : uint8
{
Waiting,
Playing,
Finished
};
UCLASS()
class CAPTUREARENA_API ACaptureArenaGameState : public AGameStateBase
{
GENERATED_BODY()
public:
void AddTeamScore(int32 TeamId, int32 Amount);
void SetMatchPhase(ECaptureMatchPhase NewPhase);
UPROPERTY(ReplicatedUsing = OnRep_TeamScores, BlueprintReadOnly)
int32 TeamAScore = 0;
UPROPERTY(ReplicatedUsing = OnRep_TeamScores, BlueprintReadOnly)
int32 TeamBScore = 0;
UPROPERTY(ReplicatedUsing = OnRep_MatchPhase, BlueprintReadOnly)
ECaptureMatchPhase MatchPhase = ECaptureMatchPhase::Waiting;
virtual void GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
UFUNCTION() void OnRep_TeamScores();
UFUNCTION() void OnRep_MatchPhase();
};
CaptureArenaGameState.cpp
#include "Game/CaptureArenaGameState.h"
#include "Net/UnrealNetwork.h"
void ACaptureArenaGameState::AddTeamScore(int32 TeamId, int32 Amount)
{
if (!HasAuthority() || Amount <= 0) return;
int32& Score = TeamId == 0 ? TeamAScore : TeamBScore;
Score += Amount;
OnRep_TeamScores();
}
void ACaptureArenaGameState::SetMatchPhase(ECaptureMatchPhase NewPhase)
{
if (!HasAuthority()) return;
MatchPhase = NewPhase;
OnRep_MatchPhase();
}
void ACaptureArenaGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACaptureArenaGameState, TeamAScore);
DOREPLIFETIME(ACaptureArenaGameState, TeamBScore);
DOREPLIFETIME(ACaptureArenaGameState, MatchPhase);
}
CaptureArenaPlayerState.h
UCLASS()
class CAPTUREARENA_API ACaptureArenaPlayerState : public APlayerState
{
GENERATED_BODY()
public:
void AddKill();
UPROPERTY(Replicated, BlueprintReadOnly)
int32 TeamId = INDEX_NONE;
UPROPERTY(ReplicatedUsing = OnRep_Kills, BlueprintReadOnly)
int32 Kills = 0;
virtual void GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
UFUNCTION() void OnRep_Kills();
};
GameMode 생성자에서 GameStateClass와 PlayerStateClass를 지정하고 World Settings 또는 프로젝트 기본 GameMode를 확인합니다. 클라이언트에서는 GetWorld()->GetGameState<ACaptureArenaGameState>()와 Pawn의 GetPlayerState<ACaptureArenaPlayerState>()를 사용합니다.
5. 코드가 동작하는 이유
GameMode는 서버에서만 규칙을 실행하므로 클라이언트가 승리 조건을 바꿀 수 없습니다. GameState는 서버와 모든 클라이언트에 존재해 팀 점수를 전달합니다. PlayerState는 Controller/Pawn과 분리된 플레이어 단위 Actor라 Respawn 뒤에도 점수와 팀이 유지되고 GameState->PlayerArray로 명단을 만들 수 있습니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
MINI QUIZ
0 / 2GameMode, GameState, PlayerState에 데이터를 어디에 둘까 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
LESSON STATUS
10강. GameMode, GameState, PlayerState에 데이터를 어디에 둘까 미완료 상태학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.