Unreal Engine의 Gameplay Framework는 게임을 구성하는 주요 객체들의 책임, 수명, 복제 범위를 분리하기 위해 설계되어 있다.

구분 클래스
서버에만 존재 AGameMode
서버와 모든 클라이언트에 복제 AGameState, APlayerState, APawn
서버와 소유 클라이언트에 존재 APlayerController
로컬 클라이언트 전용 AHUD, UUserWidget

핵심 클래스

클래스 역할
UGameInstance 게임 실행 전체 동안 유지되는 객체. 레벨 전환 후에도 살아남는 데이터와 Subsystem을 관리한다.
AGameMode 게임 규칙을 결정한다. 승패 판정, 매치 시작/종료, 스폰 규칙 등을 담당하며 서버에만 존재한다.
AGameState 클라이언트도 알아야 하는 게임 공통 상태를 저장하고 복제한다.
APlayerController 플레이어의 입력, 카메라, UI, Pawn 조종을 담당한다.
AAIController AI가 Pawn을 조종할 때 사용하는 Controller다. Behavior Tree, Blackboard, Perception 등을 다룬다.
APlayerState 플레이어의 이름, 점수, 팀, 핑처럼 Pawn이 죽어도 유지되어야 하는 정보를 저장한다.
APawn / ACharacter 월드 안에서 실제로 존재하고 움직이는 몸체다. 사람형 캐릭터는 보통 ACharacter를 사용한다.
AHUD 로컬 전용 2D 화면 그리기 객체다. 현대 UE에서는 주로 UMG/Common UI가 UI의 중심이다.
APlayerCameraManager 최종 카메라 위치, 회전, FOV, 카메라 셰이크 등을 결정한다.
UWorld / ULevel 현재 실행 중인 월드와 디스크에 저장된 맵 단위.

핵심 클래스의 책임 분리

책임 위치
게임 규칙, 승패 판정 AGameMode
클라이언트가 봐야 하는 매치 정보 AGameState
플레이어 개인 영구 정보 APlayerState
레벨 전환 후에도 유지되어야 하는 정보 UGameInstance 또는 UGameInstanceSubsystem
class ASuperPlayer : public APawn
{
    float Health = 100.0f;
    int32 Score = 0;

    float GameTimeRemaining = 300.0f;
    bool bGameStarted = false;

    void UpdateHealthBar();
    void CheckWinCondition();
};

이 구조는 다음과 같은 문제가 있다.

  • 플레이어 개인 정보, 게임 전체 상태, UI, 게임 규칙이 한 클래스에 섞여 있다.
  • Pawn이 GameMode, GameState, UI 역할까지 떠안는다.
  • 멀티플레이 확장이 어렵다.
  • Pawn이 죽거나 재생성될 때 점수 같은 영구 데이터가 사라질 수 있다.

GameMode

현재 레벨의 게임 규칙을 정의하는 클래스

  • 어떤 Pawn을 사용할지 결정
  • 플레이어 스폰 규칙 결정
  • 매치 시작과 종료 관리
  • 승리/패배 조건 판단
  • 게임 흐름 제어

GameMode서버에만 존재한다.
클라이언트가 직접 봐야 하는 정보는 GameState에 넘겨야 한다.


GameModeBase와 GameMode

클래스 특징
AGameModeBase 가벼운 기본형. 단순한 게임에 적합
AGameMode 매치 상태 머신, 자동 리스폰, 관전자 모드 등을 포함

AGameMode를 사용할 경우 AGameState와 함께 사용
AGameModeBase를 사용할 경우 AGameStateBase와 함께 사용


GameState

AGameState는 클라이언트도 봐야 하는 게임 공통 정보를 저장하는 클래스다.

  • 남은 시간
  • 현재 라운드
  • 매치 진행 상태
  • 전체 목표 진행도

GameMode, GameState 책임 분리

GameMode결정만 내리고 공유 정보는 GameState에 위임

  1. GameMode가 상태를 계산한다.
  2. GameModeGameState에 정보를 전달한다.
  3. GameState는 해당 정보를 복제한다.
  4. UI는 GameState를 읽어서 표시한다.
UCLASS()
class AMyGameState : public AGameStateBase
{
    GENERATED_BODY()

public:
    UPROPERTY(BlueprintReadOnly, ReplicatedUsing=OnRep_RemainingTime)
    float RemainingTime = 0.0f;

    UFUNCTION()
    void NotifyMatchStarted(float Duration);

protected:
    UFUNCTION()
    void OnRep_RemainingTime();
};

클라이언트가 직접 GameState의 값을 수정하는 구조는 피해야 한다.


PlayerState

APlayerState는 플레이어 한 명의 영구 상태를 저장한다.

  • 플레이어 이름
  • 점수
  • 킬/데스
  • 캐릭터가 죽어도 유지되어야 하는 진행 정보

Pawn은 죽거나 교체될 수 있지만, PlayerState는 플레이어의 상태를 유지하기 위해 존재한다.

데이터 적절한 위치
현재 체력 APawn 또는 체력 컴포넌트
현재 무기 장착 상태 APawn 또는 인벤토리/장비 컴포넌트
점수 APlayerState
APlayerState
닉네임 APlayerState
레벨 전환 후 누적 점수 APlayerState 또는 UGameInstance

클라이언트에서 점수를 변경해야 한다면 직접 수정하지 말고 서버 RPC를 통해 요청해야 한다.

UFUNCTION(Server, Reliable)
void Server_AddScore(int32 Points);

GameInstance

UGameInstance는 게임 실행 시작부터 종료까지 살아 있는 객체다.
레벨이 바뀌어도 파괴되지 않는다.

  • 플레이어 프로필
  • 세이브 데이터
  • 누적 진행도
  • 전체 레벨 진행 상태
  • 레벨 전환 제어
  • 게임 전체에서 유지되어야 하는 매니저 기능
