1. Архитектура UE5 и модель объектов: UCLASS, USTRUCT, UFUNCTION, UPROPERTY
Архитектура UE5 и модель объектов: UCLASS, USTRUCT, UFUNCTION, UPROPERTY
Зачем Unreal Engine “просит” макросы
Unreal Engine на C++ выглядит как обычный C++, но ключевые игровые системы движка работают поверх модели объектов UE и рефлексии. Именно поэтому в коде появляются макросы UCLASS, USTRUCT, UFUNCTION, UPROPERTY.
Эти макросы нужны, чтобы движок мог:
В этой статье мы разберём архитектурный контекст и практическое применение основных макросов.
Картина мира UE5: модули, объектная система и Gameplay Framework
На высоком уровне проект UE5 состоит из модулей C++ (ваш игровой модуль и плагины), которые собираются через Unreal Build Tool и интегрируются с движком.
Ключевой момент: игровая логика UE строится вокруг UObject-иерархии.
!Базовая иерархия типов и где они существуют
Базовые типы
UWorld и может быть размещён на уровне.
- Имеет трансформ и жизненный цикл уровня.
Почему это важно для макросов
UCLASS/USTRUCT/UFUNCTION/UPROPERTY подключают ваш код к системам:
Рефлексия UE5 и Unreal Header Tool
UE использует собственную систему рефлексии. В отличие от некоторых языков, C++ не предоставляет рефлексию “из коробки”, поэтому UE генерирует вспомогательный код.
Что делает Unreal Header Tool
Unreal Header Tool (UHT) анализирует заголовки, где встречаются UE-макросы, и генерирует код в *.generated.h.
!Как UHT генерирует код для рефлексии
Практические следствия:
#include "YourType.generated.h" должен быть последним include в вашем .h.Официальная документация:
UCLASS: классы, которые понимает Unreal
UCLASS применяется к классам, которые наследуются от UObject (или его потомков, например AActor, UActorComponent).
Минимальный шаблон:
Что даёт UCLASS
NewObject, SpawnActor)Часто используемые спецификаторы UCLASS
| Спецификатор | Для чего | Типичный сценарий |
|---|---|---|
| Blueprintable | Разрешает наследование в Blueprint | Базовый C++ класс, от которого дизайнеры делают BP-потомков |
| BlueprintType | Разрешает использовать тип как переменную в Blueprint | Data-объекты, компоненты, структуры данных |
| Abstract | Запрещает создание экземпляров напрямую | Базовые классы-фреймворки |
| Config=Game | Подключает систему ini-конфигов | Настройки, которые читаются из DefaultGame.ini |
| NotBlueprintable | Запрещает наследование в Blueprint | Внутренние технические классы |
Примечание: часть поведения задаётся не только спецификаторами UCLASS, но и тем, от какого базового класса вы наследуетесь.
Документация:
USTRUCT: структурные типы для данных, сериализации и Blueprints
USTRUCT нужен, когда вы хотите:
UObjectПример структуры с видимостью в Blueprint:
Когда USTRUCT лучше, чем UObject
Документация:
UPROPERTY: поля, которые видит движок
UPROPERTY помечает член класса или структуры как свойство UE. Это включает его в рефлексию и подключает к подсистемам движка.
Почему UPROPERTY критично для UObject-ссылок
Unreal использует сборщик мусора для UObject. Он отслеживает ссылки между объектами, но только те, которые он знает.
Если вы храните ссылку на UObject в обычном “сыром” указателе без UPROPERTY, сборщик мусора может считать, что объект больше никому не нужен, и удалить его. Итог: висячий указатель и краш.
Практическое правило:
UObject-типы, которые должны удерживать объект живым, обычно должны быть UPROPERTY()В UE5 часто встречается TObjectPtr<T> как рекомендуемая форма UObject-ссылок в свойствах, но базовый принцип остаётся тем же: свойство должно быть известно системе.
Категории спецификаторов UPROPERTY
#### Видимость и редактирование в редакторе
| Спецификатор | Что делает | Пример |
|---|---|---|
| EditAnywhere | Можно редактировать и в defaults, и у instance | Настройки актёра на уровне |
| EditDefaultsOnly | Редактирование только в Class Defaults | Параметры, одинаковые для всех инстансов |
| VisibleAnywhere | Видно, но нельзя менять | Отладочные/вычисляемые поля |
#### Доступность в Blueprints
| Спецификатор | Что делает | Пример |
|---|---|---|
| BlueprintReadOnly | Только чтение в BP | Текущие значения состояния |
| BlueprintReadWrite | Чтение/запись в BP | Настраиваемые параметры |
#### Сериализация, сохранения, временные данные
| Спецификатор | Что делает | Пример |
|---|---|---|
| Transient | Не сериализуется | Кэш, временные вычисления |
| SaveGame | Участвует в системе сохранений | Прогресс игрока |
#### Репликация
| Спецификатор | Что делает | Пример |
|---|---|---|
| Replicated | Реплицируется по сети | Состояния, важные для клиентов |
| ReplicatedUsing=OnRep_X | Репликация + коллбек при обновлении | Запуск VFX/SFX при изменении |
Для репликации одного UPROPERTY(Replicated) недостаточно: нужно ещё включить репликацию актёра и описать реплицируемые поля в GetLifetimeReplicatedProps.
Документация:
UFUNCTION: функции для Blueprint, делегатов и сети
UFUNCTION делает метод видимым системе рефлексии. Это нужно для:
Exec)Примеры:
Сетевые RPC через UFUNCTION
RPC задаются спецификаторами:
Server вызывается на сервереClient вызывается на клиентеNetMulticast вызывается на всех (при вызове с сервера)Reliable/Unreliable задаёт гарантии доставкиПример объявления:
Важно: RPC работают только в контексте сетевой модели UE и при корректных настройках репликации для актёра/компонента.
Blueprint-события из C++
Два частых варианта:
BlueprintImplementableEvent означает, что реализация будет в BlueprintBlueprintNativeEvent означает, что есть C++ реализация по умолчанию, но Blueprint может её переопределитьДокументация:
Сборка примера: актёр, структура данных, свойства и методы
Ниже пример, который связывает всё вместе: актёр хранит структуру, имеет ссылку на компонент, экспонирует настройки в редакторе и предоставляет функции для Blueprint.
Ключевые моменты:
Mesh помечен как UPROPERTY, чтобы редактор видел компонент, и чтобы ссылка корректно учитывалась системами UEBaseDamage настроечный параметр, удобно править в defaultsLastHit это USTRUCT, отображается и редактируетсяDealDamageAtLocation доступна из BlueprintТипичные ошибки и как их избегать
generated.h*.generated.h должен подключаться последним include в .h файле.
UObject* как обычный указатель, GC может удалить объект.
2. Используйте UPROPERTY() и подходящий тип ссылки.
UFUNCTION(Server/Client/NetMulticast, ...).
USTRUCT не имеет сборки мусора и не живёт как отдельный объект UE.Итоги
UCLASS подключает класс к объектной системе UE и рефлексииUSTRUCT подходит для данных-значений и удобен для сериализации и Blueprint-переменныхUPROPERTY делает поле видимым для UE, критично для GC, сериализации, редактора и репликацииUFUNCTION делает метод вызываемым из Blueprint, пригодным для делегатов и сетевых RPCВ следующих материалах курса эта база станет фундаментом для более сложных тем: жизненный цикл объектов, подсистемы, модульность, делегаты, репликация, сериализация и архитектура игрового кода.