언리얼 프로퍼티 시스템(리플렉션)
https://www.unrealengine.com/ko/blog/unreal-property-system-reflection
- 2014년 글이라 현재와 다소 차이가 있음
리플렉션
- 프로그램이 실행시간에 자기 자신을 조사하는 기능
- 언리얼 엔진 테크놀로지의 근간
- 에디터의 디테일 패널, 시리얼라이제이션, 가비지 콜렉션, 네트워크 리플리케이션, 블루프린트/C++ 커뮤니케이션 등 다수의 시스템에 탑재
- C++는 어떠한 형태의 리플렉션을 지원하지 않아 언리얼에는 자체적으로 구축
- 리플리케이션 시스템은 옵션
- 리플렉션 시스템에 보이도록 했으면 하는 유형이나 프로퍼티에 주석을 달아주면, Unreal Header Tool (UHT)가 그 프로젝트를 컴파일할 때 해당 정보를 수집함
- 헤더에 리플렉션이 있는 유형으로 마킹을 하려면, 파일 상단에 특수한 include 를 추가해 줘야 함
#include "FileName.generated.h"
- UENUM(), UCLASS(), USTRUCT(), UFUNCTION(), UPROPERTY() 등을 사용하여 헤더의 다양한 유형과 멤버 변수 주석을 달 수 있음
- 자동으로 리플렉션 시스템을 구성하는 필요한 소스 코드를 생성해 줌
- UPROPERTY()와 같이 선언을 해줘야 가비지 콜렉터와 같은 자동 메모리 관리를 해줌
- 계층구조
- 특정 개체, 값 접근 가능
언리얼 오브젝트 구성
- UPROPERTY: 언리얼 시스템에 의해서 관리되는 클래스 멤버 변수에 대한 매크로
- UFUNCTION: 언리얼 시스템에 의해서 관리되는 클래스 멤버 함수에 대한 매크로
- 매크로 안에 여러 메타 데이터를 심을 수 있음
- UClass
- 클래스 정보를 담은 클래스
- 자신이 가진 프로퍼티, 클래스 이름, 함수 정보와 같은 다양한 정보를 컴파일 타임과 런타임에 조회할 수 있음
- 언리얼 오브젝트는 일반적인 C++ 객체를 생성할 때 사용되는 new() 키워드가 아니라 NewObject() API를 사용해서 생성해야 함
- CDO
- 언리얼 클래스 정보에는 클래스 기본 오브젝트(CDO: Class Default Object)가 함께 포함
- CDO는 언리얼 객체가 가진 기본 값을 보관하는 템플릿 객체
- 한 클래스로부터 다수의 물체를 생성해 게임 콘텐츠에 배치할 때 일관성 있게 기본 값을 조정하는데 사용
- GetDefaultObject 함수를 통해 UClass로부터 얻어올 수 있음
- UClass 와 CDO는 엔진 초기화 과정에서 생성
- 콘텐츠 제작 과정에서 안심하고 사용 가능
언리얼 오브젝트 처리
https://docs.unrealengine.com/5.3/ko/unreal-object-handling-in-unreal-engine/
- 클래스, 프로퍼티, 함수에 적합한 매크로로 마킹해 주면 UClass, UProperty, UFunction 으로 변함
- 그러면 언리얼 엔진이 접근할 수 있어, 다수의 내부적인 처리 기능을 구현할 수 있음
- 자동 프로퍼티 초기화
- UObject 는 생성자 호출 전 초기화시 자동으로 0 으로 초기화
- 레퍼런스 자동 업데이트
- 자동 메모리 관리의 이점을 받을 수 있음
- 직렬화(Serialization)
- 언리얼 오브젝트 객체를 우리가 지정된 포맷에 맞게 저장하거나 불러들이는 것을 일괄적으로 진행할 수 있는데 저장되는 정보는 UProperty라는 것으로 명시를 해줘야 이것들만 언리얼 오브젝트에서 빼내서 디스크에 저장하고 불러들일 수 있게 됨
- 프로퍼티 값 업데이트 하기
- CDO를 사용해서 게임 제작 과정에서 하나의 클래스를 게임에 대해 여러 가지를 배치 했을 때 기본 값을 CDO를 통해서 효과적으로 관리 가능
- 에디터 통합
- UProperty와 매크로 안에 메타 데이터를 넣어주면 에디터와 통합되면서 유용한 기능들을 사용할 수 있음
- 리플렉션 시스템을 사용하게 되면 런타임에 정보를 얻을 수 있고 안전하게 형변환이 가능함
- 가비지 컬렉션
- 더 이상 참조되지 않는 언리얼 오브젝트는 시스템이 자동으로 회수해서 소멸
- 네트워크 리플리케이션
- Serialization과 유사한 기능
- 네트워크 통신을 통해서도 UProperty를 자동으로 전송하고 받을 수 있게 되는 시스템이 자동으로 구축되어 있음
실습
- 검증 코드
- check
- 에디터 뻗고 Crash Reporter가 나옴
- ensure
- 에디터 안뻗고 에러 로그 뜸
- ensureMsgf
- 에러 로그 메시지를 추가로 기록할 수 있음
- GetClass
- 런타임에 클래스 정보
UClass* ClassRuntime = GetClass();
- StaticClass
- 컴파일에 클래스 정보
UClass* ClassCompile = MyGameInstance::StaticClass();
- 둘이 같음
CDO 기능
- 생성자에서 초기화했을 때의 기본값은 CDO 템플릿 객체에 저장
- 헤더를 변경할 때와 마찬가지로 에디터를 끄고 컴파일을 해줘야 제대로 작동함
- 값을 변경해도 기본값은 남아있음
UE_LOG(LogTemp, Log, TEXT("학교 이름 : %s"), *SchoolName); UE_LOG(LogTemp, Log, TEXT("학교 이름 기본값 : %s"), *GetClass()->GetDefaultObject<UMyGameInstance>()->SchoolName);
- CDO를 생성하는 시점을 중단점으로 확인해보면 엔진을 초기화하는 단계에서 생성하는 것을 알 수 있음
- 즉, 엔진이 초기화되는 과정에서 CDO나 UClass 정보들이 만들어짐
- 다 만들어진 이후에 에디터나 게임 어플리케이션이 가동이 됨