Pawn, Character, Controller 이해
Controller가 Pawn을 Possess하는 흐름과 Character의 이동·충돌·애니메이션 확장 구조를 구분합니다.
2장에서 객체 시스템과 게임 루프의 큰 틀을 잡았다면, 이제 실제 게임플레이의 중심 클래스로 내려와야 합니다.
이번 절에서는 APawn, ACharacter, AController를 제어 주체와 몸체 책임 기준으로 다룹니다.
이 세 클래스는 플레이어와 AI의 움직임, 상호작용, 제어 책임을 나누는 핵심 기준입니다.
APawn: 제어 가능한 월드 객체
APawn은 언리얼 엔진의 3D 월드에 존재하며 AController에 의해 빙의(Possess)되어 제어될 수 있는 AActor의 한 종류입니다.
Pawn은 기본적으로 시각적인 표현이나 복잡한 이동 로직을 내장하고 있지 않습니다.
대신, AController로부터 명령을 받아 움직이거나 특정 행동을 수행하는 대리인 역할을 합니다.
-
주요 특징
- 제어 가능성:
APlayerController또는AAIController에 의해 빙의될 수 있습니다. 빙의는 제어 연결이며 이동 자체의 필수 조건은 아닙니다. 빙의되지 않아도 물리나 직접 작성한 로직으로 움직일 수 있습니다. - 변환 정보:
AActor를 상속받으므로 월드 내에서 위치, 회전, 스케일 정보를 가집니다. - 컴포넌트 컨테이너:
APawn자체는 아무런 시각적 메시나 이동 로직을 가지지 않지만,UPROPERTY로 선언된 컴포넌트들을 추가하여 기능을 확장할 수 있습니다. 예를 들어,UStaticMeshComponent를 추가하여 시각적인 형태를 부여하고,UFloatingPawnMovement같은 컴포넌트를 붙여 이동 로직을 구현할 수 있습니다. - 입력 처리 위임:
APawn은 직접 플레이어 입력을 처리하기보다는, 자신을 제어하는AController로부터 명령을 받습니다. 하지만 필요하다면APawn자체적으로도 입력을 바인딩하고 처리할 수 있습니다.
- 제어 가능성:
-
언제
APawn을 사용할까요?- 사람 형태가 아닌 플레이어블 객체: 예를 들어, 차량, 비행기, 드론, 탱크 등 CharacterMovement와 다른 이동 모델을 구현할 때
APawn을 상속받아 사용합니다. - 간단한 AI 객체: 단순한 움직임이나 상호작용만을 수행하는 AI 객체에 적합합니다.
- 사람 형태가 아닌 플레이어블 객체: 예를 들어, 차량, 비행기, 드론, 탱크 등 CharacterMovement와 다른 이동 모델을 구현할 때
ACharacter: 플레이어를 위한 특화된 Pawn
ACharacter는 APawn을 상속받는 특화된 Pawn 클래스입니다.
사람 형태의 플레이어 캐릭터나 AI 캐릭터 구현에 맞춰 설계되어 있으며, APawn 기능 위에 이동/충돌/애니메이션 연동에 필요한 기본 컴포넌트를 제공합니다.
-
주요 특징
-
UCapsuleComponent(Root Component):ACharacter의 루트 컴포넌트로 자동으로 포함됩니다. 캐릭터의 충돌 영역을 캡슐 형태로 정의하며, 캐릭터 이동의 주된 충돌 형상으로 사용됩니다. -
USkeletalMeshComponent: 캐릭터의 스켈레탈 메시(애니메이션 가능한 3D 모델)를 표현하는 컴포넌트입니다. 캐릭터의 시각적인 부분을 담당하며, 애니메이션 블루프린트와 연동되어 복잡한 애니메이션을 구현합니다. -
UCharacterMovementComponent:ACharacter의 핵심 컴포넌트입니다. 중력, 점프, 걷기, 달리기, 웅크리기, 낙하 같은 이동 로직을 기본 구현하고 있어 설정 조정과 함수 호출만으로 다양한 움직임을 만들 수 있습니다.네트워크 멀티플레이어 동기화까지 고려되어 있다는 점도 큰 장점입니다.
-
네트워크 복제 최적화:
ACharacter는 네트워크 환경에서 이동 및 상태 복제에 최적화되어 있습니다.
-
-
언제
ACharacter를 사용할까요?- 대부분의 플레이어블 캐릭터: FPS/TPS 게임의 주인공, RPG 게임의 캐릭터 등 사람 형태의 복잡한 움직임이 필요한 경우에 사용합니다.
- 사람 형태의 AI 캐릭터: NPC, 몬스터 등
UCharacterMovementComponent의 이동 로직이 필요한 AI 캐릭터에 사용합니다.
AController: Pawn을 제어하는 두뇌
AController는 APawn 또는 ACharacter를 빙의(Possess)해 제어하는 클래스입니다.
AController 자체는 월드에 보이지 않으며, Pawn/Character가 몸이라면 Controller는 그 몸을 움직이는 두뇌 역할을 합니다.
이 클래스는 크게 두 가지 파생 타입으로 나뉩니다.
APlayerController: 플레이어의 두뇌
-
역할: 사용자(플레이어)의 입력(키보드, 마우스, 게임패드 등)을 받아
Pawn이나Character를 제어하고, 게임 월드와 상호작용하는 역할을 합니다. 또한 플레이어의 HUD(Head-Up Display) 표시, 인벤토리 관리, 설정 저장/로드 등 플레이어 고유의 전반적인 관리도 담당합니다. -
특징
- 각 플레이어마다 하나씩 존재: 멀티플레이어 게임에 접속한 각 플레이어는 자신만의
APlayerController인스턴스를 가집니다. - 서버와 클라이언트 모두에 존재:
APlayerController는 서버와 해당 클라이언트 모두에 복제되어 존재하며, 입력 처리와 명령 전달을 담당합니다. - UI 상호작용: UI 위젯을 생성하고 관리하며, 마우스 커서 표시 등을 제어할 수 있습니다.
Possess()및UnPossess()함수:APlayerController는Possess(APawn* InPawn)함수를 통해 특정Pawn에 빙의하여 제어를 시작하고,UnPossess()를 통해 제어를 해제할 수 있습니다.
- 각 플레이어마다 하나씩 존재: 멀티플레이어 게임에 접속한 각 플레이어는 자신만의
-
언제
APlayerController를 사용할까요?- 플레이어의 입력 처리 및 캐릭터 조작.
- 플레이어 인벤토리, 스킬, 능력치 등 플레이어 고유의 데이터 관리.
- 플레이어에게 보이는 UI(HUD, 메뉴 등) 관리.
- 클라이언트와 서버 간의 RPC(Remote Procedure Call) 통신 시작점.
AAIController: AI의 두뇌
-
역할: AI(인공지능)의 로직을 처리하고, 해당 AI가 조종하는
Pawn이나Character를 제어하는 클래스입니다. AI 제어를 Controller에 분리할 때 AAIController를 사용합니다. 모든 자동 동작이 이 클래스의 사용을 요구하는 것은 아닙니다. -
특징
- 행동 트리(Behavior Tree) 및 블랙보드(Blackboard) 연동: 언리얼 엔진의 강력한 AI 시스템인 행동 트리와 블랙보드를 사용하여 복잡한 AI 로직을 구축하는 데 핵심적인 역할을 합니다.
- 지각 컴포넌트(Perception Component):
UAIPerceptionComponent와 같은 컴포넌트를 사용하여 환경을 인지(시각, 청각 등)하고, 인지된 정보를 바탕으로 행동을 결정합니다. - 내비게이션(Navigation) 및 경로 탐색: 내비게이션 메시를 이용하여 캐릭터가 이동할 수 있는 경로를 탐색하고 이동 명령을
Pawn에게 전달합니다.
-
언제
AAIController를 사용할까요?- 게임 내의 적, NPC, 아군 AI 등 컴퓨터가 제어하는 모든 캐릭터의 행동 로직을 구현할 때.
빙의와 객체의 수명
하나의 Pawn은 동시에 하나의 Controller에 빙의됩니다. 네트워크 게임의 Possess는 권한 측에서 수행하며, 로컬 UI와 입력은 해당 로컬 플레이어의 실행 환경에서 처리합니다.
빙의 연결을 바꾸어도 객체 수명은 별개입니다
기존 C/A/B에서 C→A 제어를 C→B로 바꾸는 실제 관계 전이다. A/B 생성·파괴나 소지품 3개 이전은 자동 추가하지 않는다.
UNREAL C++ · CH3-1
빙의 연결을 바꾸어도 객체 수명은 별개입니다
Possess·UnPossess는 Controller와 Pawn의 제어 연결을 바꿉니다. 생성·파괴·상태 이전까지 자동으로 수행하는 동작은 아닙니다.
전환 전: C가 기존 A를 제어합니다.
전환 후: 같은 C가 기존 B를 제어합니다. 세 객체는 그대로 있습니다.
| 동작 | 바뀌는 연결 | 자동으로 하지 않는 일 |
|---|---|---|
| Possess | 권한 측 Controller가 제어할 Pawn을 선택 | Pawn이나 이동 컴포넌트를 새로 만드는 작업 |
| UnPossess | 현재 Controller와 Pawn의 제어 연결 해제 | 두 객체를 모두 파괴하거나 Pawn의 모든 움직임 정지 |
| 다른 Pawn으로 전환 | 같은 Controller가 다른 몸체를 제어하도록 변경 | 기존 Pawn의 상태·소지품을 새 Pawn으로 복사 |
- Possess
- 바뀌는 연결: 권한 측 Controller가 제어할 Pawn을 선택자동으로 하지 않는 일: Pawn이나 이동 컴포넌트를 새로 만드는 작업
- UnPossess
- 바뀌는 연결: 현재 Controller와 Pawn의 제어 연결 해제자동으로 하지 않는 일: 두 객체를 모두 파괴하거나 Pawn의 모든 움직임 정지
- 다른 Pawn으로 전환
- 바뀌는 연결: 같은 Controller가 다른 몸체를 제어하도록 변경자동으로 하지 않는 일: 기존 Pawn의 상태·소지품을 새 Pawn으로 복사
GetPawn()과 GetController()가 의도한 상대인지 확인합니다. Controller의 로컬 제어 상태, PlayerState의 공유 상태, Pawn의 몸체 상태를 게임의 수명 정책에 맞춰 나눕니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
| 범위 | 원문 |
|---|---|
| 관계·조건 설명 | 같은 Controller C와 기존 PawnA/B의 두 시점을 별도로 표현한다. 전환 전 C→A, 성공한 전환 후 C→B이며 선은 제어 관계 하나다. 생성·파괴·몸체 소지품 복사는 포함하지 않는다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 기존 Possess C가 PawnA를 제어한다. |
|
|
| 대상 변경 제어 관계를 PawnB로 바꾼다. |
|
|
| 현재 상태 C의 현재 Pawn은 B이며 A/B는 독립 객체다. |
|
|
빙의 연결을 바꾸어도 객체 수명은 별개입니다
기존 C/A/B에서 C→A 제어를 C→B로 바꾸는 실제 관계 전이다. A/B 생성·파괴나 소지품 3개 이전은 자동 추가하지 않는다.
UNREAL C++ · CH3-1
빙의 연결을 바꾸어도 객체 수명은 별개입니다
Possess·UnPossess는 Controller와 Pawn의 제어 연결을 바꿉니다. 생성·파괴·상태 이전까지 자동으로 수행하는 동작은 아닙니다.
전환 전: C가 기존 A를 제어합니다.
전환 후: 같은 C가 기존 B를 제어합니다. 세 객체는 그대로 있습니다.
| 동작 | 바뀌는 연결 | 자동으로 하지 않는 일 |
|---|---|---|
| Possess | 권한 측 Controller가 제어할 Pawn을 선택 | Pawn이나 이동 컴포넌트를 새로 만드는 작업 |
| UnPossess | 현재 Controller와 Pawn의 제어 연결 해제 | 두 객체를 모두 파괴하거나 Pawn의 모든 움직임 정지 |
| 다른 Pawn으로 전환 | 같은 Controller가 다른 몸체를 제어하도록 변경 | 기존 Pawn의 상태·소지품을 새 Pawn으로 복사 |
- Possess
- 바뀌는 연결: 권한 측 Controller가 제어할 Pawn을 선택자동으로 하지 않는 일: Pawn이나 이동 컴포넌트를 새로 만드는 작업
- UnPossess
- 바뀌는 연결: 현재 Controller와 Pawn의 제어 연결 해제자동으로 하지 않는 일: 두 객체를 모두 파괴하거나 Pawn의 모든 움직임 정지
- 다른 Pawn으로 전환
- 바뀌는 연결: 같은 Controller가 다른 몸체를 제어하도록 변경자동으로 하지 않는 일: 기존 Pawn의 상태·소지품을 새 Pawn으로 복사
GetPawn()과 GetController()가 의도한 상대인지 확인합니다. Controller의 로컬 제어 상태, PlayerState의 공유 상태, Pawn의 몸체 상태를 게임의 수명 정책에 맞춰 나눕니다.
이 예의 조건
- 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
- 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
| 범위 | 원문 |
|---|---|
| 관계·조건 설명 | 같은 Controller C와 기존 PawnA/B의 두 시점을 별도로 표현한다. 전환 전 C→A, 성공한 전환 후 C→B이며 선은 제어 관계 하나다. 생성·파괴·몸체 소지품 복사는 포함하지 않는다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| 기존 Possess C가 PawnA를 제어한다. |
|
|
| 대상 변경 제어 관계를 PawnB로 바꾼다. |
|
|
| 현재 상태 C의 현재 Pawn은 B이며 A/B는 독립 객체다. |
|
|
연결을 확인할 때는 Controller의 GetPawn()과 Pawn의 GetController()가 의도한 상대를 가리키는지 봅니다. 점수처럼 다른 클라이언트도 알아야 하는 플레이어 상태는 PlayerState 등 별도 책임에 둡니다.
예시: 같은 제어 주체가 다른 몸체를 고르기
권한 측의 Controller C가 기존 Pawn A를 제어하고 있고, 기존 Pawn B는 아직 제어자가 없다고 합시다. 게임의 전환 처리가 성공해 C가 B를 Possess한 뒤에는 C의 GetPawn()은 B, B의 GetController()는 C를 가리킵니다. 다른 제어자의 개입이 없다면 A의 제어 연결은 해제됩니다. A와 B를 새로 만들거나 파괴한 것이 아니며, A의 몸체에 보관한 소지품 3개가 B에 자동으로 복사되지도 않습니다. 상태를 어디에 유지하고 언제 옮길지는 별도 게임 규칙입니다.
직접 연결 판단하기
같은 C와 B의 연결에서 UnPossess만 호출했습니다. 다른 제어자·생성·파괴·상태 복사 처리는 없으며 두 객체는 유효하게 남아 있습니다. C의 GetPawn()과 B의 GetController()는 무엇을 가리킬까요? B에 독립적으로 동작하는 물리나 이동 로직이 있다면 UnPossess만으로 모든 움직임이 정지한다고 판단해도 될까요?
제어 연결과 수명의 풀이
서로의 제어 참조는 해제되어 두 조회 모두 더 이상 상대를 가리키지 않습니다. 이 조건에서는 null을 확인합니다. 객체는 그대로 남고, 빙의 해제는 독립 물리·이동 로직을 모두 끄는 명령이 아니므로 필요한 정지·입력 해제·상태 정리는 별도로 처리합니다.
Possess API는 권한 측 실행 조건을, Pawn은 기본 제어 관계와 스폰만으로 자동 빙의되지 않는 점을 설명합니다.
실제 게임에서의 예시
-
FPS 게임 플레이어
ACharacter: 플레이어가 직접 조종하는 캐릭터 (시각적인 모델, 움직임).APlayerController: 마우스/키보드 입력을 받아ACharacter를 움직이고 총을 발사하는 등 제어. HUD 표시.
-
NPC 적
ACharacter: 적 NPC의 시각적인 모델과 움직임.AAIController: 플레이어를 추적하거나 공격하는 AI 로직을 수행하고,ACharacter에게 이동 및 공격 명령을 내림.
-
차량 시뮬레이션
APawn: 차량의 물리 모델과 시각적인 메시.APlayerController: 키보드/게임패드 입력을 받아APawn(차량)을 조작.
몸체가 사람형 보행·점프·이동 예측을 필요로 하면 ACharacter를, 다른 이동 모델을 직접 조립하려면 APawn과 적합한 이동 컴포넌트를 검토합니다.