[이득우의 언리얼] 11. 언리얼 컨테이너 라이브러리 - 구조체, Map

2026. 2. 8. 14:11·기타/[강의] 이득우의 언리얼 프로그래밍 Part1

개요

이번 강의에서는 Unreal Engine의 구조체(Struct)의 특징을 이해하고, 마지막 핵심 컨테이너인 TMap의 내부 구조와 활용 방법을 학습합니다. TArray, TSet, TMap 세 가지 컨테이너의 장단점을 비교하여 상황에 맞는 최적의 자료구조를 선택하는 방법을 익힙니다.

 

학습 목표

- Unreal 구조체의 선언 방법과 특징 이해

- TMap의 내부 구조 파악 및 활용 방법 학습

- TArray, TSet, TMap의 장단점 비교 및 적재적소 활용

- 커스텀 구조체를 해시 기반 컨테이너에서 사용하는 방법 획득

 


 

Unreal 구조체 (USTRUCT)

개념 및 특징

: **구조체(USTRUCT)**는 데이터를 저장하고 전송하는 데 특화된 가벼운 객체입니다.

 

UObject vs USTRUCT

 

구조체 vs 클래스

// ✅ 구조체 사용 (데이터 중심)
USTRUCT()
struct FPlayerStats
{
    GENERATED_BODY()
    
    UPROPERTY()
    int32 Health;
    
    UPROPERTY()
    int32 Mana;
    
    UPROPERTY()
    float Speed;
};

// ✅ 클래스 사용 (로직 중심)
UCLASS()
class UPlayerComponent : public UActorComponent
{
    GENERATED_BODY()
    
public:
    UFUNCTION()
    void TakeDamage(float Damage);
    
    UFUNCTION()
    void Heal(float Amount);
    
private:
    UPROPERTY()
    FPlayerStats Stats;  // 구조체를 멤버로 포함
};

 

리플렉션 관련 오브젝트 계층 구조

 

Algo::Transform 활용

#include "Algo/Transform.h"

void UMyGameInstance::Init()
{
    Super::Init();
    
    // 1. 구조체 배열 생성
    TArray<FStudentData> StudentDatas;
    for (int32 i = 1; i <= 300; ++i)
    {
        StudentDatas.Emplace(MakeRandomName(), i);
    }
    
    // 2. 이름만 추출 (TArray)
    TArray<FString> AllStudentNames;
    Algo::Transform(StudentDatas, AllStudentNames, 
        [](const FStudentData& Student)
        {
            return Student.Name;
        });
    
    UE_LOG(LogTemp, Log, TEXT("모든 학생 이름의 수: %d"), AllStudentNames.Num());
    // 출력: 300
    
    // 3. 이름만 추출 (TSet - 중복 제거)
    TSet<FString> AllUniqueNames;
    Algo::Transform(StudentDatas, AllUniqueNames,
        [](const FStudentData& Student)
        {
            return Student.Name;
        });
    
    UE_LOG(LogTemp, Log, TEXT("중복 없는 학생 이름의 수: %d"), AllUniqueNames.Num());
    // 출력: 64 (4 × 4 × 4 조합)
}

 

구조체를 TSet/TMap에서 사용하기

TSet<FStudentData> StudentSet;
// 컴파일 에러: GetTypeHash가 정의되지 않음!
해결방법 : operator==와 GetTypeHash 구현
USTRUCT(BlueprintType)
struct FStudentData
{
    GENERATED_BODY()
    
public:
    FStudentData()
        : Name(TEXT("학생"))
        , Order(0)
    {
    }
    
    FStudentData(const FString& InName, int32 InOrder)
        : Name(InName)
        , Order(InOrder)
    {
    }
    
    /** 이름 변수입니다. */
    UPROPERTY()
    FString Name;
    
    /** 순번 변수입니다. */
    UPROPERTY()
    int32 Order;
    
    // ===== TSet/TMap 사용을 위한 필수 함수 =====
    
    /** 동등 비교 연산자입니다. */
    bool operator==(const FStudentData& Other) const
    {
        // 순번이 같으면 같은 학생으로 간주
        return Order == Other.Order;
    }
    
    /** 해시 함수입니다 (friend 함수). */
    friend uint32 GetTypeHash(const FStudentData& Student)
    {
        // Order의 해시값을 구조체의 해시값으로 사용
        return GetTypeHash(Student.Order);
    }
};

 

TMap - 키 - 값 자료구조

개념 및 특징

TMap은 키(Key)와 값(Value) 쌍으로 데이터를 저장하는 해시 테이블 기반 자료구조입니다.

 

내부 구조

- TSet을 기반으로 구현

- Element가 TPair<Key, Value>로 구성

- 해시 테이블 + 동적 배열 (TSet과 동일)

 

STL map vs Unreal TMap

 

검색

더보기
TMap<int32, FString> StudentMap = 
{
    {1, TEXT("Alice")},
    {2, TEXT("Bob")},
    {3, TEXT("Charlie")}
};

// Contains - 존재 확인
bool bHasKey = StudentMap.Contains(2);  // true

