UClass는 실제로 어떤 정보를 가지고 있을까?

//
//

🚀 들어가며

이전 글에서는 Unreal Header Tool(UHT)이UCLASS, UPROPERTY, UFUNCTION 같은 매크로를 분석해 Reflection 메타데이터를 생성하는 과정을 살펴봤습니다.

UHT를 공부하다보면 자연스럽게 다음 질문이 생길 수 있습니다.

  • UHT가 생성한 Reflection 정보는 어디 저장될까?
  • 언리얼은 런타임에 클래스 정보를 어떻게 알고 있을까?

예를 들어, 언리얼에서는 이런 코드가 자연스럽게 동작합니다.

UClass* Class = MyActor->GetClass();

그리고 아래 코드와 같이 클래스 정보로부터 프로퍼티 정보를 가져오는 것도 가능합니다.

Class->FindPropertyByName(TEXT("HP"));

일반 C++에서는 런타임에

  • 멤버 변수 목록
  • 함수 목록
  • 메타데이터

같은 것을 다루기 쉽지 않고, C++은 기본적으로는 이런 리플렉션 기능을 제공하지 않습니다.

그런데 언리얼은 이런 정보를 런타임에 모두 알고 있습니다.

그 중심에 있는 것이 바로 👉 UClass 입니다.

이번 글에서는

  • UClass가 무엇인지
  • 실제로 어떤 정보를 저장하는지
  • Reflection 시스템과 어떻게 연결되는지
  • 왜 언리얼 엔진 구조에서 중요한지

정리해보겠습니다.


🧠 먼저 중요한 사실

언리얼에서 클래스는 단순 C++ 타입이 아닙니다.

일반 C++에서는 클래스가 컴파일되면 보통

  • 코드
  • 메모리 레이아웃
  • vtable

정도 개념으로 남습니다.

즉,

  • “이 클래스의 이름은 무엇인가?”
  • “어떤 프로퍼티가 존재하는가?”
  • “어떤 함수가 BlueprintCallable인가?”

같은 정보를 런타임에 쉽게 다루기 어렵습니다.

하지만 언리얼은 다릅니다.

언리얼은 클래스 자체를 👉 엔진이 이해할 수 있는 객체 형태로 관리합니다.

그 객체가 바로 UClass 입니다.


//

🎯 UClass는 무엇인가?

간단하게 말하면 UClass는 “클래스에 대한 메타데이터 객체”입니다.

예를 들어, 이런 클래스가 있다고 해봅시다.

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()

public:

    UPROPERTY(EditAnywhere)
    int HP;

    UFUNCTION(BlueprintCallable)
    void Attack();
};

언리얼은 단순히 AMyActor 타입만 생성하는 것이 아닙니다.

추가로 아래 코드와 같은 형태의 클래스 메타데이터 객체도 함께 생성합니다.

UClass* AMyActor::StaticClass()

AMyActor
→ 실제 게임 객체 타입

UClass
→ AMyActor에 대한 Reflection 정보 객체

입니다.


🧩 UClass는 어디서 생성될까?

여기서 이전 글의 UHT가 다시 등장합니다.

UHT는

  • UCLASS
  • UPROPERTY
  • UFUNCTION

같은 정보를 분석합니다.

그리고 generated.h / generated.cpp 내부에 Reflection 등록 코드를 생성합니다.

개념적으로는 이런 느낌입니다.

헤더 분석
↓
Reflection 메타데이터 생성
↓
UClass 생성 코드 생성
↓
엔진 시작 시 등록

즉, 👉 UClass는 UHT가 생성한 Reflection 시스템의 핵심 결과물이라고 볼 수 있습니다.


🎮 실제로 UClass 안에는 무엇이 있을까?

지금까지 설명한 UClass의 전체 구조를 그림으로 정리해보면 다음과 같습니다.

핵심은 UClass는 단순 타입 정보가 아니라, 언리얼 엔진 전체 Reflection 시스템을 연결하는 메타데이터 객체라는 점입니다.

