Серия исчезающих платформ является основным элементом в играх жанра «платформер», таких как полосы препятствий. В таких играх игроки должны заранее планировать прыжки с одной платформы на другую, иначе они упадут, после чего придётся начинать всё заново.
В этом уроке вы научитесь создавать последовательную цепочку платформ, которые исчезают и появляются друг за другом. В этом вам поможет язык Verse в Unreal Editor для Fortnite (UEFN).
Используемые функции языка Verse
array: с помощью типа array можно хранить ссылки на платформе для быстрого доступа и во избежание дублирования кода.
loop: цикл появления и исчезновения платформы должен запускаться в начале игры и продолжаться до её окончания. В данном примере показано, как реализовать такое поведение с помощью выражения
loop
в Verse.block: с помощью выражения
block
можно группировать несколько выражений так, чтобы они выполнялись друг за другом.for: с помощью выражений с
for
можно перебирать платформы в вашем массиве.sync: с помощью выражения
sync
и структурированного конкурентного выполнения можно выполнять несколько асинхронных выражений одновременно.
Используемые API Verse
Sleep()
: с помощью APISleep()
можно задать время видимости/невидимости платформ.Редактируемые свойства: несколько свойств Verse-устройств выведены в UEFN, и вы можете настраивать их через редактор: три задержки для задания поведения платформ и четыре ссылки на устройства, связанные с платформами.
Указания
Выполните следующие действия, чтобы настроить серию платформ, которые будут периодически исчезать и появляться: В конце этого урока для справки приведён полный сценарий.
Подготовка уровня
В этом уроке в качестве отправной точки используется стартовый шаблон Verse. Для начала создайте новый проект на основе примера использования функции устройства Verse.
В этом примере используются следующие объекты окружения и устройства.
1 устройство «Точка появления игрока»: это устройство определяет, где должен появляться игрок в начале игры.
6 объектов окружения творческого режима: они имеют несколько вариантов поведения, которые можно вызвать с помощью Verse, такие как
Hide()
иShow()
, чтобы переключать видимость и столкновение платформ. В этом уроке в качестве платформы, с которой взаимодействует пользователь, используется Аэроплатформа A, но вы легко можете заменить её на что-то другое, более соответствующее вашему острову.
Выполните следующие действия, чтобы подготовить уровень:
Добавьте одну Аэроплатформу A в свою сцену. Разместите её над полом, чтобы игрок падал, если он не успеет спрыгнуть с исчезающей платформы. Назовите платформу SynchronizedPlatform1 на панели Структура.
Продублируйте платформу несколько раз, чтобы создать линию. Разместите устройство **Точка появления игрока** на платформе, с которой должен стартовать игрок. Всё вместе должно выглядеть следующим образом:
Создание устройства
В данном примере для определения поведения, которое переключает режимы видимости платформы, используется Verse-устройство. Ниже пошагово описан процесс создания этого устройства на языке Verse.
Создайте новое устройство Verse и назовите его platform_series. Чтобы узнать, как создать новое устройство в Verse, обратитесь к разделу Создание собственного устройства в Verse.
Перетащите устройство platform_series из Каталога ресурсов на уровень.
Редактирование свойств устройства в UEFN
В данном разделе показано, как вывести свойства устройства в UEFN, чтобы их можно было настраивать в редакторе:
Три константы типа
float
для хранения времени видимости/невидимости платформы:HeadStart
,AppearDelay
иDisappearDelay
.Ссылки устройств на объекты творческого режима, которые вы разместили на уровне.
Следуйте дальнейшим инструкциям, чтобы вывести эти свойства устройства platform_series, которое вы создали в предыдущем разделе, в редактор.
Откройте проводник Verse и дважды нажмите на файл platform_series.verse, чтобы открыть сценарий в Visual Studio Code.
Добавьте следующие поля в определение класса
platform_series
:Редактируемая переменная типа
float
с названиемHeadStart
. Она содержит время (в секундах) от начала появления платформы до начала её исчезновения. Инициализируйте её со значением2.5
, что означает две с половиной секунды.Verse# How long to wait in seconds after platforms start appearing # before they start disappearing. @editable HeadStart:float = 2.5
Редактируемая переменная типа
float
с названиемAppearDelay
. Она содержит время (в секундах) до появления следующей платформы. Инициализируйте её со значением1.0
, что означает одна секунда.Verse# How long to wait in seconds before the next platform appears. @editable AppearDelay:float = 1.0
Редактируемая переменная типа
float
с названиемDisappearDelay
. Она содержит время (в секундах) до исчезновения следующей платформы. Инициализируйте её со значением1,25
, что означает одна секунда с четвертью.Verse# How long to wait in seconds before the next platform disappears. @editable DisappearDelay:float = 1.25
Редактируемое поле класса
creative_prop
с названиемDisappearingPlatform
. Оно относится к платформе, которая будет исчезать и появляться. Так как в вашем коде ещё нет ссылки на этот объект на уровне, вам нужно создать его экземпляр с пустым архетипомcreative_prop{}
. Ссылку на свою парящую платформу вы назначите позже.Verse# The in-level platform that disappears and reappears. @editable DisappearingPlatform:creative_prop = creative_prop{}
Поля класса
platform_series
теперь должны выглядеть следующим образом:Verse# A Verse-authored creative device that can be placed in a level platform_series := class(creative_device): # How long to wait in seconds after platforms start appearing # before they start disappearing. @editable HeadStart:float = 2.5 # How long to wait in seconds before the next platform appears. @editable
Полезно добавить атрибут
@editable
, чтобы вывести из своего сценария в редактор такие значения какAppearDelay
. Это позволит вам настраивать их в UEFN, не пересобирая каждый раз код Verse, чтобы вы могли быстро перебирать и находить значения, которые соответствуют вашему игровому процессу.Сохраните сценарий в Visual Studio Code.
Нажмите Verse на панели инструментов UEFN, а затем Собрать код Verse, чтобы обновить устройство platform_series, размещённое на уровне.
На панели Структура в UEFN выберите устройство looping_disappearing_platform, чтобы открыть его панель Сведения.
На панели Сведения в разделе Цепочка платформ установите для DisappearingPlatform значение SynchronizedPlatform1 (объект окружения творческого режима, добавляемый на уровень), нажав на инструмент выбора объекта и выбрав устройство «Платформа» в окне просмотра.
Управление появлением и исчезновением платформы
После настройки уровня и первой платформы можно добавить функции появления и исчезновения платформы. Выполните следующие действия, чтобы задать это поведение устройству platform_series:
В классе
creative_prop
реализованы два метода переключения видимости:Hide()
иShow()
. Вернитесь в Visual Studio Code, вOnBegin()
задайте вызовHide()
, а затемShow()
для своейDisappearingPlatform
.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Hide the platform. DisappearingPlatform.Hide() # Show the platform. DisappearingPlatform.Show()
Если вы запустите этот код, то не увидите, как платформа исчезает и появляется, потому что методы
Hide()
иShow()
срабатывают один за другим.Чтобы платформа дольше оставалась видимой/невидимой, добавьте задержку при вызове
Hide()
илиShow()
с помощью метода`Sleep()`. Функция
Sleep()
приостанавливает программу — вы можете задать определённое время (в секундах), чтобы приостановить выполнение, передав в функцию аргумент типаfloat
. Задайте вызовSleep()
перед каждым вызовомHide()
иShow()
, чтобы передать задержкуDisappearDelay
, которую вы определили до этого.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Hide the platform. DisappearingPlatform.Hide() # Wait for DisappearDelay seconds. Sleep(DisappearDelay) # Show the platform.
Если вы запустите этот код,
платформа будет невидимой в течение одной секунды (значение, определённое в
DisappearDelay
), после чего вновь станет видимой до конца игры.Функция
Sleep()
может быть вызвана только в асинхронном контексте. Поскольку методOnBegin()
уже поддерживает асинхронный контекст, то есть содержит спецификаторsuspends
, вам больше не нужно ничего делать. Более подробно об спецификатореsuspends
рассказано в разделе Спецификаторы и атрибуты.
Исчезновение и появление нескольких платформ
Вы можете повторить код, приведённый в предыдущем разделе, для каждой расположенной на уровне платформы, которая должна исчезать, создав массив для более эффективного хранения ссылок устройства. Это позволит вам перебирать все платформы в массиве, выполняя код на каждой из них без необходимости дублировать устройство Verse несколько раз. Чтобы исчезали и появлялись несколько платформ, выполните следующие действия:
Замените в определении класса
platform_series
полеDisappearingPlatform
на массив объектов окруженияcreative_prop
с названиемDisappearingPlatforms
. Этот массив понадобится для перебора платформ по порядку. Инициализируйте переменную значением по умолчаниюarray{}
(пустой массив).Verse# The in-level platforms that disappear and reappear in sequence. @editable DisappearingPlatforms:[]creative_prop = array{}
Вы можете использовать выражение
for
для перебора элементов массива. В выраженииfor
используется отношениеX -> Y
для получения пар «индекс-значение». Индекс привязан к левой части (X
), а значение — к правой (Y
). В данном случаеX
— это номер/индекс платформы, аY
— ссылка на каждую платформу, полученная из массива. Сначала создайте выражениеfor
для перебора по каждому элементу и получите индекс каждого числа в переменнойPlatformNumber
.~~~(verse) # Выполняется при запуске устройства в работающей игре OnBegin<override>()<suspends>:void= for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: ~~~
Задайте вывод номера платформы и вызов
Hide()
, чтобы скрыть платформу. Затем задайте количество секунд вSleep()
для`DisappearDelay`.
Verse# For each platform in DisappearingPlatforms, make it invisible and sleep. for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: # Hide the platform DisappearingPlatform.Hide() Print("Platform {PlatformNumber} is now hidden") Sleep(DisappearDelay)
Чтобы показать платформы напротив, вы используете второе выражение
for
после первого. Переберите платформы вDisappearingPlatforms
таким же образом, только на этот раз задайте вызовShow()
, чтобы показать платформу, и количество секунд вSleep()
дляAppearDelay
.~~~(verse) # Сделаем каждую платформу в DisappearingPlatforms видимой и отправим в режим ожидания. for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: # Показать платформу. DisappearingPlatform.Show() Print("Платформу {PlatformNumber} теперь видно") Sleep(AppearDelay) ~~~
При программировании рекомендуется выносить код, который может быть использован повторно, в отдельные функции. Это позволит вам вызывать код из разных контекстов и избежать необходимости переписывать один и тот же код снова и снова. В зависимости от специфики вашей игры может понадобиться скрывать и показывать платформы в различных ситуациях, поэтому вы создадите функции для работы с каждой из них. Добавьте в определение класса
platform_series
две новые функцииHideAllPlatforms()
иShowAllPlatforms()
. Переместите выражениеfor
, которое управляет скрытием платформ, вHideAllPlatforms()
, а выражение, которое управляет показом платформ, — вShowAllPlatforms()
. Так как вы используете функциюSleep()
, эти функции должны быть асинхронными, поэтому добавьте модификатор<suspends>
к каждой из них. После этого задайте вOnBegin()
вызовHideAllPlatforms()
, а затемShowAllPlatforms()
.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= HideAllPlatforms() ShowAllPlatforms() HideAllPlatforms()<suspends>:void= # For each platform in DisappearingPlatforms, make it invisible and sleep. for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do:
Код, который есть сейчас, будет запускаться только один раз. Чтобы платформа исчезала и появлялась на протяжении всей игры, можно использовать выражение loop. Для этого добавьте
loop
в функциюOnBegin()
, которая содержит вызовыHideAllPlatforms()
иShowAllPlatforms()
. В этом примере нам нужно переключать режим видимости платформ на протяжении всей игры, поэтому нет необходимости добавлять выражениеbreak
для прерывания циклаloop
.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= loop: # Hide all platforms. HideAllPlatforms() # Show all platforms. ShowAllPlatforms()
Если вы запустите этот код, платформы начнут появляться одна за другой, а затем исчезать в том же порядке, и так будет повторяться до конца игры.
Сохраните свой код и скомпилируйте его. На панели Структура в UEFN выберите устройство looping_disappearing_platform, чтобы открыть его панель Сведения.
Добавьте для каждой платформы на уровне массив элементов в секции DisappearingPlatforms на панели Сведения. Добавьте в массив новые элементы, нажав кнопку <strong>Добавить элемент</strong>, а затем на инструмент выбора объекта и выбрав устройство творческого режима в окне просмотра. Порядок элементов в массиве должен совпадать с порядком, в котором должен выполняться их перебор:
Теперь, когда вы запустите этот код, платформы начнут появляться одна за другой, а затем исчезать в том же порядке, и так будет повторяться до конца игры.
Синхронизация исчезновения и появления платформ
Чтобы побудить игрока ещё быстрее перемещаться с одной плитки на другую, можно сделать так, чтобы первые платформы начинали исчезать, пока последующие платформы ещё отображаются. Так игроку придётся поторопиться, иначе он просто упадёт. Чтобы воссоздать такое поведение, оба метода (ShowAllPlatforms()
и HideAllPlatforms()
) должны выполняться одновременно, причём второй должен отставать от первого, чтобы у игрока была фора для перехода на следующую платформу до того, как она исчезнет.
Чтобы все платформы исчезали и появлялись одновременно, выполните следующие действия.
Чтобы методы
HideAllPlatforms()
иShowAllPlatforms()
выполнялись конкурентно, можно использовать выражение sync. Этовыражение одновременно выполняет два и более асинхронных выражения в блоке кода и ждёт, пока все его выражения будут выполнены. Только после этого выполняется последующий код. В
OnBegin()
внутри выраженияloop
добавьте выражениеsync
дляHideAllPlatforms()
иShowAllPlatforms()
Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= loop: # Run both expressions concurrently using sync. sync: # Hide all platforms. HideAllPlatforms() # Show all platforms. ShowAllPlatforms()
Если вы запустите этот код в таком виде, исчезновение и появление платформ будет происходить одновременно. Это не совсем то, что нам нужно, поэтому вам необходимо задать небольшую задержку исчезновения платформы. Чтобы дать игроку фору, используйте
Sleep()
, передав значение вHeadStart
. Поскольку выражениеsync
выполняет все выражения в своём блоке кода одновременно, необходимо использовать выражениеblock
над функциямиSleep()
иHideAllPlatforms()
. Добавьте выражениеblock
, которое охватываетSleep()
иHideAllPlatforms()
. Теперь sync будет выполнять два выражения. Сначала вызываетсяShowAllPlatforms()
, затемSleep()
, и после этого вызываетсяHideAllPlatforms()
.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= loop: # Run both expressions concurrently using sync. sync: block: Sleep(HeadStart) # Hide all platforms. HideAllPlatforms() # Show all platforms.
Сохраните сценарий и нажмите Verse, а затем Собрать код Verse, чтобы скомпилировать код.
Нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня.
Теперь при игровом тесте уровня платформы начнут исчезать по очереди, тогда как другие платформы, следующие за ними, будут появляться снова, и так будет продолжаться до конца игры.
Полный сценарий
Следующий код представляет собой полный сценарий для создания серии платформ, которые исчезают и появляются по очереди.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# See https://dev.epicgames.com/documentation/en-us/uefn/create-your-own-device-in-verse for how to create a verse device.
# A Verse-authored creative device that can be placed in a level
platform_series := class(creative_device):
# How long to wait in seconds after platforms start appearing
Самостоятельная работа
В этом уроке вы научились создавать устройство с помощью Verse, которое переключает режим видимости цепочки платформ на протяжении всей игры.
Используя полученные знания, попробуйте выполнить следующее:
Измените порядок появления и исчезновения платформ.
Примените рассмотренные концепции для периодического вызова функций устройств других типов, таких как устройство перемещения объектов.