언리얼 Pawn과 게임플레이 프레임워크 정리 (GameMode, Controller, 입력, 애니메이션)
언리얼 Pawn 학습 노트. 강의 4.1~4.3 개념만. 게임모드/컨트롤러/폰 관계, 입력 흐름 헷갈릴 때 다시 보기.
게임플레이 프레임워크 3요소
다양한 장르와 멀티플레이까지 지원하도록 설계된 프레임워크. 핵심 셋:
- 게임모드(GameMode): 게임 규칙 관리. 눈에 안 보이는 액터
- 플레이어 컨트롤러(PlayerController): 게임에 입장하는 플레이어를 대변하는 무형의 액터
- 폰(Pawn): 플레이어 컨트롤러에게 조종당하는 액터
비유: 플레이어 컨트롤러 = 정신, 폰 = 육체. 컨트롤러를 통해 현재 폰을 버리고 다른 폰에 빙의 가능.
게임모드의 두 역할과 서버 관계
역할 두 가지: 게임 진행의 심판(승리 조건 등 판정), 플레이어 입장 준비(컨트롤러/폰 지정).
서버와의 관계가 핵심 함정: 게임모드는 서버 컴퓨터 한 대에만 존재함. 리슨서버면 방장 PC에만, 데디케이티드 서버면 데디 서버에만. 그래서 게임모드에 클라이언트별 로직을 넣으면 멀티플레이에서 깨짐. 게임모드는 서버 권한 로직만.
클래스를 지정하지 개체를 지정하지 않는다
가장 중요한 개념: 게임모드에 플레이어 컨트롤러"개체"를 만들어 넘기는 게 아니라 "클래스 정보"를 지정한다(PlayerControllerClass, DefaultPawnClass에 StaticClass()).
이유: 멀티플레이 구조. 플레이어가 입장할 때마다 그 클래스로 컨트롤러/폰을 새로 생성해야 하기 때문. 플레이어 캐릭터, 플레이어 스테이트도 동일 원리.
게임모드 설정 두 가지 방법
- 프로젝트 전역: Project Settings > Maps & Modes > Default GameMode. 레벨의 World Settings에 GameMode Override가 None일 때 기본 적용. 재사용하려고 일부러 None 두기도 함
- 레벨 한정: World Settings > GameMode Override. 그 아래 Selected GameMode에서 컨트롤러/폰도 지정 가능
함정: C++ 게임모드 클래스는 에디터에서 수정 불가. C++로 지정해야 함. 블루프린트 자식을 만들어야 에디터에서 만질 수 있음.
로그인과 빙의 용어
- 로그인(Login): 플레이어의 게임 입장(PIE 버튼)
- 빙의(Possess): 플레이어 컨트롤러가 폰을 소유해 조종하게 되는 과정
이벤트 함수 호출 순서
게임모드 → 컨트롤러 → 폰 순으로 흐름. override 시 부모 접근 지정자에 맞추고 Super 먼저 호출.
게임모드: InitGame → InitGameState → PostInitializeComponents → PreLogin → Login → PostLogin
컨트롤러: PostInitializeComponents → BeginPlay → (OnPossess) → PlayerTick
폰: PostInitializeComponents → (PossessedBy) → BeginPlay → SetupPlayerInputComponent → Tick
핵심: OnPossess(컨트롤러 측)와 PossessedBy(폰 측)가 빙의 시점에 짝으로 호출됨. 빙의 관련 초기화는 BeginPlay가 아니라 이 함수들에서 하는 게 안전(빙의가 안 끝났는데 BeginPlay가 먼저 돌 수 있음).
인간형 폰 컴포넌트 구성
- Capsule: 충돌 처리 + 루트 컴포넌트 겸함. 절반 높이/반지름 설정
- SkeletalMesh: 렌더링 + 애니메이션
- FloatingPawnMovement: 입력 따라 이동
- SpringArm: 3인칭 카메라 지지대. 길이/회전 설정
- Camera: 화면 출력. SpringArm에 부착
조립 구조: Capsule을 루트로, SkeletalMesh/SpringArm은 루트에 부착, Camera는 SpringArm에 부착. SkeletalMesh는 보통 캡슐 바닥에 발이 닿도록 -절반높이만큼 내리고 -90도 회전(메시 기본 방향 보정).
메시 길이 재는 법: 애셋을 Viewport에 드랍 → 좌상단 Perspective를 Front로 → 휠 버튼 누르고 드래그하면 cm 단위 측정. 다 재면 Front를 Perspective로 복귀.
입력 시스템 (구 방식, Deprecated)
이 방식은 deprecated지만 UE4 프로젝트 취업 시 쓰이고 개념 잡기 좋아서 학습용. 다음 단원에서 Enhanced Input 배움.
- Axis Mappings: 조이스틱 레버 같음. -1~1 값 전달(이동 등)
- Action Mappings: 버튼 같음. 0/1 값 전달(점프 등)
- 같은 입력에 키를 여러 개 묶고 Scale로 방향 구분(W는 +1, S는 -1)
- Project Settings > Input에서 설정. 휴지통 누르면 기존 설정 전체 초기화(주의)
처리 흐름: 입력 처리 함수를 InputComponent에 바인드하면 입력 신호가 함수 인자로 자동 전달. 바인드하기 좋은 이벤트 함수가 폰의 SetupPlayerInputComponent().
AddMovementInput(WorldDirection, Scale): 운전석 비유. WorldDirection은 핸들(월드 기준 방향 벡터), Scale은 액셀(1 전진, -1 후진).
입력 필터링 함정
입력 값은 플레이어 컨트롤러를 거쳐 폰으로 전달됨. 컨트롤러에서 같은 입력을 처리하면 그 입력은 필터링되어 폰까지 안 감.
원칙: 폰을 조종하는 입력 로직은 폰 클래스에 구현하는 게 올바름. "컨트롤러에 입력 바인드했더니 폰이 입력을 못 받네" 하면 이 필터링 때문. 컨트롤러 Tick이 돌아야 입력 처리가 되므로 bCanEverTick = true 필요.
SetInputMode 함정: PIE 후 매번 뷰포트를 클릭해야 입력이 게임에 전달됨. 컨트롤러 BeginPlay에서 FInputModeGameOnly로 SetInputMode 하면 바로 포커싱됨.
애니메이션 지정 두 방식
방식 1, C++ 직접 로드: BeginPlay에서 SetAnimationMode(AnimationSingleNode) 후 LoadObject로 애님 시퀀스 로드해 PlayAnimation. 규모 커지면 재생 코드 관리가 한계.
방식 2, 애니메이션 블루프린트(권장): 애니메이션 흐름을 Anim Graph에서 체계적으로 설계. SkeletalMesh는 애니메이션 처리를 애님 인스턴스에 위임하고, 거기에 ABP를 지정.
치트시트:
- LoadObject<>(): 런타임 중 애셋 로드
- ConstructorHelpers::FObjectFinder: 생성자에서 애셋(메시 등) 로드
- ConstructorHelpers::FClassFinder: 생성자에서 클래스(블루프린트 등) 로드
가장 자주 데이는 함정: 블루프린트 애셋을 클래스로 지정할 때 오브젝트 패스 끝에 반드시 _C를 붙여야 함(ABP_PlayerPawn.ABP_PlayerPawn_C). _C 없으면 클래스가 아니라 애셋 자체를 가리켜서 SetAnimInstanceClass가 실패.
Anim Graph 컴파일 함정: 컴파일 후 저장 안 하면 날아감. Compile 옆 점 세 개 > Save On Compile > On Success Only로 두면 성공 시 자동 저장.
실무 정리: C++로 애셋/ABP를 하드코딩하는 것보다 블루프린트 애셋(BP_PlayerPawn)에서 Skeletal Mesh와 Anim Class를 지정하는 게 안전(애셋 이동 대응). 코드로 했던 지정은 제거 가능.
'학습 > Unreal' 카테고리의 다른 글
| 언리얼 애니메이션 시스템 정리 (AnimInstance, State Machine, Montage, Notify) (0) | 2026.05.06 |
|---|---|
| 언리얼 Character와 시점 구현 정리 (Enhanced Input, Control Rotation, BackView/QuarterView) (0) | 2026.05.01 |
| 언리얼 Actor와 컴포넌트 구조 정리 (컴포지션, UPROPERTY, 이벤트 함수, Movement) (0) | 2026.04.30 |
| 언리얼 실무 도구 정리 (Interface, Delegate, FString, 컨테이너) (0) | 2026.04.28 |
| 언리얼 UObject 동작 원리 정리 (CDO, Reflection, GC, Serialization) (0) | 2026.04.27 |
