2026-04-20(월) TObjecPtr, RootComponent, Relative vs World, ActorComponent, Axis Mappings

조범근·2026년 4월 20일

TIL

목록 보기
46/81

C++ Week 9

Study

언리얼C++ 기초, 알고리즘 1문제


Today I Learned


UnrealC++

TObjectPtr

문득 UBoxComponent같은 것들이 그냥 UBoxComponent* BoxComponent로 관리되어도 UPROPERTY의 관리를 받아 리플렉션 시스템과 GC시스템을 이용할 수 있는데 굳이 TObjectPtr<UBoxComponent>로 하는 이유가 궁금해졌다.

UE5에서 TObjectPtr이 도입된 핵심 이유는 바로 에디터에서의 성능과 관리 때문이다.

  • 지연 로딩(Lazy Loading) : 에디터에서 수많은 액터와 에셋을 불러올 때, 모든 것을 한꺼번에 메몰ㅣ에 올리면 엄청 무겁기때문에 TObjectPtr은 해당 데이터가 진짜로 필요할 때까지 로딩을 미루거나, 에셋의 상태를 더 정교하게 관리할 수 있는 기능을 내장하고 있다.

  • 액세스 추적(Access Tracking) : 이 포인터가 언제 참조되는지, 에디터 상에서 어떤 상태인지 시스템이 더 똑똑하게 감시할 수 있게 해준다.

클래스 멤버 변수는 무조건 TObjectPtr<T>를 사용하고 함수 내부의 지역 변수나 매개변수로는 RawPointer를 사용한다.





어떤걸 RootComponent 두면 좋을까

SceneComponent가 대체적으로 RootComponent로 두는걸 알지만, 그냥 BoxComponent를 RootComponent로 두는 경우도 보았다. 어떤 상황에 따라 사용 하면 좋을까?

SceneComponent를 Root로 두는 방식은 Root는 기준점만 담당하고, 충돌/메시를 자식으로 유연하게 붙일 수 있다는 장점이있다.

BoxComponent를 Root로 두는 방식은 충돌 박스가 이 액터의 핵심이면 간편하게 사용 할 수있다.

즉, 충돌 박스가 본체인 트리거/상자/판정용 액터면 BoxComponent
기준 축이 필요하고 충돌/메시를 나중에 갈아끼울 수도 있는 일반 액터면 SceneComponent





Relative vs World

RelativeRotation, RelativeLocation 자꾸 나와서 궁금해졌다.

Relative Location (상대 위치) -> 내 앞 1m, 내 옆자리 같은 개념

World Location (절대 위치) -> 월드의 절대적인 좌표 세상어디에 있든 변하지 않는 절대적인 주소

언리얼의 캐릭터는 보통 여러 Component가 계층 구조로 묶여 있다. 예를들어 부모의 RootComponent가 있고 자식에 Mesh, Camera이 있다고 하자. 여기서 캐릭터가 좌표를 확 이동하면 World Location은 바뀌지만 Mesh, Camera는 여전히 캐릭터 옆에 붙어있다. 이때 Relative Location(0, 0, 0) 으로 유지되는 것이다.

SetRelativeLocation은 부모를 기준으로 내가 어디쯤 떨어져 있을지를 정하는 함수





ActorComponent

ActorComponent는 좌표가 없고 논리만 있는 컴포넌트이다. 액터에게 특정 능력을 부여한다고 생각하면 된다.

URotatingMovementComponent -> 액터를 지정한 속도로 계속 회전시킨다. (아이템, 회전 장애물 등)

UProjectileMovementComponent -> 액터를 발사체처럼 날아가게 한다. 중력, 도탄, 유도탄 기능을 내장하고있다. (총알,화살,미사일 등)

UInterpToMovementComponent -> 지정된 지점 사이를 왔다 갔다 하거나 부드럽게 이동합니다. (움직이는 발판, 엘리베이터 등)

UFloatingPawnMovement -> 중력 영향을 받지 않는 단순한 공중 이동 기능을 제공한다. (비행 몬스터, 드론 등)

UAIPerceptionComponent -> AI에게 시각, 청각 등의 감각을 부여한다. 적을 발견하거나 소리를 듣는 로직을 짤때 사용 가능

UPawnNoiseEmitterComponent -> 캐릭터가 소리를 내게 만든다. 이 소리를 AI가 감지할 수 있다.

UCharacterMovementComponent -> 걷기, 뛰기, 점프, 수영, 낙하 등 모든 복잡한 이동 로직이 들어있다. (ACharacter 클래스에 기본 내장되어있다.)





Axis Mappings

void AUSPlayerPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	
	PlayerInputComponent->BindAxis(TEXT("UpDown"), this, &ThisClass::UpDown);
	PlayerInputComponent->BindAxis(TEXT("LeftRight"), this, &ThisClass::LeftRight);
}

Axis Mappings는 UE5 전에 사용하던 Mapping방법이다.

UInputComponent* PlayerInputComponent

이 Pawn이 입력을 받을 때 사용하는 입력 바인딩 컨테이너이다. 쉽게말하면

키보드 입력 -> InputComponent -> 바인딩 된 함수 호출

PlayerInputComponent는 어떤 입력이 들어왔을 때 어떤 함수를 실행할지 연결하는 중간 관리자다.


입력흐름

키 입력 (W, A, S, D)

Project Settings -> Axis Mapping

"UpDown", "LeftRight" 이름으로 값 생성

값 (-1 ~ 1) 계산

InputComponent

BindAxis로 연결된 함수 호출

UpDown(float Value), LeftRight(float Value)


BindAxis

PlayerInputComponent->BindAxis(TEXT("UpDown"), this, &ThisClass::UpDown);
PlayerInputComponent->BindAxis(TEXT("LeftRight"), this, &ThisClass::LeftRight);

TEXT(" ") 큰 따옴표 안에 들어온게 아까 Axis Mapping에서 설정한 것이다. 여기에 해당하는 키에 입력이 들어오면 this객체의 &ThisClass::함수를 호출해라

this = AUSPlayerPawn 인스턴스 = 이 Pawn 객체에서 함수를 실행해라 라는 뜻





Possess

Possess는 Controller가 특정 Pawn을 자신의 조작 대상으로 연결할때이다. Actor같은 Object는 월드에 존재하는 기본 객체지만, Pawn은 Controller에게 Possess될 수 있는 Actor이다. PlayerController나 AIController가 Pawn을 Possess하면, 그 Pawn은 플레이어 입력이나 AI 판단에 의해 움직일 수 있는 대상이 된다.

즉 Possess는 단순한 초기화가 아니라 “누가 이 Pawn을 조종할 것인가”를 정하는 연결 과정이다.





EnhancedInput과 .uproject, Build.cs

EnhancedInput을 사용하려면 .uprojectBuild.cs를 둘다 수정해야 한다. 이유는 EnhancedInput은 플러그인이기때문이다. 그렇지만 외부에서 사는 플러긍ㅣㄴ이 아니라, 엔진에 기본 포함된 플러그인이다.

그럼 왜 기본인데 꺼져있을까

이유는 성능과 모듈화때문이다. 안 쓰는 기능까지 다 켜놓으면 빌드 느려짐, 의존성 꼬임, 관리 어려움 등의 문제가 있다.

즉, Enhanced Input은 엔진에 이미 들어있는 플러그인이지만, 직접 켜야 쓸 수 있는 구조

0개의 댓글