Что хотим получить

Логика должна быть такой:

При возвращении в игру пауза автоматически не снимается.

Игрок возвращается и видит обычное меню:

А уже сам нажимает «Продолжить».


Почему не обычный LostFocus

Изначально я пробовал использовать:

На первый взгляд всё работает.

Но возникла проблема: если в проекте используется CommonUI, игровой viewport может потерять фокус даже тогда, когда игрок просто открывает внутриигровое меню.

В результате получалось:

То есть событие срабатывало дважды.

Поэтому в итоге я отказался от проверки фокуса самого viewport и стал отслеживать именно состояние приложения.

Для этого используется:

Теперь мы различаем:

и:


Шаг 1. Добавляем C++ в Blueprint-проект

Если проект до этого был полностью на Blueprint ничего страшного.

В Unreal Engine:

Tools → New C++ Class

В качестве родителя я использую:

потому что в проекте уже используется CommonUI.

Создаём класс:(за место Pangit…..используйте свое имя

После этого Blueprint-проект становится гибридным Blueprint + C++, но переписывать существующие Blueprint'ы на C++ не требуется.


Шаг 2. Добавляем зависимости

Открываем:
У меня это

У меня он выглядит так:

Здесь нам нужны:

потому что наш Viewport Client наследуется от:

и:

потому что дальше будем использовать:


Шаг 3. PangitGameViewportClient.h

Создаём заголовочный файл:

Главная часть здесь:

Это позволяет пробросить событие из C++ обратно в Blueprint.

То есть C++ будет только определять:

Игра действительно потеряла фокус приложения.

А что делать после этого - решаем уже в Blueprint.


Шаг 4. PangitGameViewportClient.cpp

Когда приложение становится неактивным:

вызывается:

И дальше управление переходит в Blueprint.


Шаг 5. Компилируем

После изменения C++:

и:

Build → Build Solution

Если всё нормально:


Шаг 6. Создаём Blueprint Viewport Client

Теперь создаём Blueprint-наследника нашего класса:

И назначаем его:

Project Settings → Engine → General Settings → Default Classes

В:

ставим:

При этом CommonUI не пропадает.

Иерархия остаётся:


Шаг 7. Ловим событие в Blueprint

В BP_PangitGameViewportClient появляется:

Дальше можно вызвать уже существующую систему паузы.
Я использую ассет Menu System Pro

У меня получилось примерно так:

Вы можете вызывать свой виджет где у вас меню (с логикой Pause/Unpause)


Что получилось

Теперь:

То же самое работает при сворачивании окна или переключении на другое приложение.

А обычное:

не вызывает событие повторно, потому что мы отслеживаем не потерю фокуса GameViewport, а именно изменение активности всего приложения.

В итоге C++ здесь нужен буквально как небольшой мост: