Back to Home

Reflection in Unreal Engine: how the type system works

The article explains the Unreal Engine reflection system, including code generation through Unreal Header Tool, UObject and FField hierarchy architecture, and practical application for runtime type access. The material is intended for developers working with C++ and Blueprint in UE5.

Reflection in Unreal Engine: internal structure for developers
Advertisement 728x90

Unreal Engine Reflection System: How It Handles Types at Runtime

Unreal Engine relies on its own reflection system to access type information during runtime. This powers object serialization, property display in the editor, C++ and Blueprint integration, and network communication. The system is built on code generation via the Unreal Header Tool and two parallel type hierarchies.

Reflection Architecture: UHT and Generated Files

The Unreal Header Tool (UHT) scans C++ header files, spots macros like UCLASS and UPROPERTY, and generates code to register types. This creates two key files:

  • .generated.h — holds macros and forward declarations.
  • .gen.cpp — contains type registration code that can span thousands of lines.

The generated code stores metadata like property names, flags, and memory offsets. For instance, the CurrentValue property in FAbilityAttribute has its offset registered via STRUCT_OFFSET, letting the engine access data directly at runtime.

Google AdInline article slot

Two Type Hierarchies: UObject and FField

UE5 uses two systems to describe types, split for performance optimization.

UObject-Based Hierarchy

Managed by the garbage collector, this includes:

  • UClass for C++ classes.
  • UFunction for functions.
  • UScriptStruct for structs.
  • UEnum for enums.

FField-Based Hierarchy

Introduced in UE 4.25 to cut overhead, properties here skip garbage collection:

Google AdInline article slot
  • FField — base class.
  • FProperty — describes individual properties, like FIntProperty or FFloatProperty.
  • Link between hierarchies: UStruct holds a pointer to a linked list of FField properties.

Key FField features:

  • Uses a linked list for child elements.
  • Includes FFieldClass with fast type casting via bitmasks.
  • FFieldVariant combines UObject and FField pointers, using the low bit to distinguish types.

Anatomy of FProperty: Accessing Data

FProperty provides tools for handling properties in memory. Core elements:

  • Offset_Internal — property's memory offset, calculated via STRUCT_OFFSET.
  • EPropertyFlags — flags dictating behavior, like CPF_Edit for editor tweaks.
  • Access methods like ContainerPtrToValuePtr for direct read/write.

Example in action:

Google AdInline article slot
UAbilityComponent* Comp = ...;
FProperty* HealthProp = Comp->GetClass()->FindPropertyByName(TEXT("HealthAttribute"));
FAbilityAttribute* HealthPtr = HealthProp->ContainerPtrToValuePtr<FAbilityAttribute>(Comp);
float CurrentHealth = HealthPtr->CurrentValue;

Practical Uses of Reflection

Unreal Engine's reflection system drives key features:

  • Serialization — saving and loading objects from files.
  • Editor — displaying properties in the Details panel with categories and custom widgets.
  • Blueprint Integration — exposing C++ properties and functions to visual scripting.
  • Network Replication — syncing data between client and server.
  • Garbage Collection — tracking object ownership for memory management.

Key Takeaways

  • Unreal Engine reflection relies on Unreal Header Tool code generation, not native C++ features.
  • Splitting UObject and FField hierarchies boosts performance and memory handling.
  • Memory offsets in FProperty enable fast runtime data access.
  • The system underpins core engine functions like serialization, editing, and networking.
  • Mastering reflection is essential for building advanced systems like ability components or custom editor tools.

— Editorial Team

Advertisement 728x90

Read Next