Powrót do strony głównej

Refleksja w Unreal Engine: jak działa system typów

Artykuł wyjaśnia system refleksji w Unreal Engine, w tym generowanie kodu za pomocą Unreal Header Tool, architekturę hierarchii UObject i FField oraz praktyczne zastosowanie do dostępu do typów w runtime. Materiał przeznaczony dla programistów pracujących z C++ i Blueprint w UE5.

Refleksja w Unreal Engine: wewnętrzne urządzenie dla programistów
Advertisement 728x90

System refleksji w Unreal Engine: Jak silnik obsługuje typy w czasie wykonywania

Unreal Engine wykorzystuje własny system refleksji do uzyskiwania informacji o typach podczas wykonywania. Pozwala to silnikowi serializować obiekty, wyświetlać właściwości w edytorze, integrować C++ z Blueprintami i zarządzać komunikacją sieciową. System jest zbudowany na generowaniu kodu poprzez Unreal Header Tool i dwóch równoległych hierarchiach typów.

Architektura refleksji: UHT i pliki generowane

Unreal Header Tool analizuje pliki nagłówkowe C++, znajduje makra takie jak UCLASS i UPROPERTY, oraz generuje kod do rejestracji typów. Ten proces tworzy dwa pliki:

  • .generated.h — zawiera makra i deklaracje wstępne.
  • .gen.cpp — obejmuje kod rejestracji typów, który może osiągać tysiące wierszy.

Wygenerowany kod przechowuje metadane, takie jak nazwy właściwości, flagi i przesunięcia w pamięci. Na przykład, dla właściwości CurrentValue w strukturze FAbilityAttribute rejestrowane jest jej przesunięcie przez STRUCT_OFFSET, co pozwala silnikowi bezpośrednio uzyskać dostęp do danych w runtime.

Google AdInline article slot

Dwie hierarchie typów: UObject i FField

W UE5 istnieją dwa systemy do opisywania typów, oddzielone dla optymalizacji wydajności.

Hierarchia oparta na UObject

Ta hierarchia jest zarządzana przez zbieranie śmieci i obejmuje:

  • UClass dla klas C++.
  • UFunction dla funkcji.
  • UScriptStruct dla struktur.
  • UEnum dla enumeracji.

Hierarchia oparta na FField

Wprowadzona w UE 4.25 dla zmniejszenia narzutów, właściwości tutaj nie uczestniczą w zbieraniu śmieci:

Google AdInline article slot
  • FField — klasa bazowa.
  • FProperty — opisuje poszczególne właściwości, takie jak FIntProperty lub FFloatProperty.
  • Połączenie między hierarchiami: UStruct zawiera wskaźnik na linked list właściwości FField.

Kluczowe cechy FField:

  • Używa linked list do przechowywania elementów podrzędnych.
  • Zawiera FFieldClass z systemem szybkiego rzutowania typów przez maski bitowe.
  • FFieldVariant łączy wskaźniki na UObject i FField, używając najmłodszego bitu do rozróżniania typów.

Anatomia FProperty: dostęp do danych

FProperty dostarcza mechanizmy do pracy z właściwościami w pamięci. Główne elementy:

  • Offset_Internal — przesunięcie właściwości w pamięci, obliczane przez STRUCT_OFFSET.
  • EPropertyFlags — flagi określające zachowanie, na przykład CPF_Edit dla edycji w edytorze.
  • Metody dostępu, takie jak ContainerPtrToValuePtr, do bezpośredniego odczytu i zapisu wartości.

Przykład użycia:

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

Praktyczne zastosowanie refleksji

System refleksji jest używany w różnych komponentach Unreal Engine:

  • Seriałizacja — zapisywanie i wczytywanie obiektów z plików.
  • Edytor — wyświetlanie właściwości w panelu szczegółów z obsługą kategorii i widżetów.
  • Integracja z Blueprint — zapewnianie dostępu do właściwości i funkcji C++ z wizualnego skryptowania.
  • Replikacja sieciowa — synchronizacja danych między klientem a serwerem.
  • Zbieranie śmieci — śledzenie posiadania obiektów do zarządzania pamięcią.

Co ważne

  • Refleksja w Unreal Engine opiera się na generowaniu kodu przez Unreal Header Tool, a nie na możliwościach C++.
  • Podział hierarchii UObject i FField optymalizuje wydajność i zarządzanie pamięcią.
  • Przesunięcia w pamięci, przechowywane w FProperty, pozwalają efektywnie uzyskiwać dostęp do danych podczas wykonywania.
  • System wspiera kluczowe funkcje silnika, w tym serializację, edycję i komunikację sieciową.
  • Zrozumienie refleksji jest niezbędne do opracowania złożonych systemów, takich jak komponenty umiejętności lub niestandardowe narzędzia edytorskie.

— Editorial Team

Advertisement 728x90

Czytaj dalej