내일배움캠프 언리얼트랙 38일차 - 심화반 2강

2026. 6. 16. 23:26·내일배움캠프

4대 핵심 클래스

클래스 명 비유 핵심 특징
AGameMode Rule Maker (심판) 규칙을 정하고 승패를 판정. 서버에만 존재.
AGameState Scoreboard (전광판) 현재 점수, 남은 시간 등 모두가 봐야 하는 정보를 공유함.
APlayerState 개인 수첩 개별 이름, 득점 등 개인 데이터를 기록함.
UGameInstance 총관리자 레벨이 끝나고 다음 레벨로 넘어가도 절대 사라지지 않음.

AGameMode

키워드 : 규칙, 서버 전용, 오직 명령만(내게 명령하지마라. 명령은 내가 한다.)

 

역할

  • 게임의 룰 관리
    • 승리하려면 몇점을 내야하는지, 제한 시간은 얼마나 되는지 등 규칙을 가짐.
  • Spawn 결정
    • 플레이어에게 어떤 Pawn을 줄지, PlayerStart를 어디로 할지를 결정.
  • 게임 흐름 제어
    • 스테이지 시작, 관전모드 전환, 게임오버 등 굵직한 판정을 내림.

특징

  • Server Only. 서버에만 산다!
    • 멀티플레이 게임을 만들 때 가장 많이 하는 실수가 클라이언트에서 GameMode를 찾으려고 하는것.
    • AGameMode는 오직 서버(Host) 메모리에만 존재한다. 즉, A라는 유저의 컴퓨터(클라이언트)에는 GameMode가 아예 존재하지 않음!
    • 클라이언트에 GameMode가 있으면 게임의 규칙을 바꿔버릴 수 있기 때문에 보안을 위해 서버에만 둔다.

Base vs 일반

  • AGameModeBase (가벼운 기본형)
    • 싱글 플레이 게임이나 오픈월드RPG처럼 "시작과 끝이 단순한 게임"에 적합
  • AGameMode (매치 시스템이 있는 무거운 버전)
    • FPS처럼 먕확한 단계(State Machine)가 필요한 게임에 사용

핵심 구현 패턴

결정만 하고 AGameState에 넘기기!

AGameMode는 결정하는 고귀한 아이. 동네방네 소문내는 입이 가벼운 아이가 아님!

void AMyGameMode::StartMatch()
{
	bMatchInProgress = true;
    
    // 1. GameMode가 매치 시작이라고 결정
    if(AMyGameState* GS = GetGameState<AMyGameState>())
    {
    	// 2. 그 사실을 GameState에 넘겨서 모두가 볼 수 있게 함
        GS->NotifyMatchStarted(MatchDuration);
    }
}

 

만약 GameMode가 남은 시간 변수를 직접 가지고 있으면, 클라이언트들은 GameMode를 볼 수 없으니 화면에 남은 시간이 뜨지 않는 대참사가 발생함.

즉, GameMode는 명령만 내리고, 변수는 모두가 볼 수 있는 AGameState에 적어두는것이 정석이다.

 


AGameState

키워드 : 네트워크 복제, 읽기 전용

 

역할

GameMode 가 내린 결정이나 게임의 현재 상황을 담아서 모든 유저가 볼 수 있도록 동기화.

 

특징

클라이언트와  UI가 읽기만 해야한다. 데이터를 직접 수정하는 결정은 GameMode의 역할이다.

 


APlayerState

키워드 : 개인 데이터의 영속성(Persistence), 모두에게 복제(Replication), 한 레벨에 유지

 

역할 / 특징

내 캐릭터가 죽으면 그 캐릭터는 월드에서 파괴되거나 사라진다. 만약 캐릭터에 점수/킬카운트를 저장했다면 캐릭터가 죽어서 사라질 때 내 점수와 킬카운트값도 공중분해 영영 빠이빠이 되어버린다. 흑흑. 리스폰 했더니 내 화려한 전적이 0이 되어버림..

 

따라서 캐릭터(Pawn)은 언제든 갈아치우는 일회용 몸뚱이로 쓰고 절대 사라지면 안되는 내 데이터(이름, 점수, 팀, 핑...)는 PlayerState라는 개인 수첩에 보관하는 것이다. 이렇게 하면 캐릭터가 죽어도 수첩의 내용은 그대로이니 완전안심!

 

 