Unreal Engine의 UClass가 Reflection 메타데이터, Property, Function, CDO 정보를 저장하고 사용하는 구조를 설명하는 인포그래픽
UClass는 Unreal Engine Reflection 시스템의 핵심 메타데이터 객체이며, Property, Function, Metadata, CDO 정보를 기반으로 GC, 블루프린트, 에디터 시스템과 연결됩니다.

UClass는 생각보다 훨씬 많은 정보를 가집니다.

대표적으로

  • 클래스 이름
  • 부모 클래스
  • Property 목록
  • Function 목록
  • Metadata
  • Class Flags
  • CDO(Class Default Object)
  • Reflection 정보

등을 포함할 수 있습니다.

즉, UClass는 단순 타입 이름 정도가 아니라 👉 클래스 전체 메타정보 컨테이너에 가깝습니다.


🧠 부모 클래스 정보

예를 들어, 아래 코드를 선언하면 UClass는 부모 클래스 정보도 저장합니다.

class AMyActor : public AActor

즉,

AMyActor
 └── ParentClass = AActor

형태입니다.

그래서 언리얼은 아래 코드와 같이 런타임에 타입 판별이 가능합니다.

MyActor->IsA(AActor::StaticClass())

즉, 👉 언리얼 RTTI 시스템도 UClass 기반으로 동작합니다.


🎯 Property 정보

UClass의 가장 중요한 역할 중 하나는 Property 정보 저장입니다.

예를 들어, 아래 코드에서 변수 정보는 Reflection 시스템에 등록됩니다.

UPROPERTY(EditAnywhere)
int HP;

그리고 UClass 내부에는 아래에 설명한 것과 같은 메타데이터가 저장될 수 있습니다.

Property Name = HP
Type = int
Editable = true

그래서 언리얼 에디터는

  • Details 패널 표시
  • 직렬화
  • GC 추적

같은 작업이 가능합니다.

즉,

UPROPERTY
↓
UHT 분석
↓
UClass Property 정보 저장
↓
엔진 시스템 사용

흐름입니다.


🎯 Function 정보

함수 역시 마찬가지입니다.

아래 함수 정보도 UClass에 연결됩니다.

UFUNCTION(BlueprintCallable)
void Attack();

즉 런타임에

  • 함수 이름
  • 인자 정보
  • 반환 타입
  • BlueprintCallable 여부

같은 정보를 다룰 수 있습니다.

그래서 언리얼은 아래 코드와 같이 함수를 검색하거나 이름으로 함수를 가져와 호출하는 등의 작업이 가능합니다.

FindFunction()

즉, 블루프린트 호출 시스템 역시👉 UClass Reflection 정보 기반으로 동작합니다.


🔥 Metadata 정보

언리얼에서는 메타데이터도 굉장히 중요합니다.

예를 들어 UPROPERTY 매크로에 아래와 같이 메타 데이터 속성을 지정하면

UPROPERTY(EditAnywhere, Category="Stats")

여기서

Category = Stats

정보 역시 메타데이터로 저장됩니다.

그래서 에디터는 Stats 카테고리 아래에 표시 같은 처리가 가능합니다.

즉, 언리얼 에디터는 👉 UClass 메타데이터를 읽어서 UI를 구성합니다.


🧩 CDO(Class Default Object)

UClass를 설명할 때 반드시 등장하는 개념이 있습니다.

바로 CDO (Class Default Object)입니다.

언리얼은 각 UClass마다 👉 기본 객체(Default Object)를 하나 생성합니다.

예를 들어 아래 코드는 내부적으로 AMyActor의 기본 상태 객체가 연결됩니다.

AMyActor::StaticClass()

이 객체는

  • 기본 프로퍼티 값 저장
  • 객체 생성 시 초기값 기준
  • Blueprint 기본값 저장

등에 사용됩니다.

즉, 언리얼은 👉 “클래스 자체도 객체처럼 관리”하는 구조를 가집니다.

이건 일반 C++와 굉장히 다른 부분입니다.


🎮 왜 GetClass()가 가능한가?

언리얼에서는 자연스럽게 이런 코드가 가능합니다.

