리플렉션이란, 프로그램이 실행 중 자기자신을 조사하는 기능을 의미한다.
에디터의 디테일 패널, 직렬화, 가비지 컬렉션, 네트워크 리플리케이션, 블루프린트/C++ 간 커뮤니케이션 등 엔진 내 다수의 시스템의 기반이 되는 시스템이다.
언리얼 엔진 내에서는 그래픽 용어와 구분짓기 위해서 프로퍼티 시스템이라고 부르기도 한다.
클래스 / 변수 / 함수에 리플렉션 매크로를 붙여주면 해당하는 리플렉션 객체가 생성되는데, 각 매크로마다 어떤 객체가 생성되는 지는 다음과 같다.
- UCLASS (리플렉션되는 클래스임을 의미)
- UCLASS 매크로를 붙여준 클래스는 해당 클래스를 설명하는 UClass 객체가 런타임에 생성된다.
- 해당 UClass 인스턴스가 곧 CDO와 같다.
- 또한 각 UCLASS 인스턴스는 자신의 부모 클래스를 가리키는 포인터를 가진다.
- GetSuperClass()로 참조할 수 있다.
- UCLASS를 붙이기 위해서는 UObject의 자손타입이어야 하며, 네이티브 C++ 클래스에는 붙여도 소용 없음
- UCLASS 매크로를 붙여준 클래스는 해당 클래스를 설명하는 UClass 객체가 런타임에 생성된다.
- UPROPERTY (리플렉션되는 멤버 변수임을 의미)
- UPROPERTY 매크로를 붙여준 변수는 타입에 따라 UObjectProperty, UIntProperty 등 멤버변수의 타입에 맞는 객체가 생성된다.
- 생성된 UProperty 객체는 해당 변수를 설명한다.
- UClass객체가 이 UProperty 객체들을 리스트 형태로 참조한다.
- UProperty 객체가 멤버 변수의 타입에 따라 세분화되는 이유?
- 엔진에는 여러가지 시스템이 있는데, 이 시스템들이 변수의 타입에 따라 달라져야 하는 부분이 있다.
- 두 객체를 비교하는 경우라던가, 디테일 패널에서 변수의 값을 채운다던가, 이게 포인터라서 가비지 컬렉션이 알아야 한다던가, ...
- U___Property 객체에 해당 사항들이 정의되어 있다.
- 엔진에는 여러가지 시스템이 있는데, 이 시스템들이 변수의 타입에 따라 달라져야 하는 부분이 있다.
- UPROPERTY 매크로를 붙여준 변수는 타입에 따라 UObjectProperty, UIntProperty 등 멤버변수의 타입에 맞는 객체가 생성된다.
- UFUNCTION (리플렉션되는 멤버 함수임을 의미)
- 해당 매크로를 붙여준 함수는 UFunction 객체가 생성되고, 해당 객체는 그 함수를 설명한다.
- 생성된 UFunction 객체는 UClass 객체가 참조한다. (UProperty 객체와 마찬가지)
- UFunction 객체도 자신의 매개 변수를 UProperty 객체로 참조한다.
- USTRUCT(리플렉션되는 구조체임을 의미)
- UClass는 UStruct의 서브클래스이다.
- 구조체의 멤버함수는 UFUNCTION으로 지정할 수 없다.
- 언리얼 C++에서 클래스와 구조체는 네이티브 C++에서보다 명확히 구분된다.
- UCLASS : 주로 포인터로 다루고, GC의 회수대상이며, 원본 객체는 UObject의 자손이어야 한다.
- USTRUCT : 주로 값으로 다루고, GC 지원이 되지 않는다. 부모 타입에 제약이 없다.
상술한 리플렉션 관련 매크로들은 모두 UHT(Unreal Header Tool)에게 알려주기 위한 용도이다.
- 비주얼 스튜디오에서 빌드 버튼을 누르면, C++ 컴파일러 실행 전 UHT가 먼저 실행된다,
- 사용자가 작성한 소스코드를 다 훑고 매크로가 붙은 것들을 찾아 리플렉션 정보를 모두 수집한다.
- 수집한 리플렉션 정보들을 가지고 런타임에 리플렉션 객체를 생성하기 위한 코드를 자동으로 생성한다.
- 언리얼엔진 C++ 헤더 파일 최상단의 #include "FileName.generated.h"와 클래스 바디 안의 GENERATED_BODY()가 해당 코드를 사용하기 위해 존재하는 것이다.
- 사용자가 작성한 코드는 Source 폴더 안, UHT의 코드는 Intermediate 폴더 내부에 생성된다.
이렇게 UHT의 역할이 끝나면 두 코드가 실제 C++ 컴파일러로 들어가 컴파일/링크 후 온전한 클래스가 된다.
참조 :
https://www.youtube.com/watch?v=VpEe9DbcZIs&ab_channel=NHNCloud
(좋은 강의 감사합니다)
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/unreal-object-handling-in-unreal-engine
https://www.unrealengine.com/ko/blog/unreal-property-system-reflection
'언리얼 엔진 5 > 공부' 카테고리의 다른 글
[언리얼 엔진 5] 가비지 컬렉션(+유니티와의 차이), 스마트 포인터 (0) | 2024.09.29 |
---|---|
[언리얼 엔진 5] 싱글톤 패턴 (Subsystem) (0) | 2024.04.10 |
[언리얼 엔진 5] 언리얼 엔진에서의 순수 가상함수 사용법 (0) | 2024.04.10 |
[언리얼 엔진 5] Retriggerable Delay 사용법 (FLatentActionInfo) (0) | 2024.04.10 |
[언리얼 엔진 5] 블루프린트에서 디버깅하는 방법 (0) | 2023.12.30 |