GameMode, GameState, PlayerController, PlayerState, Pawn, AnimInstance가 각각 왜 따로 존재하는지
1. 두 축으로 나누기
멀티플레이의 기본 축은 두 가지다
권한 축: 서버에만 존재하는가, 클라이언트에 복제되는가
개인 축: 나 자신에게만 보이는가, 모두에게 공개되는가
GameMode는 서버에만 존재하며 라운드, 리스폰, 승패 판정 같은 게임 규칙 본체를 담는다.
GameState는 전체 클라이언트에 복제되며 그 규칙의 결과를 모두에게 보여주는 전체 상태다.
PlayerController는 자기 자신에게만 존재하며 입력 처리와 카메라를 담당하는 플레이어의 의지다
PlayerState는 전체 클라이언트에 복제되며 점수나 닉네임처럼 공개되는 개인 데이터를 담는데 Pawn이 죽어도 유지된다는 게 특징이다
Pawn/Character는 서버와 클라이언트 양쪽에 존재하는 실제 몸으로 PlayerController가 Possess로 빙의한다
AnimInstance는 Character와 별도의 객체로 Character의 상태값을 받아 애니메이션 재생을 결정한다
Pawn은 죽으면 사라지고 새로 생기지만 점수 같은 데이터는 사라지면 안 되기 때문에 Pawn이 아니라 PlayerState에 둔다
리스폰 시 PlayerState::CopyProperties()가 호출되는데 이 함수가 "몸이 바뀌어도 데이터는 이어진다"는 PlayerState의 존재 이유를 보여준다
전체 흐름
접속 단계에서는 플레이어가 접속하면 GameMode::PostLogin()이 호출되고, PlayerController와 PlayerState가 생성된다.
이어서 GameMode::RestartPlayer()가 Pawn을 스폰하고, PlayerController::OnPossess(Pawn)으로 둘이 연결된다
게임플레이 중에는 매 프레임마다 입력이 들어오면 PlayerController가 처리해서 Character::Move()를 실행시키고, Character의 Velocity가 변하면 AnimInstance::NativeUpdateAnimation()이 그 Velocity를 읽어서 애니메이션을 갱신한다.
이벤트가 발생할 때
예를 들어 점수를 획득하면 Character에서 사건이 발생하고 PlayerState::AddScore()가 호출된다
Replicated 변수가 바뀌면 모든 클라이언트에 복제되어 OnRep_Score()가 실행되고, GameState의 전역 카운트도 갱신되어 다시 모두에게 복제된다
정리하면 GameMode가 위에서 전체를 지휘하고, 그 아래 사람 쌍(Controller+State)과 몸 쌍(Character+AnimInstance)이 Possess로 연결되며, 사건의 결과는 PlayerState에서 GameState 순서로 위로 보고되며 퍼진다.
C++ 베이스 + Blueprint 상속 패턴
C++을 고치면 매번 컴파일이 필요하지만 Blueprint는 즉시 적용된다
그래서 로직(함수, UPROPERTY)은 C++에 정의하고, 수치나 에셋 연결 같은 값 조정은 Blueprint에서 한다.
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
float MoveSpeed;
'학습 > Unreal' 카테고리의 다른 글
| NetLoadOnClient, Replication Notify (OnRep), Conditional Property Replication (0) | 2026.06.29 |
|---|---|
| 멀티플레이 디버깅 (0) | 2026.06.24 |
| Property Replication (기초) (0) | 2026.06.22 |
| 서버를 거치는 통신 구조 (0) | 2026.06.22 |
| Remote Procedure Call 기초 (RPC 기초) (0) | 2026.06.19 |
