unreal 5기

251028 언리얼엔진 본캠프 54일차 TMap

parkjinnam 2025. 10. 28. 20:46

TMap

std::map은 예전에 블로그 글을 통해서 다룬 적이 있다. 내부적으로 이진탐색트리 중 하나인 Red-Black 트리를 사용하여 값이 계속 추가되어도 RB트리만의 규칙 때문에 균형이 유지되며 최악의 경우에도 O(logN)의 시간복잡도를 가지는 이점이 있어 위치를 모르는 값의 위치를 찾을 때 유용하게 사용할 수 있다는 것이 글의 요지 었다. 언리얼엔진에도 그동안 배웠던 UStruct와 UClass와 같이 기존의 C++에서 제공하는 map과 비슷한 TMap이라는 것이 존재한다.

 

TMap은 언리얼 엔진에서 제공하는 C++컨테이너 클래스로 map과 동일하게 Key와 Value를 쌍으로 묶어 저장하는 연관 컨테이너이다. TMap은 내부적으로 해시 테이블로 구현되어 있어 O(1)의 시간 복잡도를 갖게된다. 최악의 경우 O(N)이라는 시간 복잡도를 갖게 되지만 이는 키를 해시로 전환하는 과정에서 충돌이 일어나는 경우에 발생하게 된다.

 

언리얼에서는 왜 TMap을 사용해야 하는가?

왜 멀쩡한 std::map을 냅두고 TMap을 만들어서 사용하는 걸까? 이는 언리얼의 핵심 시스템과의 연관성이 있기 때문이다.  일단 첫 번째로는 UPROPERTY를 지원한다는 것이다 TMap을 UPROPERTY 매크로를 통해서 리플렉션시스템에 등록할 수 있으며 에디터에서의 편집이 가능해진다. 또한 TMap이 UObject에 대한 포인터를 값으로 가질 때 UPROPERTY로 표시하면 GC의 대상이 되어 이 자동으로 메모리를 관리해 준다. 또한 성능상으로도 평균 O(1)의 복잡도로 O(log N)의 복잡도를 보이는 std::map에 비해서 빠르기에 이점을 갖고 있다.

 

주의사항

앞서 TMap이 UObject 포인터를 값으로 가질 경우 UPROPERTY를 선언하여 GC의 대상이 될 수 있다고 했는데 사실 UObject포인터를 값으로 갖게 할 경우 반드시 TMap을 UPROPERTY()로 선언해야 한다. 또한 임의의 키를 찾아야 할 때 [] 연산자의 사용보다는 Find()의 사용이 권장된다. 만약 TMap [2]라 했을 때 2에 해당하는 키가 존재하지 않을 시 새 항목을 생성해 버리며  때문에 해당하는 키가 존재하지 않을 경우 nullptr을 반환하는 Find()의 사용이 권장된다. 또한 FindChecked()는 키가 반드시 존재한다고 가정하여 없으면 크래시를 발생시킨다.