APlayerController는 나와 서버만 볼 수 있다. 즉, 다른 사람의 화면이나 컴퓨터에는 보이지 않는다.

APlayerState는 서버가 모든 클라이언트에세 복제(Replication)을 해준다.

-> 점수판을 확인할때 다른 사람들의 점수와 이름도 다 보여야하니까! PlayerController는 나한테 안보이지만 PlayerState는 모두에게 공유되기 때문에 점수판UI를 만들땐 항상 PlayerState를 뒤져서 데이터를 가져온다!

 

접근 방법

// ❌ 절대 금지 (안티 패턴): 전광판 배열에서 그냥 0번 인덱스 꺼내기
// 싱글 게임에선 돌아갈지 몰라도, 멀티게임에선 누가 0번일지 장담할 수 없습니다!
AMyPlayerState* BadPS = GetWorld()->GetGameState()->PlayerArray[0];

//  올바른 방법 1: 내 컨트롤러에게 "내 수첩 줘"라고 하기 (내 UI 갱신할 때)
AMyPlayerState* MyPS = MyController->GetPlayerState<AMyPlayerState>();

//  올바른 방법 2: 클라이언트가 점수를 얻고 싶을 때 (핵 방지용 RPC 요청)
// "내 수첩아, 나 50점 먹었으니까 서버에 적용해줘!"
MyPlayerState->Server_AddScore(50);

 


GameInstance

키워드 : 불사신, 레벨 전환 이사 전문

 

역할

  • 전체 누적 데이터 관리
    • 플레이어의 총 누적 골드, 여태까지 클리어 한 스테이지 번호 등 게임 전체를 관통하는 데이터를 들고있기에 가장 좋다.
  • 레벨 전환의 총지휘관
    • 레벨을 열고 닫는 권환을 실행하기 가장 좋은 위치이다.

 

특징

  • 수명
    • 게임 프로그램을 킬 때 태어나서, 게임을 완전히 종료할 때 죽는다.
  • 불사신
    • 로비 레벨, 마을 레벨 심지어 메인 메뉴 화면으로 돌아가더라도 GameInstance만큼은 메모리에서 절대 사라지지 않고 단 하나만 계속 유지된다.
    •  

APlayerController

내가 이 캐릭터의 영혼이다 중생들아

 

유저가 키보드를 누르고 마우스를 움직이는 모든 행동을 게임 속 세계로 전달하는  컨트롤러 역할

 

하는 일

  • 입력 처리 (Input Binding)
    • 플레이어의 입력을 받아 처리한다.
  • 육체 빙의 (Possess / UnPossess)
    • 월드에 배치된 캐릭터(APawn)에 영혼을 불어넣는 역할을 한다. 캐릭터가 죽으면 빠져나오고 부활하면 새 캐릭터에 다시 빙의한다.
  • 카메라 및 UI 관리
    • PlayerCameraManager를 관리하고, 화면에 마우스 커서를 띄우거나 마우스 클릭 기반의 HUD/UMG 위젯 UI를 생성하고 조작하는 주체가 된다.

 

서버와 본인 컴퓨터에만 존재

멀티플레이에서 컨트롤러의 메모리 구조는 대단히 독특함!

 

  • 서버 (HOST)
    • 모든 점속자의 PlayerController를 전부 가지고 관리한다.
    • 누가 무슨 행동을 하느지 알아야하니까!
  • 내 컴퓨터 (로컬 클라이언트)
    • 오직 내 것 하나만 존재한다. 다른 사람의 PlayerController는 내 컴퓨터 메모리에 아예 생성되지 않는다.
  • 다른 사람 컴퓨터
    • 내 PlayerController가 존재하지 않는다. 

 

AIController

사람이 조종하는 캐릭터가 아닌, 컴퓨터가 조종하는 몬스터나 NPC의 영혼역할을 맡는다.

입력이나 UI를 처리하는 기능이 쏙 빠져있는 대신, Behavior Tree나 주변을 감지하는 UAIPerceptionComponent를 장착해서 스스로 Pawn을 조종하게 된다.


