Меня зовут Мария. И мы вдвоём с моим мужем Алексеем работаем над созданием небольшой игры.Для игры нам необходимо было сделать заставку. Я видела её как видео, в котором нарисованные кадры сменяют друг друга, а все фразы персонажей отображаются субтитрами.Было два очевидных варианта решения: подготовить видео заранее в After Effect либо сделать анимацию из кода. Минус первого варианта очевиден – огромный размер файла и меньшая гибкость, поэтому мы остановились на втором.Я нарисовала 9 кадров для "черновой" версии вступления. Начнём с того, что добавим изображения в проект. Создадим структуру папок , на первом уровне будем хранить программные компоненты, на втором - изображения. Порядок в папках очень важен. Не пренебрегайте им! После добавления изображений, нам потребуется сущность описывающая содержимое каждого кадра. Создаём структуру из трёх полей:1) Изображение (тип: Texture 2D)2) Текст с фразой персонажа (тип: Text)3) Длительность показа кадра (тип: Float)Структура данных кадраТеперь, имея описание структуры кадра создаём на её основе таблицу типа DataTable.Выбираем структуру для строк таблицы.Каждой строкой таблицы будет уже созданная нами структура данных, представляющая собой изображение, фразу и время длительности кадра.Имя строки используется для получения данных из конкретной строки. Мы указываем его числами, чтобы можно было обращаться к ним последовательно.Заполняем табличку данными для каждого кадра.Заполненная таблицаПриступим к созданию компонента отображения. Создаём виджет на основе User Widget.Открываем созданный виджет. Для добавления внутрь контента нам необходим контейнер способный хранить в себе несколько элементов. Я выбираю Grid Panel, потому что в нём достаточно удобно располагать элементы в табличной верстке.В Grid Panel создаём один столбец и две строки. Строкам зададим относительные размеры как 70 и 30 процентов от высоты компонента. Это сделано для того, чтобы в последствии расположить компонент с текстом в нижней части кадра.В Column [0] нужно указать любое значение больше нуля, чтобы занять всю ширину компонента. Подготовив вёрстку из двух вертикально расположенных ячеек добавим непосредственно компоненты отображения. Изображение мы будем выводить на компонент Image. Добавляем его на панель. По умолчанию Row и Column = 0, а компонент занял ячейку в верхней строке таблицы в первом столбце. Чтобы занять обе вертикальные ячейки укажем Row Span = 2.Чтобы было нагляднее добавим первый кадр нашей заставки. А чтобы легче было обращаться изменим имя на Image и проверим, что справа вверху стоит галочка "Is Variable".Теперь добавим компонент для отображения текста, Text. Чтобы он гарантированно отображался поверх изображения ставим слой равный 1 (Layer=1).После этого задаём строку равную 1 (Row=1), т.к. отчёт идёт от нуля, а нижнее поле мы заготовили как раз для текста. Горизонтальную и вертикальную привязки ставим по центру.А теперь нам нужно создать переменную, в которую мы будем передавать данные для отображения текста и привязать её к компоненты. Идем в Graph -> My Blueprint. Нажимаем на + в разделе Variables.Заполняем название и тип. Название пусть будет TextForShow, а тип - Text.Сохраняем.Возвращаемся к компоненту, в разделе Content (Содержимое) создаём привязку (Binding) для поля Text к нашей переменной TextForShow.Можно считать полдела уже сделано. Вся визуальная часть подготовлена. Осталось прописать логику.Для переключения кадров нам нужен счетчик кадров. Создаём ещё одну переменную типа - целое число (Integer).Значение по умолчанию указываю 1, потому что в таблице кадров наименования начинаются с единички.После этого создадим функцию для получения и отображения кадра.Назовем ее UpdateFrame.Мы берем переменную содержащую текущий номер кадра и функцию получения строки из таблицы данных.Так как счетчик кадров у нас число нам нужно преобразовать его в строку, а затем преобразовать в имя. Теперь мы можем обращаться к содержимому строки соответствующей номеру кадра. И отобразить это содержимое.Давайте создадим кисть. Нам нужно создать кисть, потому что на объекте Image мы можем отобразить только кисть. Мы делаем кисть из текстуры.Так как в заставке все изображения одинакового размера мы указываем разрешение текстуры здесь. Если бы изображения были разного размера, нам бы пришлось добавить информацию о размерах каждого из них в таблицу. Вводим разрешение текстуры.Теперь можем взять Image. Image это у нас объект, на котором отображается картинка.Сделать ему "Установить кисть" (Set Brush).Далее нам нужно присвоить текст.Устанавливаем переменную "Текст для отображения" (TextForShow).Теперь у нас отображены как картинка, так и текст для текущего кадра. Кроме этого, нам нужно запомнить длительность кадра.Сделаем переменную Time типа число с плавающей точкой (Float) и установим ее.Законченная функция UpdateFrameВозвращаемся на Event Graph.Обработаем событие Event Construct, вызывающееся при создании виджета. Ставим игру на паузу (Set Game Pause).И вызываем функцию UpdateFrame. Так мы поставили отображаться первый кадр.Чтобы переключать кадры дальше, нам нужно каждый тик проверять сколько прошло и прибавлять этот промежуток времени к некому таймеру.Давайте сейчас создадим переменную для этого таймера. Имя пусть будет FrameLen, а тип - Float.Надо задать ему значением по умолчанию ноль.Заставим таймер работать. Каждый тик берём FrameLen и складываем с InDeltaTime (промежуток времени с предыдущего вызова события) записывая результат во FrameLen.Теперь нам нужно ждать столько тиков пока переменная FrameLen не станет больше переменной Time (длительность кадра).Как только таймер стал больше - значит пора отображать следующий кадр.Сначала нам нужно проверить на каком мы сейчас номере кадра и не вышли ли мы за пределы таблицы. В этом примере я укажу конкретное число, но безопаснее предварительно посчитать количество строк и записать его в переменную.Если количество кадров меньше девяти, тогда мы увеличиваем внутренний счетчик на единицу.После того, как мы обновили счетчик кадров мы можем обновить содержимое кадра. Осталось только сбросить таймер, установив переменную FrameLen в 0.Теперь нужно обработать ситуацию, когда финальный кадр уже показан. Мы снимаем игру с паузы. И закрываем виджет.Виджет полностью готов для использования. Давайте его проверим.Откроем Level Blueprint.У нас здесь уже есть немного логики. Делаем Remove All Widget. Это обезопасит наc от ситуации, когда какой-нибудь элемент интерфейса будет отображаться одновременно с заставкой.Создаем новый виджет. Выбираем его класс.И добавляем его для отображения.Все готово! Можно запускать уровень, чтобы посмотреть итог.Преимущества этого способа в том, что мы создали очень гибкую систему. Просто редактируя табличку, мы можем полностью изменять все параметры заставки.А на этом всё. Всем спасибо за внимание, а Алексею за проделанную работу. Увидимся! Статья написана на основе видео. Можете его посмотреть. Там есть кот.
В текстурах-картинках еще можно отключить mip mapping и поставить и отключить streaming.