Actor와 Scene Component
6강. Actor와 Scene Component
1. 이번 강의에서 해결할 문제
Actor 안의 Mesh와 감지 영역 위치를 각각 수동 계산하면 Actor를 이동할 때 구성 요소가 어긋납니다. Scene Component 계층으로 상대 Transform을 구성합니다.
2. 학습 목표
3. 핵심 개념
Actor는 World에 존재하는 컨테이너입니다. Actor Component는 체력처럼 위치가 필요 없는 기능을, Scene Component는 위치·회전·크기를 가진 계층 노드를 표현합니다. Primitive Component는 Scene Component에 충돌과 렌더링 기능을 더합니다.
기본 Subobject는 생성자에서 만들어 모든 C++ 자식과 Blueprint 자식이 같은 구조를 갖게 합니다. 런타임마다 달라지는 임시 Component를 생성자에 조건부로 만들지 않습니다.
용어 정리
| 용어 | 무엇인가 | 예시 |
|---|---|---|
| Transform | 위치(Location)·회전(Rotation)·크기(Scale)를 묶은 공간 정보 | Actor의 월드 위치, Mesh의 Root 기준 위치 |
| RootComponent | Actor Transform의 기준이 되는 최상위 Scene Component | 이 강의의 SceneRoot |
| Local/Relative Transform | 부모 Component를 기준으로 저장한 Transform | MarkerPoint가 Root보다 Z로 100 위 |
| World Transform | 모든 부모 Transform을 합성한 최종 공간 정보 | 회전된 Actor 안에서 MarkerPoint가 실제 World에 놓이는 위치 |
| Default Subobject | C++ 생성자에서 만들어 클래스 구조의 일부가 되는 Component | TargetMesh, MarkerPoint |
Scene Component라고 모두 화면에 그려지는 것은 아닙니다. USceneComponent는 공간상의 점과 계층만 제공하므로 MarkerPoint 자체는 보이지 않습니다. UStaticMeshComponent처럼 Primitive Component 계열이 Mesh·Material과 렌더링 기능을 제공해야 Game 화면에 보입니다.
어떤 기능을 Component로 만들지는 위치 필요 여부로 먼저 판단합니다.
- 체력·인벤토리처럼 공간 위치가 필요 없으면
UActorComponent가 자연스럽습니다. - 감지 위치·카메라 기준점처럼 Transform이 필요하면
USceneComponent가 필요합니다. - 화면 표시나 충돌까지 필요하면
UPrimitiveComponent하위 타입을 선택합니다.
4. 단계별 실습
파일 경로: Source/TopDownSurvival/Actors/SurvivalTarget.h
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<USceneComponent> SceneRoot;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UStaticMeshComponent> TargetMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<USceneComponent> MarkerPoint;
파일 경로: Source/TopDownSurvival/Actors/SurvivalTarget.cpp
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
ASurvivalTarget::ASurvivalTarget()
{
PrimaryActorTick.bCanEverTick = true;
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
SetRootComponent(SceneRoot);
TargetMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TargetMesh"));
TargetMesh->SetupAttachment(SceneRoot);
MarkerPoint = CreateDefaultSubobject<USceneComponent>(TEXT("MarkerPoint"));
MarkerPoint->SetupAttachment(SceneRoot);
MarkerPoint->SetRelativeLocation(FVector(0.0, 0.0, 100.0));
}
코드 한 줄씩 이해하기
CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"))는 모든 ASurvivalTarget 인스턴스가 가질 기본 Root 후보를 생성합니다. 이름은 한 소유 객체 안에서 고유해야 합니다.SetRootComponent(SceneRoot)는 Actor의 위치·회전·크기 기준을 명시합니다.TargetMesh->SetupAttachment(SceneRoot)는 Mesh의 부모를 Root로 예약합니다. 이후 Mesh의 Relative Transform은 SceneRoot 기준입니다.MarkerPoint도 같은 Root 아래에 두므로 Mesh와 형제 관계입니다.SetRelativeLocation(FVector(0.0, 0.0, 100.0))은 Unreal 단위 기준으로 Root보다 Z축 위쪽 100에 배치합니다. 기본 단위 설정에서는 보통 100 Unreal Unit을 1m로 해석하지만 프로젝트 단위 설정을 확인해야 합니다.TObjectPtr와UPROPERTY는 멤버 UObject 참조를 엔진의 직렬화·참조 추적에 참여시킵니다. 일반 C++ 소유 포인터처럼 직접delete하지 않습니다.
Component 계층은 Blueprint Editor의 Components 패널에서 다음처럼 보여야 합니다.
SceneRoot (Root)
├─ TargetMesh
└─ MarkerPoint
Blueprint Editor에서 설정하고 결과 확인
- C++ 컴파일 후 BP_SurvivalTarget을 열고 Components 패널이 위 계층인지 확인합니다.
TargetMesh를 선택하고 Static Mesh 슬롯에Engine/BasicShapes/Cube를 지정합니다. 보이지 않으면 Content Browser 설정에서 Show Engine Content를 켭니다. 메뉴 이름은 엔진 버전에 따라 달라질 수 있습니다.MarkerPoint를 선택해 Relative Location이(0, 0, 100)인지 확인합니다. MarkerPoint는 렌더링 Component가 아니므로 점 자체가 Game 화면에 안 보이는 것이 정상입니다.- Blueprint를 Compile·Save하고 레벨에 배치합니다. 이제 4강과 달리 Cube가 회전하는 모습이 보여야 합니다.
- Actor 전체를 X로 200 이동하면 Mesh와 MarkerPoint의 World 위치가 함께 200 이동하지만 각자의 Relative Location은 유지되어야 합니다.
5. 코드가 동작하는 이유
SceneRoot가 Actor Transform의 기준이 되고 자식 Component는 부모에 대한 상대 Transform을 저장합니다. SetupAttachment는 기본 구성 단계에서 부모를 선언합니다. TObjectPtr는 UObject 멤버 참조를 표현하며 UPROPERTY와 함께 GC와 에디터 직렬화가 참조를 추적하게 합니다. 자세한 수명 규칙은 10강에서 다룹니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
실습 목표
Root와 자식 Component의 상대 Transform을 구성하고, 부모 이동·회전 시 World Transform이 어떻게 달라지는지 확인합니다.
시작 전 상태
BP_SurvivalTarget의 TargetMesh에 Cube가 연결되고, Component 계층이 SceneRoot > TargetMesh, MarkerPoint인지 확인합니다. Blueprint Compile·Save 후 레벨에 한 개만 배치합니다.
1단계: 가장 작은 확인
MarkerPoint의 Relative Location을 (0, 0, 100)에서 (0, 0, 200)으로 바꾸고 Details의 World Location 변화를 확인합니다. Actor와 Root가 회전하지 않았다면 Z도 100만큼 증가해야 합니다. 확인 후 100으로 되돌립니다.
2단계: 값을 바꾸고 결과 비교
레벨의 Actor를 X축으로 200 이동합니다. TargetMesh와 MarkerPoint의 World X는 함께 200만큼 변하지만 Relative Location은 그대로여야 합니다. Local과 World 값을 표로 나란히 기록하세요.
3단계: 직접 적용
C++에 LeftMarkerPoint, RightMarkerPoint 두 USceneComponent를 추가하고 SceneRoot에 부착한 뒤 Y를 각각 -100, 100으로 둡니다. 완성 코드 대신 기존 MarkerPoint의 선언·생성·부착 세 단계를 패턴으로 사용합니다.
4단계: 스스로 확인
SceneRoot 또는 Actor를 Yaw 45도로 회전해 두 Marker의 World 위치가 회전하는지 확인합니다. Relative 좌표는 그대로지만 World 좌표는 부모 회전을 합성하므로 달라져야 합니다.
막혔을 때
| 증상 | 원인 | 해결 |
|---|---|---|
| Blueprint Components 패널에 새 Component가 없음 | C++ 컴파일 실패 또는 오래된 Blueprint 상태 | Editor Target 빌드 성공을 확인하고 Blueprint를 다시 엽니다. |
| Cube가 보이지 않음 | Static Mesh 미지정, 카메라 밖, 숨김 상태 | TargetMesh의 Mesh·Visible·Transform과 카메라 위치를 확인합니다. |
| Marker가 화면에 보이지 않음 | USceneComponent는 렌더링하지 않음 | Components 패널과 Transform 값으로 확인하거나 학습용 시각화 Component를 별도로 사용합니다. |
| 자식이 부모를 따라오지 않음 | SetupAttachment 누락 또는 다른 부모 지정 | 생성자에서 각 자식의 부모가 SceneRoot인지 확인합니다. |
8. 이해 점검 질문 3개
9. 핵심 요약
다음 강의 연결
다음 강의에서는 Static Mesh와 Collision 설정을 구체화해 “보이는 Component”와 “부딪히는 Component”의 역할을 분리합니다.
Actor와 Scene Component 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.