언리얼 Actor와 컴포넌트 구조 정리 (컴포지션, UPROPERTY, 이벤트 함수, Movement)
언리얼 Actor 학습 노트. 강의 3.1~3.7 개념만. 컴포넌트 구조, UPROPERTY 지정자, 이벤트 함수 순서 헷갈릴 때 다시 보기.
월드의 구성 요소
월드 = 레벨 + 모든 액터 + 시간 + 물리.
- 레벨: 3차원 공간(단위 cm). .umap 애셋. 플레이 시 Outliner에 기존 액터(흰색)와 동적 생성 액터(노란색)가 같이 보임
- 액터: 월드 구성 단위. 월드에 존재하므로 트랜스폼 항상 있음. 로직은 C++ 또는 블루프린트
- 시간: 단위 초. 흐르는 속도 조절 가능
- 물리: 액터 간 작용. Collision 정보 있어야 물리 작용 발생
왜 상속이 아니라 컴포지션인가
액터의 기능은 크게 셋: 시각적(메시), 물리적(충돌), 이동.
이걸 상속(Is-A)으로 짜면 상속이 깊어지고, 최상위 부모를 바꾸면 모든 자식이 영향받아 유지보수가 어려워짐. 컴포지션(Has-A)은 기능을 뗐다 붙였다 할 수 있음. 그래서 언리얼은 기능을 규격화한 컴포넌트를 액터에 조립하는 방식을 채택.
용어: 내가 소유한 UObject = SubObject, 나를 소유한 UObject = Owner. 액터는 컴포넌트 여러 개를 가질 수 있고, 그중 대표 하나가 반드시 루트 컴포넌트.
컴포넌트를 액터에 넣는 두 방식:
- 필수적 포함: CDO에 미리 생성해서 포함 → CreateDefaultSubobject<>()
- 선택적 포함: CDO엔 빈 포인터, 런타임에 생성 → NewObject<>(). 이 경우 RegisterComponent() 호출해야 월드 시간/물리에 등록됨
자주 쓰는 컴포넌트
- 스태틱메시: 애니메이션 없는 메시. 시각/물리
- 스켈레탈메시: 애니메이션 있는 메시. 시각/물리
- 콜리전: 구/박스/캡슐 물리 기능
- 무브먼트: 이동 기능
- 카메라: 플레이어 화면 출력
컴포넌트 상속 구조 함정
- 액터 컴포넌트 ← 씬 컴포넌트(트랜스폼 추가) ← 스태틱메시 컴포넌트
- 무브먼트 컴포넌트는 트랜스폼이 필요 없어서 씬 컴포넌트가 아니라 액터 컴포넌트를 상속
그래서 무브먼트 컴포넌트는 컴포넌트 계층 트리에 안 붙고 따로 떨어져 보임(SetupAttachment 안 함). "왜 무브먼트만 트리에 안 붙지?" 하면 이것 때문.
CreateDefaultSubobject 함정
생성자에서 컴포넌트 생성 시 전달하는 문자열은 컴포넌트 구별용 해시 생성에 쓰임. 다른 컴포넌트와 중복되면 안 됨. 보통 변수명과 동일하게 지정.
루트 설정은 SetRootComponent(), 나머지는 SetupAttachment(GetRootComponent())로 루트에 붙임.
TObjectPtr과 UPROPERTY
UE5부터 헤더의 UObject 포인터 멤버는 로우 포인터 대신 TObjectPtr 권장.
UPROPERTY()는 속성을 언리얼 런타임 시스템에 등록(GC/리플렉션/리플리케이션 혜택). 단 성능 영향 있으니 불필요한 속성엔 안 붙임.
핵심 함정: UObject 포인터 멤버에 UPROPERTY() 안 붙이면 GC 추적이 안 됨. 프리미티브 타입은 UPROPERTY() 붙이면 자동 초기화됨.
UPROPERTY 지정자 치트시트
- Visible / Edit: 에디터에서 수정 불가 / 가능
- Anywhere / DefaultsOnly / InstanceOnly: 편집 영역. 어디서나 / CDO(블루프린트 애셋)에서만 / 개체에서만
- BlueprintReadOnly / BlueprintReadWrite: 블루프린트에서 수정 불가 / 가능
- Category: Details 카테고리 분류
- Meta: 추가 지정자. AllowPrivateAccess(private 멤버를 블루프린트에 노출), BindWidget 등
조합 예 해석: EditDefaultsOnly + BlueprintReadOnly면 블루프린트 애셋에서만 수정, 개체별로는 못 바꿈. EditInstanceOnly + BlueprintReadWrite면 개체마다 다른 값 가능.
VisibleAnywhere로 에디터에서 본 값은 초기화 버튼/에디터 재시작 시 리셋됨. C++ 코드로 수정한 값은 리셋 안 됨. "에디터에서 바꿨는데 왜 초기화되지?" 하면 이 차이.
bCanEverTick: true면 Tick()이 매 프레임 호출. 성능 큰 영향이라 안 쓰면 false.
언리얼 자료형
C/C++은 플랫폼(32/64bit)마다 자료형 크기가 달라 파편화 문제. 언리얼은 크기 모호하지 않게 재정의(uint8, int32, float 등).
- FVector: 3개 값 묶음. 위치/크기. 내적·외적 등 연산자 재정의됨
- FRotator: 회전. Pitch(Y축, 좌우 기준), Yaw(Z축, 상하 기준), Roll(X축, 전후 기준)
- FTransform: 크기(FVector) + 회전(FRotator) + 위치(FVector). 모든 액터가 가짐
bool 함정: C/C++ bool은 크기 표준이 없음. Serialization/Replication과 관련된 bool은 uint8 + 비트필드(uint8 bIsDead : 1)로 1bit 자료형 만들어 대체. 무관하면 그냥 bool.
애셋 지정과 오브젝트 패스
모든 애셋은 레벨(.umap) 빼고 .uasset. C++에서 애셋을 불러오려면 고유 키가 필요한데, 언리얼은 경로를 키로 씀(애셋 클릭 후 Ctrl+C).
오브젝트 패스 형식: {오브젝트 타입}'{폴더}/{파일}.{애셋명}'. 오브젝트 타입과 작은따옴표 빼고 간단히 써도 됨. 프로젝트 내 유일 보장.
C++ 생성자에서 로딩: ConstructorHelpers::FObjectFinder<타입>. 경로는 런타임에 안 변하니 static. Succeeded() 확인 후 사용.
가장 중요한 함정: 코드에 오브젝트 패스 하드코딩은 비추천. 아트팀이 애셋을 수시로 옮기는데, 블루프린트에서 지정하면 이동돼도 Fix Up Redirectors로 자동 보정됨. 하드코딩하면 경로 깨짐.
이벤트 함수 호출 순서
게임 시작 시 액터는 준비 → 시작 → 삭제 과정. 자동 호출되는 함수가 이벤트 함수.
순서:
- PostInitializeComponents(): 모든 컴포넌트 초기화 후. 준비
- BeginPlay(): 액터 로직 시작. 한 번
- Tick(DeltaSeconds): 매 프레임. DeltaSeconds는 이전~현재 프레임 시간차
- EndPlay(EndPlayReason): 소멸 시
override 시 Super::함수() 먼저 호출 필수(엔진 루틴 보장). Tick 쓰려면 생성자에서 bCanEverTick = true.
프레임 독립적 움직임: Tick에서 속도에 DeltaSeconds 곱해야 함(RotationSpeed * DeltaSeconds). 안 그러면 프레임 수에 따라 속도가 달라짐.
Movement Component 종류
- FloatingPawnMovement: 중력 무시. 입력대로 자유 이동
- RotatingMovement: 지정 속도로 회전
- InterpMovement: 지정 위치로 이동
- ProjectileMovement: 중력 받는 탄도 운동. 총알/미사일
- CharacterMovementComponent: 캐릭터 전용. 걷기/수영/쪼그리기 등
회전을 Tick에서 직접 AddActorWorldRotation으로 짤 수도 있지만, RotatingMovementComponent를 붙이면 RotationRate만 설정하면 됨. 이 경우 Tick 로직 불필요(bCanEverTick = false 가능). 엔진이 제공하는 컴포넌트로 대체 가능한 건 직접 Tick 짜는 것보다 그쪽이 깔끔.
'학습 > Unreal' 카테고리의 다른 글
| 언리얼 Character와 시점 구현 정리 (Enhanced Input, Control Rotation, BackView/QuarterView) (0) | 2026.05.01 |
|---|---|
| 언리얼 Pawn과 게임플레이 프레임워크 정리 (GameMode, Controller, 입력, 애니메이션) (0) | 2026.05.01 |
| 언리얼 실무 도구 정리 (Interface, Delegate, FString, 컨테이너) (0) | 2026.04.28 |
| 언리얼 UObject 동작 원리 정리 (CDO, Reflection, GC, Serialization) (0) | 2026.04.27 |
| [실습] Pawn 클래스 3D캐릭터 만들기 (0) | 2026.04.16 |
