[UE5] Unreal Engine 5 길라잡이 - 9. 프로퍼티 시스템, 리플렉션(Reflection)

세동네·2022년 7월 2일
0
post-thumbnail

이 시리즈는 이득우의 언리얼 C++ 게임 개발의 정석을 바탕으로 작성되었습니다.

· 리플렉션

일반 C++ 오브젝트를 언리얼 오브젝트(UObject)로 만들기 위해 리플렉션(Reflection)을 활용한다. 언리얼 테크놀로지의 기본이며, 리플렉션이 있는 오브젝트는 런타임에 자기 자신을 조사하여 언리얼 엔진이 조작할 수 있는 형태로 정보를 수집한다.

리플렉션을 가질 수 있는 오브젝트는 열거형 UENUM(), 클래스 UCLASS(), 구조체 USTRUCT(), 함수 UFUNCTION(), 멤버 변수 UPROPERTY()가 있다. 오브젝트가 리플렉션을 가지면 디테일 패널, 직렬화(Serialization), 가비지 콜렉션, 네트워크 리플리케이션, 블루프린트 등 언리얼 엔진의 유용한 시스템에서 사용될 수 있다.

리플렉션을 가지게 하려면 오브젝트가 포함된 C++ 클래스 헤더 파일에 "모듈명".generated.h 헤더를 포함해야 한다. 해당 헤더를 가져야 리플렉션이 있는 시스템에서 해당 클래스를 고려해야 하고 시스템 구현이 필요함을 언리얼 헤더 툴 UHT(Unreal Header Tool)에 알린다.

// MyActor.h

...

#include "MyActor.generated.h"

UCLASS()
class UE5PRACTICE_API AMyActor : public AActor
{
	GENERATED_BODY()
	
    ...
    
public:
	...
    
	UPROPERTY(VisibleAnywhere)
	int32 val;
};

소스 코드를 컴파일하기 이전에 UHT를 사용해 클래스 선언 내의 리플렉션을 위한 매크로 및 키워드를 분석한다. 분석한 결과에 따라 언리얼 실행 환경에 필요한 부가 정보를 해당 generated.h 파일에 생성한다. 컴파일 과정에서 필연적으로 발생하는 파일이므로, 해당 파일이 정상적으로 생성될 수 있게 코드 헤더 선언부 마지막에 generated.h 헤더를 반드시 포함해줘야 한다.

생성된 generated.h 파일과 함께 소스 코드를 컴파일하면 언리얼 실행 환경은 이를 사용해 해당 언리얼 오브젝트를 관리하고 에디터에서 해당 값을 편집할 수 있는 인터페이스를 제공한다.

generated.h 헤더를 포함해야 UENUM(), UCLASS(), USTRUCT(), UFUNCTION(), UPROPERTY() 키워드를 사용할 수 있게 된다. generated.h 헤더를 포함한 클래스는 UCLASS() 매크로와 GENERATED_BODY() 매크로를 반드시 포함해야 한다.

- UCLASS() 매크로 지정자

  • 언리얼 오브젝트에 특별한 기능을 추가하는 구문을 지정자라고 한다. 필요한 경우 UCLASS 뒤 괄호 ()에 특수한 기능을 하는 지정자를 삽입할 수 있으며, 지정자 목록은 이곳에서 확인할 수 있다.

    각 UObject마다 사용할 수 있는 지정자가 다르며, 자주 사용되는 클래스 지정자로는

    • Abstract : 해당 클래스를 추상 클래스로 만들어 액터로 레벨에 배치할 수 없게 한다.
    • Blueprintable : 블루프린트 클래스로의 확장을 가능하게 한다.
    • BlueprintType : 블루프린트에서 변수로 사용할 수 있는 타입으로 노출시킨다.

    등이 있다.

- GENERATED_BODY() 매크로

  • 언리얼 오브젝트로 만든 클래스가 언리얼 시스템을 위한 추가적인 함수, Super:: 또는 ThisClass::와 같은 유용한 typedef를 사용할 수 있게 해준다.

· 리플렉션이 있는 클래스

리플렉션을 가져 언리얼 오브젝트가 된 클래스는 언리얼 에디터에서 그 존재를 확인할 수 있게 된다.

리플렉션이 있으면 레벨에 액터를 배치할 수도, 리플렉션을 가진 멤버 변수를 에디터에서 관리할 수도 있게 된다. 앞선 코드에서 선언한 val 변수는 리플렉션을 가지며, VisibleAnywhere 지정자가 있으므로 에디터의 디테일 패널에서 다음과 같이 값을 확인할 수 있다.

· 리플렉션이 없는 클래스

반면에 새 C++ 클래스 생성에서 액터나 폰 등 언리얼 시스템을 위한 오브젝트가 아닌 '없음'이라는 이름의 빈 C++ 클래스를 생성하면 다음과 같은 소스 코드로 이루어진 것을 볼 수 있다.

#pragma once

#include "CoreMinimal.h"

class UE5PRACTICE_API MyClass
{
public:
	MyClass();
	~MyClass();
};

해당 클래스는 콘텐츠 브라우저에서 찾아볼 수 없다. 리플렉션을 가지지 않기 때문이다. 따라서 에디터 UI를 지원받는 것과 더불어 언리얼 시스템이 해당 클래스를 관리해주지 않게 된다. 물론 리플렉션이 없는 클래스는 리플렉션을 가진 함수나 프로퍼티(멤버 변수)를 가질 수도 없다.

0개의 댓글