[UE] 언리얼 리플렉션 Unreal Reflection I
언리얼 오브젝트의 특징과 리플렉션 시스템의 동작원리를 이해하자. 언리얼 오브젝트의 처리 방식을 이해하고 사용예시를 분석하자.
인프런 이득우님의 '언리얼 프로그래밍 Part1 - 언리얼 C++의 이해' 강의를 참고하였습니다.
😎 [이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해] 강의 들으러 가기!
목차
언리얼 오브젝트 리플렉션
리플렉션(Reflection)은 프로그램이 실행시간에 자기 자신을 조사하는 기능이다.
UPROPERTY()를 붙이는 기준
리플렉션 프로퍼티 변수는 언리얼 엔진의 시스템의 관리(=Garbage Collector)를 받는다.
반면에, 리플렉션 프로퍼티가 아닌 것은 해당 리플렉션에 의존하는 시스템 전부에 보이지 않는다.
즉, 리플렉션 되지 않은 UObject 포인터 그대로를 저장하면 Garbage Collector(GC)가 레퍼런스를 확인할 수 없다.
해당 경우는 직접 메모리 관리를 해줘야 한다.
Unreal Header Tool (UHT)
- 컴파일 전 리플렉션 시스템을 포함하여 필요한 소스 코드를 만드는 작업을 거치게 되고, 소스 코드들은 .generatred.h에 생성 된다.
- Intermediate 폴더 내 생성
- Unreal Build Tool (UBT)과 함께 코드를 분석 후 빌드에 필요한 소스를 제작
- UHT는 C++ 파서가 아니다.
- 언리얼 엔진에서 코드를 자동으로 생성하는데 필요한 기능만 제공한다. (실제 C++ 언어를 UHT이 분석해서 컴파일을 진행하는게 아니다!)
- UHT는 실제 컴파일 과정에 있어 관여하는 부분은 없으며, 정교하지 않다.
언리얼 오브젝트의 구성
언리얼 오브젝트에는 특별한 프로퍼티와 함수를 지정할 수 있음
- 관리되는 클래스 멤버 함수: UFUNCTION ()
- 관리되는 클래스 멤버 변수: UPROPERTY()
- 에디터와 연동되는 메타데이터를 심을 수 있음
모든 언리얼 오브젝트는 클래스 정보(= UClass)와 함께 함 (※ UClass는 클래스 정보를 담는 클래스다)
- 클래스(=UClass)를 사용해 자신이 가진 프로퍼티와 함수 정보를 컴파일 타임과 런타임에서 조회할 수 있음
이렇게 다양한 기능을 제공하는 언리얼 오브젝트는 NewObjectAPI를 사용해 생성해야 함
언리얼 오브젝트의 클래스 기본 오브젝트
Class Default Object (CDO) 클래스 기본 오브젝트
- 언리얼 클래스 정보에는 클래스 기본 오브젝트(Class Default Object)가 함께 포함되어 있음.
- CDO는 언리얼 객체가 가진 기본 값을 보관하는 템플릿 객체임
- 한 클래스로부터 다수의 물체를 생성해 게임 콘텐츠에 배치할 때 일관성 있게 기본 값을 조정하는데 유용하게 사용됨
- CDO는 클래스 정보로부터 GetDefaultObject 함수를 통해 얻을 수 있음.
- UClass 및 CDO는 엔진 초기화 과정에서 생성되므로 콘텐츠 제작에서 안심하고 사용할 수 있음.
언리얼 오브젝트 처리
자동 프로퍼티 초기
- UPROPERTY 속성의 변수들은 자동으로 값이 초기화
- C++과 달리 가비지 값이 아닌 0으로 채워짐
레퍼런스 자동 업데이트
- 언리얼 엔진의 자동 메모리 시스템의 이점을 활용
직렬화 Serialization
- UPROPERTY값은 명시적으로 "transient" (휘발성) 마킹 또는 생성자 이후 기본 값에서 미변경 상태가 아닌 이상 자동으로 읽고 쓰기가 가능하다.
프로퍼티 값 업데이트하기
- CDO가 변경되면, 기존 배치 된 오브젝트들을 조사
- 기본 값인 경우: 새로운 값으로 업데이트
- 값이 상이할 경우: 그대로 둠 ( 의도적으로 바꾸었다고 판단 )
런타임 유형 정보 및 형변환
- UObject는 항상 자신이 무슨 UClass인지 알고 있음
- Super를 통해, 부모의 정보 덮어 쓰기에 대한 제어가 쉬워짐
- Cast를 통해, 파생된 클래스로 안전하게 캐스팅
- IsA를 사용하여, 오브젝트가 특정 클래스의 것인지 질의할 수 있다
예제 프로젝트
예제 코드
#include "MyGameInstance.h"
UMyGameInstance::UMyGameInstance()
{
// CDO는 하나의 인스턴스
// 엔진이 초기화되는 과정에서 CDO 생성. 따라서 생성자 코드를 고치는 경우에는 에디터를 꺼준 후 다시 실행하는게 안전하다.
SchoolName = TEXT("기본 학교");
}
void UMyGameInstance::Init()
{
Super::Init();
// 동일한 객체를 가리키고 있다
UClass* ClassRuntime = GetClass(); // 런타임
UClass* ClassCompile = UMyGameInstance::StaticClass();
check(ClassRuntime == ClassCompile); // false면 오류 메시지 출력 + 게임 중단
ensure(false); // 오류 발생 시 에디터가 꺼지지 않고 Output Error Log를 출력하여 에러를 알려줌
ensureMsgf(false, TEXT ("일부러 에러를 발생시킨 코드"));
UE_LOG(LogTemp, Log, TEXT("학교 클래스 이름: %s"), *ClassRuntime->GetName());
SchoolName = TEXT("울랄라 학교");
UE_LOG(LogTemp, Log, TEXT("학교 이름: %s"), *SchoolName);
UE_LOG(LogTemp, Log, TEXT("학교 기본 이름: %s"), *GetClass()->GetDefaultObject <UMyGameInstance>()->SchoolName);
}
에디터를 재시작 해야되는 경우는?
헤더 파일에 리플렉션 정보의 이런 구조를 변경하거나,
생성자 코드에서 Class Defualt Object(CDO) 기본값을 변경하는 경우에는
에디터를 끄고 컴파일해서 다시 실행하는 것이 안전하다.
'⭐ Unreal Engine > UE 개념정리 - 언리얼의 이해' 카테고리의 다른 글
[UE] 언리얼 C++ 설계 1 - 인터페이스 (0) | 2024.04.05 |
---|---|
[UE] 언리얼 리플렉션 Unreal Reflection II (0) | 2024.03.21 |
[UE] 언리얼 오브젝트 시스템 (0) | 2024.03.18 |
[UE] 문자타입, 문자열 FString, FText, FString (0) | 2024.03.13 |
[UE] 언리얼 C++ 코딩 표준 (0) | 2024.03.06 |
댓글
이 글 공유하기
다른 글
-
[UE] 언리얼 C++ 설계 1 - 인터페이스
[UE] 언리얼 C++ 설계 1 - 인터페이스
2024.04.05 -
[UE] 언리얼 리플렉션 Unreal Reflection II
[UE] 언리얼 리플렉션 Unreal Reflection II
2024.03.21 -
[UE] 언리얼 오브젝트 시스템
[UE] 언리얼 오브젝트 시스템
2024.03.18 -
[UE] 문자타입, 문자열 FString, FText, FString
[UE] 문자타입, 문자열 FString, FText, FString
2024.03.13