Как приручить Widget Component: идеальные 3D‑виджеты без мыла в UE5
Допустим, вам требуется реализовать World-Space виджеты на основе стандартного UMG в Unreal Engine 5.
Самый быстрый и простой способ — добавить Widget Component к какому‑нибудь актору.
В поле Space выбрать World, в поле Widget Class указать ваш UserWidget класс.
Также можно явно задать размер виджета или сделать его автоматическим, но эта статья не об этом.
Как выглядит наш виджет:
На первый взгляд всё работает корректно, однако у этого подхода есть ряд скрытых ограничений.
Ограничения метода «из коробки»
Нельзя отключить тень
Внутри Widget Component — это обычный меш, на который наложен материал с Render Target‑текстурой.
Решается наследованием своего Widget Component и вызовом SetCastShadow(false) в конструкторе класса.
Цветокоррекция и тонмаппер
Наш виджет существует прямо в мире: на него влияют HDR‑коррекция, Color Grading, Tonemapper и т. д. В стилизованных или малоконтрастных интерфейсах это легко «съедает» читаемость.
Подробнее о преобразовании HDR → LDR см. в документации Epic Games.
Апскейлинг
Следующий важный аспект — совместимость нашего подхода с технологиями масштабирования рендеринга, такими как DLSS, FSR и TAA.
В статике все работает неплохо.
А что насчет динамики?
Как правило, наш виджеты имеют анимации и эффекты. Не говоря о том, что игрок может быстро перемещаться относительно виджета. Как в таком случае поведет себя апскейлер?
Как и ожидалось, виджет начинает демонстрировать артефакты при использовании апскейлинга. Для прототипов этого может быть достаточно, для продакшена — нет.
Очевидное решение?
Это должно решать ряд вышеуказанных проблем. Виджет будет рендерится как HUD, минуя все коррекции. А также, что самое главное, будет рисоваться в полном разрешении и тем самым проблемы апксейлинга и артефактов уйдут. Пробуем!
Виджет действительно переходит в HUD‑слой: цветокоррекция и апскейлеры к нему не применяются. Но позиция вычисляется просто по центру компонента, перспективы нет, размеры — фиксированы. Итог: виджет «прилипает» к экрану и не повторяет геометрию объекта.
На этом описание проблемы закончили. Теперь перейдем к решению.
Если хочешь сделать что-то хорошо — сделай сам.
Мы сделаем собственный HUD‑виджет, который:
- Получает Render Target текстуру;
 - Принимает четыре угловые точки в мире;
 - В NativePaint строит перспективно‑корректный меш
 - Отрисовывает его через материал (можно добавить любые пост‑эффекты).
 
Немного кода
WorldSpaceWidget.h
WorldSpaceWidget.cpp
Далее расширяем Widget Component:
ScreenSpaceWidgetComponent.h
ScreenSpaceWidgetComponent.cpp
И не забываем добавить модули в *.Build.cs
Использование
Добавляем наш компонент вместо обычного Widget компонента
Материал для примера выглядит так:
Результат
Спасибо, что дочитали! Если материал оказался полезным — дайте знать, буду писать еще.