언리얼엔진

언리얼엔진 리플렉션 시스템 이란

silbaram 2025. 3. 30. 01:38
728x90

언리얼 엔진의 리플렉션(Reflection) 시스템은 C++의 한계를 극복하여 런타임 시 객체의 타입 정보를 확인하고 조작할 수 있게 해주는 강력한 메커니즘입니다. 기본 C++에서는 런타임 타입 정보(RTTI)를 제한적으로만 제공하지만, 언리얼 엔진은 이를 확장하여 블루프린트와의 연동, 가비지 컬렉션, 네트워킹, 에디터에서의 인스펙션 등 다양한 기능을 지원합니다.

아래에서 언리얼 엔진 리플렉션 시스템의 주요 요소와 작동 방식을 자세히 설명합니다.


1. 리플렉션 시스템의 기본 원리

  • 메타데이터 제공:
    언리얼 엔진은 클래스, 구조체, 열거형 등의 타입에 대해 메타데이터를 제공하여 런타임에 해당 타입의 정보(예: 속성, 함수, 상속 관계 등)를 확인할 수 있게 합니다.

  • 매크로와 코드 생성:
    UCLASS, USTRUCT, UENUM, UPROPERTY, UFUNCTION 등의 매크로를 사용하여 타입에 필요한 정보를 지정합니다. 이 매크로들은 언리얼 헤더 툴(Unreal Header Tool, UHT)에 의해 파싱되고, 리플렉션 시스템에 필요한 추가 코드가 자동으로 생성됩니다.

  • 가비지 컬렉션 및 객체 관리:
    리플렉션 시스템을 통해 생성된 메타데이터는 엔진의 가비지 컬렉션(Garbage Collection) 시스템과도 연동되어 메모리 관리에 도움을 줍니다.

  • 블루프린트 연동:
    리플렉션 시스템 덕분에 C++로 작성된 코드가 블루프린트 에디터에 노출되어 디자이너들이 시각적으로 로직을 구성할 수 있습니다.


2. 주요 매크로와 사용 예제

2.1 UCLASS, USTRUCT, UENUM

  • UCLASS: 클래스를 리플렉션 시스템에 노출시키기 위해 사용합니다.
  • USTRUCT: 구조체를 리플렉션에 등록할 때 사용합니다.
  • UENUM: 열거형을 리플렉션에 등록하여 블루프린트나 에디터에서 사용 가능하게 합니다.

2.2 UPROPERTY

  • UPROPERTY: 클래스의 멤버 변수를 리플렉션 시스템에 등록합니다.
    옵션을 통해 에디터에서 노출 여부, 블루프린트에서 읽기/쓰기 가능 여부, 직렬화 등의 설정을 할 수 있습니다.

2.3 UFUNCTION

  • UFUNCTION: 멤버 함수를 리플렉션 시스템에 등록하여 블루프린트에서 호출하거나 네트워크 호출 등을 할 수 있게 합니다.

3. 코드 예제

다음은 간단한 액터 클래스를 작성하여 리플렉션 시스템을 사용하는 예제입니다.

// MyActor.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

// UCLASS 매크로를 사용해 클래스가 리플렉션 시스템에 등록됨을 알립니다.
UCLASS()
class MYGAME_API AMyActor : public AActor
{
    GENERATED_BODY()

public:
    // 기본 생성자
    AMyActor();

    // UPROPERTY를 사용해 이 변수는 에디터와 블루프린트에서 노출됩니다.
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test")
    int32 MyIntProperty;

    // UFUNCTION을 사용해 이 함수는 블루프린트에서 호출 가능하도록 합니다.
    UFUNCTION(BlueprintCallable, Category = "Test")
    void MyTestFunction();

protected:
    // 게임이 시작될 때 호출되는 함수
    virtual void BeginPlay() override;

public:
    // 매 프레임마다 호출되는 함수
    virtual void Tick(float DeltaTime) override;
};
// MyActor.cpp
#include "MyActor.h"

// 생성자: 기본값 초기화
AMyActor::AMyActor()
{
    // 이 액터가 매 프레임마다 Tick 함수를 호출하도록 설정
    PrimaryActorTick.bCanEverTick = true;

    // 기본 값 설정
    MyIntProperty = 0;
}

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    // 게임 시작 시 로그 출력
    UE_LOG(LogTemp, Warning, TEXT("MyActor BeginPlay - MyIntProperty: %d"), MyIntProperty);
}

void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    // 매 프레임마다 호출되는 로직을 여기에 작성할 수 있습니다.
}

void AMyActor::MyTestFunction()
{
    // 블루프린트 또는 코드에서 호출 시 실행되는 로직
    UE_LOG(LogTemp, Warning, TEXT("MyTestFunction 호출됨!"));
}

4. 리플렉션 시스템의 처리 과정

  1. 코드 작성:
    개발자는 위와 같이 매크로를 사용해 클래스와 멤버를 선언합니다.

  2. UHT 처리:
    Unreal Header Tool이 빌드 과정에서 헤더 파일을 파싱하여 리플렉션 데이터(메타데이터)를 생성합니다. 이 과정에서 자동으로 생성된 코드 파일(.generated.h 등)이 포함되어 런타임에 타입 정보와 관련 기능을 제공하게 됩니다.

  3. 컴파일 및 런타임 사용:
    생성된 메타데이터를 기반으로 엔진은 가비지 컬렉션, 블루프린트 노출, 네트워크 복제 등 다양한 기능을 수행할 수 있습니다.


이와 같이 언리얼 엔진의 리플렉션 시스템은 개발자가 C++ 코드에 메타데이터를 추가하여 런타임에 동적 타입 정보를 활용할 수 있도록 지원하며, 이를 통해 다양한 기능(가비지 컬렉션, 블루프린트 연동 등)을 구현할 수 있습니다.

728x90