언리얼 엔진5 Basic - 자료구조

타입·2024년 3월 25일
0

언리얼 강의

목록 보기
3/47

Array와 Set

  • 언리얼 컨테이너 라이브러리 (UCL)
    언리얼 엔진이 자체 제작해 제공하는 자료구조 라이브러리
  • C++ STL과 언리얼 컨테이너 라이브러리의 차이점
    • C++ STL
      범용적으로 설계됨
      표준이라 호환성이 높음
      많은 기능이 엮여 있어 include 시 컴파일 시간이 오래 걸림
    • 언리얼 컨테이너 라이브러리
      언리얼 엔진에 특화
      언리얼 오브젝트 구조를 안정적으로 지원
      가볍고 게임 제작에 최적화
  • 언리얼 C++ 주요 컨테이너 라이브러리
    • TArray
      오브젝트를 순서대로 담아 효율적으로 관리하는 용도
    • TSet
      중복되지 않는 요소로 구성된 집합을 만드는 용도
    • TMap
      키-밸류 조합의 레코드를 관리하는 용도

TArray

가변 배열(Dynamic Array) 자료구조
STL의 vector와 동작 원리가 유사

  • 게임 제작에서는 가변 배열 자료구조를 효과적으로 활용하는 것이 좋음
    데이터가 순차적으로 모여있기 때문에 메모리를 효과적으로 사용할 수 있고 캐시 효율이 높음
    컴퓨터 사양이 좋아지면서, 캐시 지역성(Locality)으로 인한 성능 향상이 중요해짐
    임의 데이터의 접근이 빠르고 고속으로 요소를 순회하는 것이 가능
  • 가변 배열의 단점
    맨 끝에 데이터를 추가하는 것은 가볍지만, 중간에 요소를 추가하거나 삭제하는 작업은 비용이 큼
    데이터가 많아질 수록 검색, 삭제, 수정 작업이 느려지기 때문에 많은 수의 데이터에서 검색 작업이 빈번하게 일어난다면 TArray 대신 TSet 사용

  • TArray 문서
    얼로케이터(Allocator)는 메모리에 오브젝트가 레이아웃되는 방식과 배열에 엘리먼트를 추가하기 위해 배열을 키울 방식을 정의하지만 보통 기본값은 1로 사용
    TArray는 값 유형이라 동적할당을 하지 않음, TArray 인스턴스를 new나 delete로 생성하거나 소멸하면 안됨
    TArray 소멸은 엘리먼트의 소멸로 이어짐
    다른 TArray 변수에서 TArray 변수를 만들면 엘리먼트를 새 변수에 복사하고, 공유되는 상태는 없음

TSet

순서가 중요하지 않은 상황에서 고유 엘리먼트를 저장하는데 사용되는 고속 컨테이너 클래스

  • STL의 set과 언리얼 TSet
    • STL set
      이진 트리로 구성되어 있어 정렬을 지원
      이진 트리라 메모리 구성이 효율적이지 않음
      요소가 삭제될 때 균형을 위한 재구축이 일어날 수 있음
      모든 자료를 순회하는데 적합하지 않음
    • 언리얼 TSet
      해시테이블 형태로 키 데이터가 구축되어 있어 빠른 검색 가능
      동적 배열의 형태로 데이터가 모여있어 빠르게 순회 가능
      데이터를 삭제해도 재구축이 일어나지 않음
      동적 배열에 비어있는 데이터가 있을 수 있음
      STL의 unordered_set과 유사하게 동작하지만 동일하진 않음

  • TSet 문서
    데이터 값 자체를 키로 사용
    내부적으로 해시 테이블로 구현되어 있어
    엘리먼트 추가, 검색, 제거가 빠름
    TSet이 소멸되면 엘리먼트도 소멸 (TArray가 그렇듯)
    해싱 커스터마이징 가능

TSet의 중간 엘리먼트를 제거하여 디버깅 모드에서 보면 Elements의 해당 엘리먼트가 존재했던 위치가 Invalid로 비어있는 걸 확인할 수 있음


구조체와 Map

언리얼 구조체

데이터 저장/전송에 특화된 가벼운 객체

  • 대부분 GENERATED_BODY 매크로를 선언
    리플렉션, 직렬화와 같은 유용한 기능 지원
    GENERATED_BODY를 선언한 구조체는 UScriptStruct 클래스로 구현됨
    • 이 경우 제한적으로 리플렉션 지원
      속성 UPROPERTY만 선언할 수 있고 함수 UFUNCTION은 선언할 수 없음
  • 언리얼 엔진의 구조체 이름은 F로 시작
    대부분 힙 메모리 할당(포인터 연산)없이 스택 내 데이터로 사용됨
    NewObject API를 사용할 수 없음

구조체는 단순한 데이터 타입에 적합하므로 UObject와는 다름
UStruct는 리플리케이션용으로 간주되지 않음, UProperty 변수는 리플리케이션용으로 간주됨

// MyGameInstance.h
UCLASS()
class UNREALCONTAINER_API UMyGameInstance : public UGameInstance
{
	...
    TArray<FStudentData> StudentsData;
    
    UPROPERTY() // 내부적으로 UObject 관리 시 언리얼 엔진이 메모리 관리를 할 수 있도록 UPROPERTY 필수
    TArray<TObjectPtr<class UStudent>> Students;
};

TMap

키-밸류 쌍이 필요한 자료구조에 광범위하게 사용

  • STL map과 TMap
    • STL map
      STL set과 동일하게 이진 트리로 구성되어 있음
      정렬은 지원하지만, 메모리 구성이 효율적이지 않으며, 데이터 삭제 시 재구축이 일어날 수 있음
      모든 자료를 순회하는데 적합하진 않음
    • 언리얼 TMap
      키-밸류 구성의 튜플(Tuple) 데이터의 TSet 구조로 구현되어 있음
      해시테이블 형태로 구축되어 있어 빠른 검색 가능
      동적 배열의 형태로 데이터가 모여있어 빠르게 순회할 수 있음
      데이터는 삭제해도 재구축이 일어나지 않음, 비어있는 데이터가 있을 수 있음
      TMultiMap을 사용하면 중복 데이터를 관리할 수 있음
      STL unordered_map과 유사
  • TMap 문서
    TSet과 같은 해시 기반
    TPair<KeyType, ElementType>으로 구성
    TSet처럼 슬랙이 발생 (중간에 빈 공간이 있을 수 있음)
    TMultiMap 사용하면 키 중복 가능
// MyGameInstance.h
UCLASS()
class UNREALCONTAINER_API UMyGameInstance : public UGameInstance
{
	...
    
    // 키나 밸류에 UObject 포인터가 있다면 UPROPERTY() 필요
    TMap<int32, FString> StudentsMap;
};

Algo::Transform() 함수로 다른 타입의 원소를 빠르게 전달할 수 있음

  • FStudentData를 TSet에서 사용하기
    operator==(), GetTypeHash() 추가
struct FStudentData
{
	...    
    bool operator==(const FStudentData& InOther) const
    {
		return Order == InOther.Order;
    }
    friend FORCEINLINE uint32 GetTypeHash(const FStudentData& InStudentData)
    {
    	return GetTypeHash(InStudentData.Order);
    }
    
    UPROPERTY()
    FString Name;
    UPROPERTY()
    int Order;
};
profile
주니어 언리얼 프로그래머

0개의 댓글