쾌락없는 책임 (공부)/Unreal

[Unreal] Unreal Engine 5 TObjectPtr

허스크 2022. 9. 20. 18:06
반응형

개요

 언리얼 4에서 하던 프로젝트가 왜인지는 모르겠으나 맛이 가버려서 이참에 언리얼 5를 공부해보자는 생각으로 받아서 해보는 도중, 기본 캐릭터에게서 TObjectPtr이라는 단어를 보게 되었습니다. 찾아보니 언리얼 5에서 기존의 원시 포인터를 대체하기 위한 UObject용 포인터라고 하는데 이참에 이걸 좀 더 알아보기 위해서 찾아본 것들을 글로 작성하게 되었습니다.

 

 

원시 포인터를 대체하는 TObjectPtr, 일단 선언 제외 사용법이 같다

 

언리얼 엔진 5 마이그레이션 가이드

언리얼 엔진 4 프로젝트로 언리얼 엔진 5로 이주하는 방법 및 요구 사항.

docs.unrealengine.com

 일단 TObjectPtr과 관련한 이야기는 공식 문서 중에서 '4->5로 마이그레이션'하는 문서에서 볼 수 있었습니다. 기존 4 버전을 사용하는 사람들을 위해서 작성되었다는 게 보였습니다. 언리얼이 32비트를 더 이상 지원하지 않음과 동시에 생기는 64비트 포인터 시스템으로 일단 원시 포인터와 동일한 역할을 한다고 합니다.

// Character.h
UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
TObjectPtr<UCapsuleComponent> CapsuleComponent;

// Character.cpp 의 생성자
CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(ACharacter::CapsuleComponentName);

 위 코드가 기본 내장 Character 클래스의 모습인데 위 경우 선언이 TObjectPtr로 되어있다를 제외하고는 생성도 같고 사용법도 같았습니다.

// SetupAttatchment의 시그니처
void USceneComponent::SetupAttachment(class USceneComponent* InParent, FName InSocketName)

// Character.cpp에서 위 함수를 사용하는 모습
ArrowComponent->SetupAttachment(CapsuleComponent);

 보면 프록시 패턴과 비슷하게 처리해놓은걸 볼 수 있습니다. 스마트 포인터와 유사하게 사용할 수 있죠. 자동으로 형변환이 되기에 더더욱 사용에서 차이점을 느낄 수 없게 됩니다.

FORCEINLINE T* Get() const { return (T*)(FObjectPtr::Get()); }
FORCEINLINE T* operator->() const { return Get(); }
FORCEINLINE T& operator*() const { return *Get(); }

 

 

그러면 TObjectPtr은 뭐가 다를까?

일단 공식문서의 이야기를 보면 기존에 사용하고 있던 UObject 원시 포인터보다 TObjectPtr을 사용하는걸 권장한다고 합니다. 이는 에디터 내에서 다이내믹 해상도와 액세스 트래킹을 추가한다고 하며 비 에디터(빌드)시에는 원시 포인터와 같은 역할을 한다고 하네요.

 

 그리고 UFUCTION()으로 선언한 곳에서는 인자로 TObjectPtr을 받지 못한다는 이슈가 있으니 참고하실 분들은 알아보시면 될 거 같습니다.

 

UFunctions cannot take a TObjectPtr as a parameter. Why?

I have a method: UFUNCTION() void SpawnLoadedActors(TObjectPtr<UGnarlGameInstance> GameInstance); This gives a compiler error: UFunctions cannot take a TObjectPtr as a parameter. If I remove UFUNCTION(), it compiles fine. I admit that I don’t understand

forums.unrealengine.com

 

 뭐 이야기를 들어보니...일단 대체하라는 걸 에픽에서 하라고 하니 하긴 해야 되는데... 왜 이러는지는 납득할만한 이유가 공식문서에서 없었습니다.

 

Good catch! If I must do it, then I must do it lol (아ㅋㅋ 까라면 까야지)
- Epic Dev Community

 라고 합니다.

 

 뭐 이제 기반이 되는 모든 함수, 클래스 등들이 TObjectPtr로 대체되기 때문에 이를 따르는 건 사실 당연한 이야길 수 있습니다. 그러니 이를 따르는 것도 중요한 숙제가 되겠죠.

 

 그 외 "엑세스 트래킹"이라고 하면 개체가 사용되는 시점을 감지하는 것으로 입력 스트림의 어떤 위치에 어떤 객체를 넣을지 결정하는 데 사용할 수 있으며 액세스 순서대로 객체를 넣을 수 있다고 합니다. 그리고 에디터, 디버그 모드에서 검사를 추가해 잘못된 포인터를 할당하려고 할 때 충돌이 발생하지 않고 발생한 위치를 볼 수 있다고 합니다.

 이건 언리얼 포럼에서 엔진 기여자의 이야기인데 아무튼 기존의 원시포인터보다 좋다고 하니... 일단 이를 따라서 앞으로의 선언에서 원시 포인터를 버려야 할 이유는 충분할 것 같습니다.

 

Why should I replace raw pointers with TObjectPtr?

I am reading the UE5 migration guide (Migration Guide | Unreal Engine Documentation), and I see that TObjectPtr is now recommended over raw pointers. But the only thing the guide says about what this new type does is this: This system adds dynamic resoluti

forums.unrealengine.com

 아직까지는 이와 관련된 핵심적인 이야기가 많이 없기도 하고 찾지 못해서 더 적지는 못했는데 일단 이 정도로 마무리하고 앞으로 포인터 선언에 앞서 명심해야 되겠네요.

반응형