February 10

GameDev 3.0. Этап 2.1. Дальний бой. Урок 7. Подсказки и фейк-дверь

  1. Создание блюпринта подсказок для механик взаимодействия
  2. Добавление подсказок в механику взаимодействия с кнопкой
  3. Создание механики закрытой (фейковой) двери для взаимодействия
  4. Применение анимации только на верхнюю часть тела персонажа

Создание блюпринта подсказок для механик взаимодействия

Создадим папку Tooltip в Systems. В этой папке нажимаем ПКМ -> Blueprint Class, Нажимаем All Classes, в поиске пишем widgetcomponent:

Назовем его BP_WidgetComp. Далее тут же создаем Widget Blueprint: ПКМ -> User Interface -> Widget Blueprint:

Здесь выбираем просто UserWidget:

Назовем его WB_TooltipBase. Открываем его. Он представляет собой такой экран, где можно писать текст и т.д.

Тут можно посмотреть подробнее
Пример интерфейса

Для начала работы перекидываем текст в поле, пишем нужный текст, обрамляем (точнее это заливка)

В папке Tooltip создаем новую папку Tex, перекинем туда материалы из уроков. Далее выбираем

У нас получится так:

Нажмем на эти кнопки, выравниваем текст:

Если у нас Fill Screen включен:

то поменяем его на Custom с размерами 150 * 150:

Выделив Border, добавим еще один Border снаружи, для него выберем другую маску:

и выравниваем по середине, сейчас видим, что предыдущий Border слишком сжаты, меняем его скейл по ширине:

Теперь над верхним Border нажимаем ПКМ -> Wrap with -> Vertical Box:

Теперь в Vertical Box закинем картинку Image:

Image и Border выравниваем по центру, меняем некоторые значения:

У верхнего так:

Загрузим картинку:

Переименуем нашу картинку на ImageWidget и обязательно должна быть галочка на Is Variable (это значит, что мы извне можем заменить эту картинку):

Точно так же с текстовым блоком:

Мы сейчас находимся в Designer, перейдем в Graph, создадим одну функцию

ПКМ -> T., создаем кастомный ивент, назовем ApplyData, этот ивент будет отвечать за то, что мы указывали какой текст и какая картинка должны быть на виджете.

С зажатым Ctrl вынесем ImageWidget и TextWidget. Из TextWidget вызываем Set Text (Text), из него выведем усик к ApplyData и переименуем в нем на ToolTip Text:

Теперь из ImageWidget вызываем Set Brush from Texture. Texture тоже подключаем к ApplyData и тоже переименуем - в ToolTip Image. И еще раз из ImageWidget вызываем Set Desired Size Override, размеры поставим 32 и 32:

Сейчас эта функция ничего не делает, но если мы вызовем ее из другого блюпринта, например, то можем поменять картинку и текст.

Сейчас перейдем в BP_WidgetComp, нажмем Class Defaults.

И надо добавить здесь наш виджет, который мы создавали выше. Поменяем значения:

Далее в Event Graph добавим функцию. Для начала вызываем Self, то есть себя, вызываем Get Widget и отсюда вызываем Cast to WB_TooltipBase:

As WB Tooltip Base вызовем Promote to Variable и переменную называем WB Tooltip, и из нее вызовем функцию ApplyData. Из нее вынесем Promote to Variable с Tool Tip Image и c Tool Tip Text, и эти переменные сделаем с глазиками, чтобы их можно было редактировать извне.

Нажмем Class Defaults и поставим дефолтные значения вот такие:

Добавление подсказок в механику взаимодействия с кнопкой

Теперь мы можем этот пресет добавлять в любую нашу механику, объекты взаимодействия и т.д.

Это делается так: заходим в блюпринт, который нам нужен, например, блюпринт кнопки. Нажимаем +Add и выбираем BP_WidgetComp:

Во вьюпорте мы можем его поднять, если нам необходимо, и менять текст и иконку:

Сохраняем, и у нас уже все работает:

Теперь добавим пару нод, чтобы подсказка не всегда отображалась, а только тогда, когда мы подходим к кнопке/двери и т.д.

На примере кнопки. Заходим в BP_Button и нам нужен BeginPlay. Вытягиваем BP_WidgetComp, отсюда вытягиваем Get As WB Tooltip Base, и из этой ноды вытягиваем функцию Set Visibility, и ее соединим с Begin Play.

