리플렉션(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로 설정할 수 있음
  • 리플렉션을 활용한 동적 접근
    • 리플렉션 시스템을 이용하면, 객체 속성과 함수를 런타임에서 동적으로 가져오고 조작할 수 있음
    • 객체의 클래스 얻기(GetClass())
      • UClass* Class = MyActor->GetClass();
    • 프로퍼티 값 동적 변경(FinfPropertyByName())
      • FProperty* Property = Class->FindPropertyByName("Health");
        float HealthValue = Property->ContainerPtrTiBaluePtr<float>(MyActor);
        *HealthValue = 100.0f;
    • 함수 호출(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