Макросы рефлексии: UCLASS, UPROPERTY, UFUNCTION

Урок объясняет загадочные макросы Unreal-C++ и зачем они нужны движку.

Рефлексия — это способность движка во время работы знать структуру классов: их поля, типы и функции. В Unreal её включают специальные макросы.

Почему обычного C++ недостаточно

В стандартном C++ после компиляции имена полей и функций исчезают — остаются лишь адреса в памяти. Но движку нужно знать структуру классов на лету: чтобы показать поля в Details, сохранить объект в файл, связать C++ с Blueprint, собрать мусор. Для этого Unreal добавляет свою систему рефлексии, а включается она макросами. Это плата за мощь: код выглядит непривычно, но эти макросы — основа всей интеграции.

Главные макросы

МакросЧто помечаетЗачем
UCLASS()КлассРегистрирует класс в системе рефлексии
UPROPERTY()ПолеПоказ в редакторе, сохранение, защита от сборщика мусора
UFUNCTION()ФункциюВызов из Blueprint, привязка к событиям
GENERATED_BODY()Тело классаВставляет сгенерированный движком код

Как это выглядит

Вот класс с типичными макросами. Спецификаторы в скобках управляют поведением: EditAnywhere позволяет менять поле в редакторе, BlueprintReadWrite открывает его для Blueprint.

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

public:
    // Поле видно и редактируется в Details
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    float Health = 100.0f;

    // Функцию можно вызвать из Blueprint
    UFUNCTION(BlueprintCallable)
    void TakeDamage(float Amount);
};

Спецификаторы UPROPERTY

В скобках UPROPERTY указывают, как поле ведёт себя в редакторе:

  • EditAnywhere — можно менять в редакторе у любого экземпляра.
  • VisibleAnywhere — видно, но только для чтения.
  • BlueprintReadWrite — Blueprint может читать и писать.
  • Category="Stats" — группирует поле в Details под заголовком.

Как работает под капотом

Перед компиляцией C++ запускается Unreal Header Tool (UHT). Он читает заголовки, находит макросы и генерирует дополнительный C++-код — таблицы рефлексии, описывающие каждое помеченное поле и функцию. Именно поэтому GENERATED_BODY() обязателен: на его место подставляется этот сгенерированный код. Без UHT и макросов класс остался бы обычным C++ без интеграции с движком.

Частые ошибки

  • Забыть UPROPERTY у указателя на объект. Тогда сборщик мусора может удалить объект, и указатель повиснет — частая причина крашей.
  • Пропустить GENERATED_BODY(). Класс не скомпилируется.
  • Неверные спецификаторы. Например, ждать поле в редакторе, забыв EditAnywhere.

Спецификаторы UFUNCTION

У функций тоже есть спецификаторы, открывающие их движку по-разному. BlueprintCallable делает функцию вызываемой как нода в блюпринте — так C++-логику дёргают из визуального графа. BlueprintImplementableEvent объявляет в C++ событие, тело которого пишется уже в блюпринте: код говорит «здесь что-то происходит», а художник решает, что именно. BlueprintNativeEvent — гибрид: есть реализация по умолчанию в C++, но её можно переопределить в блюпринте.

Эти спецификаторы — мост между двумя мирами. Они позволяют программисту заложить точки расширения, в которых дизайнер дополнит поведение визуально. Без них C++ и блюпринты жили бы в изоляции; благодаря им они образуют единый организм, где каждая сторона делает то, что ей удобнее.

Итоги

  • Макросы включают систему рефлексии — движок узнаёт структуру классов на лету.
  • UCLASS, UPROPERTY, UFUNCTION, GENERATED_BODY — обязательная основа Unreal-C++.
  • Спецификаторы в скобках управляют видимостью в редакторе и Blueprint.
  • Unreal Header Tool генерирует код рефлексии перед компиляцией.
Проверьте себя
1. Зачем Unreal нужна система рефлексии?
AЧтобы ускорить графику
BЧтобы движок знал структуру классов на лету для редактора, сохранения и сборки мусора
CЧтобы уменьшить размер игры
DЧтобы заменить C++ на Python
2. Что произойдёт, если забыть UPROPERTY у указателя на объект?
AНичего
BСборщик мусора может удалить объект, и указатель повиснет
CОбъект продублируется
DКласс ускорится
3. Что делает Unreal Header Tool?
AЗапускает игру
BГенерирует код рефлексии из макросов перед компиляцией
CРисует интерфейс
DСкачивает ассеты