UCLASS()
class UMyGameInstance : public UGameInstance
{
    GENERATED_BODY()

public:
    UPROPERTY(BlueprintReadWrite)
    FString PlayerName = TEXT("Player");

    UPROPERTY(BlueprintReadWrite)
    int32 TotalScore = 0;

    UFUNCTION(BlueprintCallable)
    void LoadNextLevel();
};

단, GameInstance에 모든 것을 몰아넣으면 사실상 전역 변수처럼 변질된다.
가능하면 데이터의 수명에 맞춰 더 좁은 스코프의 Subsystem을 사용하는 것이 좋다.

Subsystem 사용 상황
UEngineSubsystem 엔진 전체에서 공유되는 기능
UGameInstanceSubsystem 게임 세션 전체에서 유지되는 기능
UWorldSubsystem 특정 World 안에서만 필요한 기능
ULocalPlayerSubsystem 특정 로컬 플레이어에게만 필요한 기능

Controller

AController는 Pawn을 소유하고 조종하는 객체다.
AController를 상속받는 APlayerController 또는 AAIController를 사용한다.


APlayerController

사람 플레이어 한 명의 의지를 표현한다.

  • 입력 처리
  • Pawn Possess / UnPossess
  • 카메라 제어
  • UI 생성과 관리
  • PlayerState 접근

주의할 점은 PlayerController에 캐릭터의 체력, 공격력, 인벤토리 같은 물리적 게임플레이 데이터를 넣지 않는 것이다.

입력과 UI는 PlayerController, 실제 이동과 전투는 Pawn 또는 ActorComponent가 담당하는 것이 좋다.


AAIController

AI가 Pawn을 조종할 때 사용하는 Controller다.

주요 책임은 다음과 같다.

  • Behavior Tree 실행
  • Blackboard 관리
  • AI Perception 처리
  • State Tree 실행
  • AI Pawn Possess

여러 적이 같은 Pawn 클래스를 사용하더라도, 각 적은 자기만의 AIController 인스턴스를 가질 수 있다.


APawn

APawn은 Controller가 Possess할 수 있는 Actor다.
조종 가능한 월드 내 물리적 존재.

  • 차량
  • 비행기
  • 탱크
  • 드론
  • 추상적인 조종 대상

이동은 보통 별도의 Movement Component를 통해 처리한다.


ACharacter

ACharacter는 사람형 캐릭터를 위한 Pawn의 특수 형태다.

기본으로 다음 기능이 포함되어 있다.

  • UCapsuleComponent
  • USkeletalMeshComponent
  • UCharacterMovementComponent
  • 걷기, 점프, 낙하, 수영, 비행 이동 모드

사람형 플레이어 캐릭터나 일반적인 인간형 적은 대부분 ACharacter를 상속한다.

책임 경계

Pawn이나 Character에는 다음처럼 월드 내 물리적 존재와 직접 관련된 데이터를 둔다.

  • 현재 체력
  • 현재 위치
  • 이동 상태
  • 장착 중인 무기
  • 애니메이션 상태

하지만 전투, 인벤토리, 퀘스트, 스탯 등 기능이 커지면 Character에 모두 넣지 말고 컴포넌트로 분리해야 한다.

UCombatComponent* CombatComponent;
UInventoryComponent* InventoryComponent;
UStatComponent* StatComponent;

AHUD, UMG, Common UI

AHUD는 과거 방식의 2D 화면 그리기 객체다.
Canvas를 이용해 크로스헤어, 디버그 텍스트, 간단한 오버레이를 그리는 용도로 사용할 수 있다.

현대 Unreal Engine에서는 대부분의 UI를 UUserWidget 기반의 UMG로 제작한다.

방식 용도
AHUD 단순 디버그 표시, 크로스헤어, 즉시 모드 2D 그리기
UMG 일반적인 게임 UI
Common UI 입력 모드, 위젯 스택, 게임패드/키보드/마우스 통합 UI 관리

작은 프로젝트라면 UMG만으로도 충분하다.
하지만 모달, 팝업 스택, 게임패드 지원, 입력 모드 전환이 많아지면 Common UI 도입을 고려할 수 있다.


PlayerCameraManager

APlayerCameraManager는 PlayerController가 소유하며, 최종 카메라 상태를 결정한다.

  • ViewTarget 결정
  • FOV 변경
  • 카메라 셰이크
  • 카메라 블렌딩
  • 시점 전환

Pawn에 붙은 UCameraComponent가 기본 시점을 제공하고, PlayerCameraManager는 최종적으로 화면에 어떤 뷰를 보여줄지 결정한다.


UWorld, ULevel

UWorld는 현재 실행 중인 월드의 런타임 컨테이너다.
GameMode, GameState, PlayerController, Pawn, Actor 등은 모두 특정 World 안에 존재한다.

ULevel은 디스크에 저장된 .umap 파일 단위다.
하나의 World는 Persistent Level과 여러 Sub Level을 가질 수 있다.

PIE, 멀티플레이, 에디터 환경에서는 여러 World가 동시에 존재할 수 있으므로
GWorld를 직접 사용하는 것을 피해야 한다.
항상 현재 객체의 컨텍스트에서 GetWorld()를 사용하는 것이 안전하다.

반응형

'Unreal Engine' 카테고리의 다른 글

AssetManager  (0) 2026.06.19
UE Game play Framework 2  (0) 2026.06.18
GAS 2  (0) 2026.06.16
GAS 1  (0) 2026.06.15
SmartObject 1  (0) 2026.06.12