APawn vs ACharacter

움직이는 육체들의 등급

컨트롤러(영혼)가 빙의할 수 있는 모든 물리적인 몸뚱이는 APawn에서 출발한다. 언리얼은 이를 크게 두 가지로 나누어 제공한다.

 

APawn

특징

인간이 아닌 형태의 탈것이나 물체를 만들 때 주로 상속 받는다.

아주 기본적인 이동 컴포넌트(MovementComponent)만 가지고 있어서, 하늘을 날거나 구르는 물리 로직을 개발자가 커스텀하기에 좋다.

 

ACharacter

특징

사람처럼 두 발로 걷고, 달리고, 점프하는 캐릭터를 만들 때 쓴다. RPG나 FPS게임의 주인공들은 99% 이 녀석을 상속받는다.

언리얼이 미리 엄청난 기능들을 기본으로 추가해두었다.

  • CharacterMovementComponent
    • 걷기, 달리기, 점프, 수영, 비행 등 인간형 이동 로직이 이미 완벽하게 구현되어있다.
  • CapsuleComponent
    • 부딪히는 물리 충돌 체형
  • SkeletalMeshComponent
    • 애니메이션을 입힐 수 있는 뼈대 메쉬

 

특수  Pawn

ADefaultPawn

자유 비행 카메라용. 에디터/디버깅에서 자주 쓰인다.

ASpectatorPawn

매치 관전 모드용. 충돌 없이 자유 이동 가능.


Framework 로딩 순서 (LifeCycle)

1단계: 가장 먼저 태어나는 맏형 (GameInstance)

  • 게임이 켜지자마자 UGameInstance::Init()이 실행된다.
  • 주의: 이때는 아직 월드(World)도 없고, 다른 4대장들도 아예 안 태어난 상태. 여기서 GetWorld()나 GetPlayerController()를 호출하면 무조건 튕긴다!

2단계: 레벨이 열리며 태어나는 동생들 (응애 응애)

  • 맵이 로드되면 GameMode => GameState => PlayerController => PlayerState => Pawn 순서로 순식간에 스폰됨.

3단계: PostLogin()과 StartPlay()

  • 많은 초보자가 BeginPlay()에서 모든 걸 해결하려고 한다. 하지만 BeginPlay는 애들의 호출 순서가 뒤죽박죽이라 위험!
  • 가장 안전한 타이밍: 심판(GameMode)의 PostLogin() 함수. 이 함수가 실행되는 시점에는 플레이어의 영혼(PlayerController)과 수첩(PlayerState)이 완벽하게 세팅되어 연결된 상태이므로, 멀티플레이어 초기화 코드를 짜기에 가장 안전의 정석이다.

 

'내일배움캠프' 카테고리의 다른 글

내일배움캠프 언리얼트랙 41일차 - 보안요원 State Tree  (0) 2026.06.19
내일배움캠프 언리얼트랙 40일차 - 보안요원 AI Controller  (0) 2026.06.18
내일배움캠프 언리얼트랙 35일차 - TA 1강  (0) 2026.06.11
내일배움캠프 언리얼트랙 34일차 - 과제04  (0) 2026.06.10
내일배움캠프 언리얼트랙 33일차  (0) 2026.06.10
'내일배움캠프' 카테고리의 다른 글
  • 내일배움캠프 언리얼트랙 41일차 - 보안요원 State Tree
  • 내일배움캠프 언리얼트랙 40일차 - 보안요원 AI Controller
  • 내일배움캠프 언리얼트랙 35일차 - TA 1강
  • 내일배움캠프 언리얼트랙 34일차 - 과제04
thinklikethink
thinklikethink
생각처럼 개발 공부 블로그입니다.
  • thinklikethink
    생각처럼
    thinklikethink
  • 전체
    오늘
    어제
    • 분류 전체보기 (53) N
      • 사전캠프 (13)
      • 내일배움캠프 (40) N
  • 블로그 메뉴

    • 홈
    • 내일배움캠프
    • 사전캠프
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
thinklikethink
내일배움캠프 언리얼트랙 38일차 - 심화반 2강
상단으로

티스토리툴바