UClass* Class = MyActor->GetClass();

어떻게 가능할까요?

UObject 내부에는 👉 자신의 UClass 정보를 가리키는 포인터가 존재하기 때문입니다.

개념적으로는 이런 느낌입니다.

MyActor Instance
 └── UClass* ClassInfo

즉, UObject는

  • 자신이 어떤 클래스인지
  • 어떤 Reflection 정보를 가지는지

런타임에 알고 있습니다.

그래서

  • Cast()
  • IsA()
  • FindFunction()
  • FindPropertyByName()

같은 시스템이 동작할 수 있습니다.


🧠 Cast()도 사실 UClass 기반이다

이전 RTTI 글과 연결되는 부분입니다.

언리얼의 Cast 함수 또한 내부적으로는 👉 UClass 기반 타입 검사와 연결됩니다.

Cast<AMyActor>(Object)

Object의 UClass 확인
↓
AMyActor와 비교
↓
상속 관계 검사

흐름입니다.

언리얼은 👉 C++ RTTI 대신 자체 Reflection 타입 시스템을 구축한 것입니다.


🔥 왜 언리얼은 이런 구조를 만들었을까?

핵심은 이것입니다.

언리얼은 게임 제작을 위한 단순 C++ 라이브러리가 아닙니다.

언리얼은

  • 에디터
  • 블루프린트
  • GC
  • 직렬화
  • 네트워크 복제

같은 시스템이 모두 연결된 플랫폼입니다.

그러려면 엔진이 👉 객체와 클래스 정보를 런타임에 이해할 수 있어야 합니다.

그래서 언리얼은

  • UHT
  • Reflection
  • UClass

기반 메타 시스템을 구축한 것입니다.


🎯 중요한 포인트

여기서 가장 중요한 것은 UClass는 단순 클래스 이름 저장 구조가 아닙니다.

실제로는 👉 언리얼 Reflection 시스템 전체를 연결하는 런타임 메타데이터 객체입니다.

왜냐하면

  • GC
  • 에디터
  • 블루프린트
  • 직렬화
  • RPC

모두 👉 UClass Reflection 정보를 기반으로 동작하기 때문입니다.

즉,

UHT
↓
UClass 생성
↓
Reflection 메타데이터 저장
↓
엔진 전체 시스템 사용

흐름입니다.


🎯 핵심 정리

  • UClass는 언리얼의 클래스 메타데이터 객체입니다.
  • UHT가 Reflection 정보를 분석하고 UClass 생성 코드를 만듭니다.
  • UClass는 Property, Function, Metadata, ParentClass 같은 정보를 저장합니다.
  • GetClass(), Cast(), IsA() 같은 시스템은 UClass 기반으로 동작합니다.
  • GC, 블루프린트, 에디터, 직렬화 시스템 모두 UClass Reflection 정보를 사용합니다.
  • 언리얼은 클래스 자체를 UObject 기반 메타 시스템으로 관리합니다.

🧩 마무리

언리얼을 공부하다보면

  • 왜 GetClass()가 가능하지?
  • 왜 Cast()가 RTTI 없이 동작하지?
  • 왜 에디터가 자동으로 프로퍼티를 표시하지?

같은 부분이 굉장히 신기하게 느껴질 수 있습니다.

하지만 내부 구조를 이해해보면, 이 모든 것이 👉 UClass 기반 Reflection 시스템으로 연결되어 있다는 점이 보이기 시작합니다.

즉, UClass는 단순 클래스 타입 정보가 아니라

  • 엔진이 객체를 이해하고
  • 에디터가 정보를 표시하고
  • GC가 객체를 추적하고
  • 블루프린트가 함수를 호출하는

언리얼 메타 시스템의 핵심 객체라고 볼 수 있습니다.

👉 게임 엔진 구조를 더 깊이 이해하고 싶다면

아래 강의를 통해 직접 구현해보는 것을 추천드립니다.

C++로 만드는 게임 엔진 프레임워크 강의

👉 C++로 만드는 게임 엔진 프레임워크 강의 바로가기

//
   

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다