리플렉션(Reflection)이란?
- 언리얼 엔진의 리플렉션 시스템은 C++ 코드에서 런타임 또는 에디터에서 객체의 속성, 함수 등을 동적으로 접근하고 조작할 수 있도록 하는 시스템
- 언리얼 엔진의 핵심 기능인 블루프린트, 세리얼라이제이션, 가비지 컬렉션, 리플렉션 기반 프로퍼티 시스템 등과 밀접하게 연관되어 있음
핵심 요소
- Unreal Header Tool(UHT)
- UCLASS, UPROTERTY, UFUNCTION등 매크로가 포함된 C++코드를 언리얼 헤더 툴이 분석하고, 자동으로 메타데이터를 생성하는 .generated.h 파일을 만듦
- 이 파일은 리플렉션 정보를 포함하는 StaticClass() 함수, 프로퍼티 테이블, 함수 테이블등이 정의 됨
- 언리얼 엔진은 클래스의 구조, 변수, 함수 정보를 런타임에도 알 수 있게 됨
- UCLASS, USTRUCT, UENUM 매크로
- 리플렉션을 사용하면 클래스, 구조체, 열거형에 특별한 매크로를 적용해야 하는데 이 매크로들은 언리얼 빌드 시스템이 UHT를 사용하여 코드에서 리플렉션 데이터를 자동으로 생성해야 함
- UCLASS()
- UObject 기반으로 하는 클래스에 리플렉션 기능을 추가한다
- USTRUCT()
- 언리얼 데이터 구조체를 만들 때 사용
- UENUM()
- 열거형을 블루프린트에서도 사용할 수 있도록 함
- UPROPERTY, UFUNCTUON
- UPROPERTY()
- 언리얼의 프로퍼티 시스템은 UPROPERTY 매크로를 통해 관리되며, 이를 통해 가비지 컬렉션, 세리얼 라이제이션, 네트워크 복제, 에디터 노출 등의 기능을 사용할 수 있다
- UFUNCTION()
- 함수에도 UFUNCTION() 매크로를 적용하여 블루프린트에서 호출 가능하게 만들거나, 네트워크 RPC로 설정할 수 있음
- UPROPERTY()
- 리플렉션을 활용한 동적 접근
- 리플렉션 시스템을 이용하면, 객체 속성과 함수를 런타임에서 동적으로 가져오고 조작할 수 있음
- 객체의 클래스 얻기(GetClass())
- UClass* Class = MyActor->GetClass();
- 프로퍼티 값 동적 변경(FinfPropertyByName())
- FProperty* Property = Class->FindPropertyByName("Health");
float HealthValue = Property->ContainerPtrTiBaluePtr<float>(MyActor);
*HealthValue = 100.0f;
- FProperty* Property = Class->FindPropertyByName("Health");
- 함수 호출(FindFunction())
- UFunction* Function = MyActor->FindFunction(FName FunctionName);
GENERATED_BODY()
- GENERATED_BODY()
- 언리얼의 메타데이터와 리플렉션 시스템을 위해 필요한 코드를 자동으로 생성
- UCLASS, USTRUCT, UENUM등에 사용
- UHT가 실행될 때 .generated.h파일을 생성하면서 클래스 관련 정보를 포함
- 자동 생성 내용
- StaticRegisterNativesAMyActor()-> 런타임에 클래스 정보를 등록하는 함수
- DECLARE_CLASS->UCLASS의 내부 정보를 생성하는 매크로
- EDCLARE_SERIALIZER->세리얼라이제이션(객체 저장 및 로드) 기능 제공
UCLASS 설정 옵션
옵션 | 설면 |
Abstruact | 추상 클래스로 지정(직접 인스턴스화 불가) |
Blueprintable | 블루프린트에서 상속 가능 |
BlueprintType | 블루프린트에서 객체로 사용할 수 있음 |
NotBlueprintable | 블루프린트에서 상속 불가능 |
NotPlaceable | 에디터에서 이 클래스 배치 불가 |
Placeable | 에디터에서 배치 가능(기본적으로 AActor 기반 클래스는 가능) |
Transient | 게임 실행 중에만 존재하고 저장되지 않음 |
Config=Game | Game.ini 파일에서 설정 값을 읽어옴 |
DefaultToInstanced | 기본적으로 인스턴스로 생성됨 |
Within=OtherClass | 특정 클래스의 내부에서만 사용 가능 |
UPROPERTY() 설정 옵션
옵션 | 설면 |
EditAnywhere | 에디터에서 수정 가능 |
EditDefaultsOnly | 에디터에서 디폴트 값만 수정 가능 |
VisibleAnywhere | 에디터에서 볼 수 있지만 수정 불가 |
Blueprint ReadOnly | 블루프린트에서 읽기만 가능 |
BlueprintReadWrite | 블루프린틀에서 읽기 및 쓰기 가능 |
Replicated | 네트워크 동기화(복제) 가능 |
Transient | 저장되지 않고, 실행 중에만 유지 |
Cinfig | .ini 설정 파일에서 값을 읽어옴 |
UFUNCTION() 설정 옵션
옵션 | 설명 |
BlueprintCallable | 블루프린트에서 호출 가능 |
BlueprintPure | 입력값만 가지고 실행되는 함수(출력값만 반환) |
Server | 서버에서 실행되는 함수 |
Clinet | 클라이언트에서 실행되는 함수 |
Reliable | 네트워크에서 보장된 실행(패킷 손실 방지) |
Unrealiable | 네트워크에서 실행 보장 X(빠른 속도) |
Exec | 콘솔 명령어에서 호출 가능 |
필요한 이유
- 블루프린트 통합
- 리플레션 시스템이 없다면, 블루프린트에서 C++ 클래스를 인식하지 못하고 속성, 함수 등을 사용할 수 없음
- 세리얼라이제이션
- 언리얼 엔진의 리플렉션 시스템은 객체를 저장 및 불러오는 과정(세리얼라이 제이션)에서도 활용됨
- 네트워크 복제
- 리플렉션이 적용된 변수는 언리얼의 네트워크 복제 시스템에서 동작할 수 있음
- 에디터 노출
- EditAnywhere, VisibleAnywhere 등 프로퍼티 지정자를 사용하면 언리얼 에디터에서 C++ 클래스를 편집할 수 있음
단점
- 런타임 오베헤드 : 동적 탐색 및 호출 과정에서 성능 부담이 있을 수 있음
- 코드 복잡성 증가 : 추가적인 매크로가 필요
- C++ 표준 리플렉션과 다름 : 언리얼 리플렉션 시스템은 표준 C++ RTTI와 다르게 동
'오늘의 키워드' 카테고리의 다른 글
대칭키/비대칭키 암호화 (0) | 2025.02.19 |
---|---|
Perlin Noise VS Simplex Noise (0) | 2025.02.18 |
프로세스/스레드 차이 (0) | 2025.02.07 |
스넬의 법칙, 프레넬 방적식 (0) | 2025.02.06 |
반사/굴절 벡터 (1) | 2025.02.04 |