본문 바로가기
Unreal/[서적] 언리얼5 이득우님 인프런1

Ch 05. 언리얼 리플렉션

by GameStudy 2023. 5. 10.

5.1 언리얼 리플렉션

5.1-1 언리얼 리플렉션의 주요 특징

  - 리플렉션은 런타임 중에 자기 자신을 조사하는 기능을 뜻함.
    가비지 컬렉션, 리플리케이션, 시리얼라이즈 등의 기능들의 근간을 이룸.

  - 리플렉션은 언리얼 오브젝트만 가질 수 있음. 일반 C++ 오브젝트는 불가능.

  - 특정 매크로(UCLASS(), UPROPERTY(), UFUNCTION(), ...)를 프로퍼티나 함수에 작성하면

    Unreal Header Tool이 컴파일 타임에 해당 정보를 수집함.

  - 단, UPROPERTY() 매크로로 지정되지 않은 멤버의 경우에는 언리얼 가비지 컬렉터에 의해

    메모리 관리가 되지 않음에 주의.

  - UHT는 C++ 파서가 아님에 주의. 즉, C++ 소스코드를 읽고 컴파일을 진행하는 프로그램이 아님.

    그래서 모든 C++ 소스코드를 읽고 대응할 수 있지는 않음. 

  - 리플렉션 시스템의 자료형 계층구조는 아래와 같음.

    UField <- UStruct <- UClass <- ...

 

5.1-2 언리얼 오브젝트의 구성

  - 언리얼 오브젝트에는 특별한 프로퍼티와 함수를 지정할 수 있음.

    멤버는 UPROPERTY(), 멤버 함수는 UFUNCTION() 매크로로 관리함.

    해당 매크로에 인자를 작성함으로써 에디터에 메타데이터를 전달할 수 있음.

  - 모든 언리얼 오브젝트는 자기 자신 클래스가 가진 프로퍼티와 함수 정보를

    컴파일 타임(StaticClass())과 런타임(GetClass())에서 조회할 수 있음.

  - 다만 언리얼 오브젝트는 C++의 new 키워드가 아닌,

    NewObject API를 사용해서 생성해야 함.

 

5.1-3 언리얼 오브젝트의 클래스 디폴트 오브젝트

  - 언리얼 클래스 정보에는 클래스 디폴트 오브젝트가 포함되어 있음.

    이를 줄여서 CDO라고도 부름.

    CDO는 언리얼 오브젝트가 가진 기본 값을 보관하는 템플릿 개체임.

    한 클래스로부터 다수의 개체가 생성될 때 일관성 있게 기본값을 조정할 수 있게끔함.

  - CDO는 클래스 정보로부터 GetDefaultObject() 함수를 통해 얻을 수 있음.

    UClass 및 CDO는 엔진 초기화 과정에서 생성되므로 컨텐츠 제작시에 안심하고 사용 가능.

 

5.1-5 언리얼 리플렉션 실습

  - 학교를 재현하고자 함. 학교 정보는 GameInstance에서 설정

  - Person 클래스 <- Student 클래스/Teacher 클래스

  - ObjectReflection 프로젝트 생성

  - 새 C++ 클래스 > GameInstance 부모 클래스 > "MyGameInstance" 클래스 생성

<hide/>

// MyGameInstance.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"

/**
 * 
 */
UCLASS()
class OBJECTREFLECTION_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()	
public:
	UMyGameInstance();

	virtual void Init() override;

private:
	UPROPERTY()
	FString SchoolName;
	
};
<hide/>

// MyGameInstance.cpp


#include "MyGameInstance.h"
#include "Student.h"
#include "Teacher.h"

UMyGameInstance::UMyGameInstance()
{
	SchoolName = TEXT("기본학교"); // 기본값. CDO에 저장됨.
	  // 중단점을 걸어보면 에디터가 실행되기 전에 호출됨을 알 수 있음.
}

void UMyGameInstance::Init()
{
	Super::Init();

	UE_LOG(LogTemp, Log, TEXT("============================="));
	UClass* ClassRuntime = GetClass();
	UClass* ClassCompile = UMyGameInstance::StaticClass();
	//check(ClassRuntime != ClassCompile); 
	//ensure(ClassRuntime != ClassCompile); 
	//ensureMsgf(ClassRuntime != ClassCompile, TEXT("일부러 에러를 발생시킨 코드"));
    	// check()와 ensure() 관련 매크로들은 릴리즈 빌드시에 모두 사라짐.

	UE_LOG(LogTemp, Log, TEXT("학교를 담당하는 클래스 이름 : %s"), *ClassRuntime->GetName());

	SchoolName = TEXT("청강문화산업대학교"); // CDO를 통해 생성된 개체에 새롭게 대입되는 값.

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

	UE_LOG(LogTemp, Log, TEXT("============================="));

	...
}

 

댓글