1 분 소요

언리얼 오브젝트의 리플렉션 시스템에 관해서 서술

Unreal Object Reflection?

1. Reflection?

UENUM(), UCLASS(), USTRUCT(), UFUNCTION(), UPROPERTY()

다음과 같이 특정 변수나 클래스 위에 표시되는 Unreal에서 정의한 매크로들을 리플렉션이라고 함
(프로퍼티라고도 함)    

c++로 구현할 때 해당 Reflection을 사용하지 않고 구현할 수도 있지만
그 경우 가비지 컬렉터라던지 언리얼에서 제공하는 여러 에디터 기능을 사용할 수 없기 때문에
고려해서 사용해야 함    

2. Reflection의 빌드

Reflection의 코드를 빌드하게 되면 컴파일 과정 이전에 UHT(Unreal Header Tool)가
정의된 함수, 변수 등에 관해서 추가적인 코드를 생성한다.
그 다음에 정식 빌드가 실행    

3. Reflection 의 데이터

Reflection의 데이터를 가져와서 여러 작업이 가능
UClass를 사용하여 자신이 가진 프로퍼티와 함수 정보를 컴파일/런타임에서 조회할 수 있다.    

또한 UObject를 생성하기 위해서는 new()가 아니라 NewObject()를 이용해서 생성해야 됨

UClass* ClassRunTime = GetClass();   //런타임에서 클래스 정보를 가져옴
UClass* ClassCompile = UMyGameInstance::StaticClass();   //컴파일된 클래스 정보를 가져옴

   

CDO(Class Default Object)

CDO란 컴파일 과정에서 생성되는 UObject의 초기 인스턴스이다.

  1. 언리얼 오브젝트를 만들 때마다 생성 및 초기화 작업을 하지 않고 기본 인스턴스를 미리 만들어 놓고 복제해서 사용하기 위함(프로토타입 패턴)
  2. CDO는 생성자에서 정의한다.
  3. 플레이를 누를 때 생성되는 것이 아니라 에디터를 컴파일 할 때 생성

언리얼 클래스 정보에는 클래스 기본 오브젝트가 함께 포함
CDO는 컴파일 과정에서 기본적인 데이터를 정의한다.
그렇게 해서 다수의 물체를 에디터에 배치할 때 일관성 있게 기본값을 조정 가능    

Image GetDefaultObject() 로 CDO를 얻어올 수 있다

	UE_LOG(LogTemp, Log, TEXT("학교이름 기본값1: %s"), *GetClass()->GetDefaultObject<UMyGameInstance>()->SchoolName);
	UE_LOG(LogTemp, Log, TEXT("학교이름 기본값2: %s"), *UMyGameInstance::StaticClass()->GetDefaultObject<UMyGameInstance>()->SchoolName);

       

빌드관련 주의점

UObject에서 생성자는 에디터가 빌드하는 과정중에서 호출 따라서 헤더정보를 변경하거나 생성자 정보를 변경하면 에디터를 끄고 컴파일해야 함

   

리플렉션의 데이터와 CDO는 엔진 초기화 과정에서 생성        

각 코드 사용법

1. Reflection 지정

	UPROPERTY()
	FString Name;
	
	UPROPERTY()
	int32 Year;

   

2. Reflection을 이용한 Get, Set

UTeacher* Teacher = NewObject<UTeacher>();
FString CurrentTeacherName;
FString NewTeachername = TEXT("홍길동");
FProperty* NameProp = UTeacher::StaticClass()->FindPropertyByName(TEXT("Name"));  //변수 이름이 Name인 변수를 찾음
if (NameProp)
{
	NameProp->GetValue_InContainer(Teacher, &CurrentTeacherName);   //UTeacher클래스의 Name 프로퍼티를 Get
	UE_LOG(LogTemp, Log, TEXT("현재 선생님 이름 %s"), *CurrentTeacherName);

	NameProp->SetValue_InContainer(Teacher, &NewTeachername);   //UTeacher클래스의 Name 프로퍼티를 Set
	UE_LOG(LogTemp, Log, TEXT("새로운 선생님 이름 %s"), *Teacher->GetName());
}

FProperty 자료형    

3. Reflection을 이용한 함수호출

UTeacher* Teacher = NewObject<UTeacher>();
UFunction* DoLessonFunc = Teacher->GetClass()->FindFunctionByName(TEXT("DoLession"));  //DoLession 함수를 찾음
if (DoLessonFunc)
{
	Teacher->ProcessEvent(DoLessonFunc, nullptr);   //UFunction 변수를 실행, 인자가 없으면 nullptr을 넘김
}

UFunction 자료형        

정리

각 Reflection 함수는 설계에 따라서 사용을 결정하면 됨 중요한건 내부가 Reflection으로 돌아가고 있다는 것을 숙지

댓글남기기