Это по сути все ноды, которые нам нужны:

Сейчас скопируем эти ноды и вставим в функции Begin Overlap и End Overlap. Во всех объектах взаимодействия есть/будут сферы или коллизии, которые будут считывать, рядом персонаж или нет. И вот туда будем ставить отображение подсказок.

На Begin Overlap включаем:

На End Overlap прячем:

Но мы видим, что иконка после нажатия не сразу пропадает, сейчас мы сделаем это.

Вызываем BP_WidgetComp, с него - Destroy Component, ну а его подключаем к Then 3:

После запуска видим, что в конце баг

Пройдемся по ссылкам после лупы и можем найти, в чем проблема.

Accessed None - распространенная ошибка при кастомных функциях. Это нормально, можем найти баг и пофиксить его.

Подвинем Set Visibility в месте, где выходит ошибка, и запустим проверку. С BP_WidgetComp вызываем Is Valid со знаком вопроса и соединим с другими нодами как на картинке:

Эта нода проверяет, существует ли переменная, если существует, то дальше выполняется функция, ну а если не существует, то ничего не происходит.

Теперь не будет этой ошибки.

Создание механики закрытой (фейковой) двери для взаимодействия

Добавим дверь/кнопку/объект взаимодействия, которая не будет работать для того, чтобы игрок подумал, что локация обширная.

В папке Systems создадим папку FakeDoor, зайдем внутрь. Создаем блюпринт актор, назовем BP_FakeDoor. Зайдем внутрь и добавим статик мэш и назовем его FakeObject:

Сюда по умолчанию подкинем фейковую дверь (блокинг, потом можем заменить на любой объект).

Вместо двери теперь поставим наш блюпринт.

Зайдем еще раз в блюпринт фейковой двери и создадим Box Collision:

Box Collision это та область, в которую мы должны зайти, чтобы у нас появилась иконка для взаимодействия с этой дверью. Делаем ее побольше, пошире, примерно так:

И добавим блюпринт виджета:

Виджет перенесем на место предполагаемой ручки двери. И поменяем иконку виджета, например на ручку двери.

Чтобы еще раз не писать логику, с BP_Button скопируем

и вставим в BP_FakeDoor и подключим к ивенту BeginPlay:

Теперь в Box добавим Begin Overlap:

и еще добавим End Overlap таким же образом. И чтобы не писать логику с нуля, мы просто скопируем с BP_Button и вставим и соединим:

Но у нас ошибка - у нас нет переменных в этом блюпринте.

Создадим, для этого ПКМ -> Create variable 'CharRef':

И так со всеми, создадим переменные.

Сейчас нам нужна логика для активации, скопируем с BP_Button еще ноды и вставим в этот блюпринт:

Дальше ноды скопируем так же с BP_Button (приведу скриншоты, что скопировать):

Остальное на не нужно, и вот что в итоге получилось:

Скопируем NavMeshBoundsVolume и расположим перед фейковой дверью:

Сейчас мы можем подбегать и пытаться открыть много раз, исправим это, чтобы было 1 раз только.

Перед Sequence вызываем ноду Do Once

К Then 3 вызываем функцию Destroy Component иконки, чтобы 1 раз только отображалась:

После него вызываем Delay, ставим его на 3 секунды, прокопируем Destroy Component и в Target вызываем Box:

Теперь все работает.

Применение анимации только на верхнюю часть тела персонажа

Сейчас исправим анимацию, когда персонаж нажимает на кнопку, чтобы ноги не двигались.

Зайдем в BP_FakeDoor, найдем AnimMontage, оттуда найдем анимацию, переходим в Content Browser, прокопируем анимацию и назовем AM_FakeDoorCheck, потом эту анимацию можно заменить на реальную, где персонаж дергает за ручку.

Зайдем в эту анимацию и здесь нам надо поменять слот. У нас анимация выполняется по дефолт слоту, где все движется, но в данном случае мы хотим, чтобы анимация проигрывалась только для верхней части.

Нажимаем на Slot и выберем UpperBody:

Сохраним, и в блюпринте выбираем новую анимацию:

И все, теперь у нас ноги остаются на месте, а анимация проигрывается только для верхней части тела:

На этом этот урок завершен.