// Find - 포인터 반환 (O(1))
FString* Found = StudentMap.Find(2);
if (Found)
{
    UE_LOG(LogTemp, Log, TEXT("Found: %s"), **Found);
}

// ⚠️ 비효율적 패턴 (2번 검색)
if (StudentMap.Contains(2))  // 1번 검색
{
    FString Name = StudentMap[2];  // 2번 검색
}

// ✅ 효율적 패턴 (1번 검색)
if (FString* Name = StudentMap.Find(2))
{
    UE_LOG(LogTemp, Log, TEXT("Name: %s"), **Name);
}

// FindOrAdd - 없으면 추가 후 반환
FString& Name = StudentMap.FindOrAdd(5);
Name = TEXT("Eve");

// FindKey - 값으로 키 역검색 (O(n), 느림!)
const int32* FoundKey = StudentMap.FindKey(TEXT("Bob"));

순회

더보기
TMap<int32, FString> StudentMap = 
{
    {1, TEXT("Alice")},
    {2, TEXT("Bob")},
    {3, TEXT("Charlie")}
};

// Range-based for loop (키-값 페어)
for (const TPair<int32, FString>& Pair : StudentMap)
{
    UE_LOG(LogTemp, Log, TEXT("ID: %d, Name: %s"), 
           Pair.Key, *Pair.Value);
}

// 구조화된 바인딩 스타일 (C++17)
for (const auto& [ID, Name] : StudentMap)
{
    UE_LOG(LogTemp, Log, TEXT("ID: %d, Name: %s"), ID, *Name);
}

// 반복자 사용
for (auto It = StudentMap.CreateConstIterator(); It; ++It)
{
    UE_LOG(LogTemp, Log, TEXT("Key: %d, Value: %s"), 
           It->Key, *It->Value);
}

삭제

더보기
TMap<int32, FString> StudentMap = 
{
    {1, TEXT("Alice")},
    {2, TEXT("Bob")},
    {3, TEXT("Charlie")}
};

// Remove - 키로 제거
int32 RemovedCount = StudentMap.Remove(2);  // 1 반환

// RemoveAndCopyValue - 제거하면서 값 복사
FString RemovedValue;
if (StudentMap.RemoveAndCopyValue(1, RemovedValue))
{
    UE_LOG(LogTemp, Log, TEXT("Removed: %s"), *RemovedValue);
}

// Empty - 모두 제거
StudentMap.Empty();

// Reset - 메모리 유지하고 비우기
StudentMap.Reset();

유틸리티 함수

더보기
TMap<int32, FString> StudentMap = 
{
    {1, TEXT("Alice")},
    {2, TEXT("Bob")},
    {3, TEXT("Charlie")}
};

// Num - 요소 개수
int32 Count = StudentMap.Num();  // 3

// IsEmpty - 비어있는지
bool bEmpty = StudentMap.IsEmpty();  // false

// GenerateKeyArray - 모든 키 추출
TArray<int32> Keys;
StudentMap.GenerateKeyArray(Keys);
// Keys: {1, 2, 3} (순서 보장 안 됨)

// GenerateValueArray - 모든 값 추출
TArray<FString> Values;
StudentMap.GenerateValueArray(Values);
// Values: {TEXT("Alice"), TEXT("Bob"), TEXT("Charlie")}

'기타 > [강의] 이득우의 언리얼 프로그래밍 Part1' 카테고리의 다른 글

[이득우의 언리얼] 12. 언리얼 엔진의 메모리 관리  (0) 2026.02.09
[이득우의 언리얼] 10. 언리얼 컨테이너 라이브러리 - TArray, TSet  (0) 2026.02.07
[이득우의 언리얼] 9. 언리얼 C++ 설계 - 델리게이트  (0) 2026.02.06
[이득우의 언리얼] 8. 언리얼의 C++ 설계 - 컴포지션  (0) 2026.02.06
[이득우의 언리얼] 7. 언리얼 C++ 설계 - 인터페이스  (0) 2026.02.04
'기타/[강의] 이득우의 언리얼 프로그래밍 Part1' 카테고리의 다른 글
  • [이득우의 언리얼] 12. 언리얼 엔진의 메모리 관리
  • [이득우의 언리얼] 10. 언리얼 컨테이너 라이브러리 - TArray, TSet
  • [이득우의 언리얼] 9. 언리얼 C++ 설계 - 델리게이트
  • [이득우의 언리얼] 8. 언리얼의 C++ 설계 - 컴포지션
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (229)
      • 게임잼 (3)
      • 언리얼 엔진 (53)
        • 꿀 Tip ! (7)
        • 트러블슈팅 (24)
        • 최적화 (0)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • 문자열 (0)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 프로젝트 (25)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • GetOutOf (15)
      • 기타 (54)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (10)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    경북게임잼
    셸정렬
    버블정렬
    참가후기
    알고리즘
    쉘정렬
    삽입정렬
    게임개발
    게임잼
    자료구조
    선택정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[이득우의 언리얼] 11. 언리얼 컨테이너 라이브러리 - 구조체, Map
상단으로

티스토리툴바