나만의 작은 도서관
[TIL][C++] 250819 MMO 서버 개발 82일차: BindWidget에 대한 오해, DataTable에서 JSON 파일을 임포트했을때, 데이터 데이블에 2D 텍스쳐 파일이 저장되도록 할 수 있을까? 본문
Today I Learn
[TIL][C++] 250819 MMO 서버 개발 82일차: BindWidget에 대한 오해, DataTable에서 JSON 파일을 임포트했을때, 데이터 데이블에 2D 텍스쳐 파일이 저장되도록 할 수 있을까?
pledge24 2025. 8. 20. 00:52주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다.
BindWidget에 대한 오해
- C++에서 위젯을 구성하는 컴포넌트를 끌고 와 사용하고 싶은 경우에 사용하려면 아래와 같이 사용한다.
UPROPERTY(meta=(BindWidget))
UTextBlock* textBlock;
- 이 방식을 사용하면 ‘사용한 컴포넌트는 블루프린트에 노출되지 않는다’고 알고 있었다. 그런데 그게 아니었다.
- 그저 UPROPERTY의 지정자를 아무것도 넣어주지 않았기 때문에 블루프린트의 그래프 탭에 노출되지 않았을 뿐이었다. 블루프린트에 노출시키는 BlueprintReadWrite와 같은 지정자를 추가해 주면 똑같이 그래프 탭에 해당 컴포넌트가 노출된다.
UPROPERTY(BlueprintReadWrite, meta=(BindWidget))
UTextBlock* textBlock;
DataTable에서 JSON 파일을 임포트했을때, 데이터 데이블에 2D 텍스쳐 파일이 저장되도록 할 수 있을까?
- 안 될 줄 알았는데 된다고 한다. 데이터 테이블의 칼럼 타입을 TObjectPtr 방식으로 지정하고 값으로 경로를 넣어주면 된다고 한다.
TObjectPtr?
- ObjectPtr은 언리얼에서 제공하는 오브젝트 포인터로, 언리얼 엔진 5.0에서 추가되었으며, UObject를 상속받는 객체를 가리키는 스마트 포인터의 일종이다. ObjectPtr은 C++의 일반 포인터(T*)와 유사하지만, 언리얼 엔진의 GC 시스템과 통합되어 메모리 관리가 자동으로 이루어진다는 장점이 있다.
TObjectPtr의 종류
TObjectPtr<T>
- 가장 기본적인 형태로, UObject 파생 클래스에 대한 강한 참조를 제공한다.
- Actor가 로딩될 때, 액터의 멤버변수로 TObjectPtr이 있다면 가리키는 오브젝트도 같이 로딩된다.
UPROPERTY()
TObjectPtr<AActor> MyActor;
// 사용 예시
MyActor = GetWorld()->SpawnActor<AActor>();
if (MyActor)
{
MyActor->Destroy();
}
TSoftObjectPtr <T>
- 약한 참조를 제공하며, 액터가 로딩되어도 가리키는 오브젝트를 같이 로딩하지 않으며, 직접 로드할 때 로딩된다.
- TObjectPtr과 다르게 가리키는 오브젝트가 로드되지 않았을 수 있기 때문에 IsValid으로 확인하고, LoadSynchronous로 로딩하고, Get()으로 가져온다.
UPROPERTY()
TSoftObjectPtr<UTexture2D> SoftTexture;
// 사용 예시
if (SoftTexture.IsValid())
{
UTexture2D* LoadedTexture = SoftTexture.LoadSynchronous();
}
TWeakObjectPtr <T>
- 약한 참조를 제공하지만, TSoftObjectPtr과 달리 이미 메모리에 로드된 오브젝트만 참조할 수 있다.
UPROPERTY()
TWeakObjectPtr<AActor> WeakActor;
// 사용 예시
if (WeakActor.IsValid())
{
WeakActor->SomeFunction();
}
TSoftObjectPtr들은 생성자로 경로 문자열을 받는다.
- TSoftObjectPtr는 생성자로 에셋 경로를 넣은 TEXT를 넣어주면 해당 경로에 존재하는 에셋을 가리키게 된다.
// 문자열 경로로 직접 생성
TSoftObjectPtr<UTexture2D> SoftTexture(TEXT("/Game/Textures/MyTexture.MyTexture"));
// FSoftObjectPath를 이용한 생성
FSoftObjectPath TexturePath(TEXT("/Game/Textures/MyTexture.MyTexture"));
TSoftObjectPtr<UTexture2D> SoftTexture(TexturePath);
- 이 방식을 이용해 데이터 테이블의 칼럼 타입을 TSoftObjectPtr로 해두고, JSON의 값에는 경로를 넣어주면 DataTable에서 JSON을 임포트 할 때 곧바로 에셋을 가리키게 된다.
// JSON
{
...
Icon : "/Game/Textures/MyTexture.MyTexture"
}
// DataTable에서는 Icon을 TSoftObjectPtr타입으로 설정
경로를 작성할 때 주의할 점: Content가 상대경로의 시점이며, Game이 곧 Content를 의미한다.
- 에셋들은 Content에 포함되어 있을 텐데, 이때 경로를 적을 때 아래와 같이 적어야 한다.
// 실제 경로: Content/UI/Icons/Sword_Icon.uasset
// 경로 문자열: /Game/UI/Icons/Sword_Icon.Sword_Icon
경로를 작성할 때 주의할 점: Sword_Icon.Sword_Icon와 같은 형태로 적어줘야 한다.
- 이게 “패키지명. 오브젝트명”이라는데, 잘은 모르겠고 그냥 경로 문자열을 적을 때 이름을 반복해서 적어줘야 경로가 제대로 설정된다. 뒷부분을 빼먹으면 경로가 제대로 인식되지 않는다. (예시는 위 코드 참고)
