Подготовка уровня
Для начала создайте новый проект на основе шаблона острова Стартовый набор Fall Guys. Этот начальный остров содержит готовую полосу, по которой может перемещаться игрок, и в этом уроке мы настроим её, заставив некоторые объекты двигаться.
Определение объектов окружения, способных перемещаться
Прежде чем перемещать объект окружения, необходимо определить, что же такое перемещаемый объект окружения. Вы можете использовать устройство Verse, чтобы перемещать объект окружения напрямую, но это может оказаться сложным, если нужно перемещать несколько объектов окружения одновременно. Вместо этого определим абстрактный класс movable_prop. Он будет содержать объект окружения, который требуется перемещать, и несколько других параметров для настройки логики и времени перемещения объекта.
Следуйте указаниям ниже, чтобы определить перемещаемый объект окружения:
Создайте новый класс Verse с помощью проводника Verse и назовите его
movable_prop. Поскольку это класс Verse, а не устройство, создайте этот файл с помощью команды Создать пустой. И поскольку это будет абстрактный класс, на основе которого мы будем создавать подклассы различных типов перемещаемых объектов окружения, добавьте к этому классу спецификатор<abstract>. Чтобы узнать, как создать новый класс в Verse, см. раздел Измените и запустите свою первую программу на Verse.Verse# Defines a Creative prop that moves to a target or location using animation. movable_prop<public> := class<abstract>():Добавьте пути импорта
using { /Fortnite.com/Devices },using { /Verse.org/Simulation }, иusing { /UnrealEngine.com/Temporary/SpatialMath }в начало файла. Эти модули необходимо импортировать для выполнения вычислений, на основе которых будут перемещаться объекты окружения.Каждое из полей этого класса также будет включать
ToolTip. Добавление к редактируемым полям сообщенияToolTipпозволяет отображать подсказку при наведении курсора на соответствующее поле в UEFN. Ниже приведены все подсказки, используемые в этом классе. Вы можете скопировать и вставить эти подсказки или определить свои собственные.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/SpatialMath } MoveDurationTip<localizes>:message = "The amount of time the prop takes to move to its destination." MoveEaseTypeTip<localizes>:message = "The animation easing applied to the movement." MoveEndDelayTip<localizes>:message = "The delay after the movement finishes." MoveOnceAndStopTip<localizes>:message = "Whether the RootProp should stop in place after it finishes moving." MoveStartDelayTip<localizes>:message = "The delay before the movement starts." MoveTargetsTip<localizes>:message = "The array of CreativeProp to move toward. These targets can be children of the RootProp."Определите поля, необходимые для каждого перемещаемого объекта окружения. Добавьте следующие поля в определении своего класса
movable_prop:Редактируемое поле типа
creative_propс названиемRootProp. Это объект окружения творческого режима, который вы будете перемещать во время игры.Verse# The Creative prop associated with this class. # This should be the root prop of the object you want to move. @editable {ToolTip := RootPropTip} RootProp:creative_prop = creative_prop{}Редактируемая переменная типа
floatс названиемMoveDuration. Это время, необходимое объекту окружения, чтобы достичь места назначения.Verse# The duration in seconds it takes for the prop to move to its destination. @editable {ToolTip := MoveDurationTip} MoveDuration:float = 3.0Редактируемая переменная типа
floatс названиемMoveStartDelay. Это время в секундах, в течение которого объект окружения ждёт перед началом перемещения.Verse# The duration in seconds to wait before movement begins. @editable {ToolTip := MoveStartDelayTip} MoveStartDelay:float = 0.0Редактируемая переменная типа
floatс названиемMoveEndDelay. Это время в секундах, в течение которого объект окружения ждёт после завершения перемещения.Verse# The duration in seconds to wait after movement ends. @editable {ToolTip := MoveEndDelayTip} MoveEndDelay:float = 0.0Редактируемая переменная типа
logicс названиемMoveOnceAndStop. Определяет, будет ли объект окружения перемещаться только один раз или повторять перемещение после его завершения.Verse# Whether the RootProp should stop in place when it finishes moving. @editable {ToolTip := MoveOnceAndStopTip} MoveOnceAndStop:logic = falseРедактируемая переменная типа
logicс названиемShouldReset. Определяет, будет ли объект окружения возвращаться в исходное положение после завершения перемещения.Verse# Whether the RootProp should reset back to the starting position when it # finishes moving. @editable {ToolTip := ShouldResetTip} ShouldReset:logic = falseПеременная
StartingTransformтипа transform. Это преобразование, в котором находитсяRootProp, когда начинает перемещение.Verse# The starting transform of the RootProp. var StartingTransform:transform = transform{}
Окончательное определение класса должно выглядеть следующим образом:
Verseusing { /Fortnite.com/Devices } using { /Fortnite.com/Devices/CreativeAnimation } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/SpatialMath } MoveDurationTip<localizes>:message = "The amount of time in seconds the prop takes to move to its destination." MoveEaseTypeTip<localizes>:message = "The animation easing applied to the movement." MoveEndDelayTip<localizes>:message = "The delay after the movement finishes." MoveOnceAndStopTip<localizes>:message = "Whether the RootProp should stop in place after it finishes moving." MoveStartDelayTip<localizes>:message = "The delay before the movement starts."Прежде чем объект окружения начнёт перемещение, ему нужно знать, откуда он будет перемещаться. Для этого необходимо определить новую функцию, задающую
StartingTransformперед началом перемещения:Добавьте новый метод
SetStartingTransform()в определение классаmovable_prop.В методе
SetStartingTransform()установите в качествеStartingTransformпреобразованиеRootPropс помощью функцииGetTransform().Готовая функция
SetStartingTransform()должна выглядеть следующим образом:Verse# Sets the StartingTransform to the current transform of the RootProp. SetStartingTransform():void= set StartingTransform = RootProp.GetTransform()
Чтобы начать перемещать объект окружения, нужно определить новую функцию
Move():Добавьте новый метод
Move()в определение классаmovable_prop.Добавьте к этой функции модификатор
<suspends>, чтобы она могла выполняться асинхронно. Поскольку это версия функции из базового класса и она не будет использоваться, просто сразу же вернём значение с помощьюreturn.Готовая функция
Move()должна выглядеть следующим образом:Verse# Move the RootProp to its target. This is the base class # version of this function and should not be used. Move()<suspends>:void= return
Если вы хотите, чтобы объект окружения возвращался в исходное положение после завершения перемещения, его необходимо телепортировать обратно в исходное положение. Для решения этой задачи добавьте новый метод
Reset()в определение классаmovable_prop:Добавьте к этой функции модификаторы
<decides><transacts>, чтобы разрешить её откат в случае неудачного выполнения. Это может произойти, если объект окружения был удалён во время игры.В функции
Reset()телепортируйтеRootPropобратно вStartingTransformс помощьюTeleportTo[].Готовая функция
Reset()должна выглядеть следующим образом:Verse# Reset the RootProp by teleporting it back to its Starting Transform. Reset()<decides><transacts>:void= RootProp.TeleportTo[StartingTransform]
Мы определили множество функций, и теперь нужно объединить их в одно целое. Чтобы управлять всеми различными функциями перемещения, добавим новый метод
ManageMovement()в определение классаmovable_prop. Добавьте к этой функции модификатор<suspends>, чтобы она могла работать асинхронно.Verse# Loops moving the RootProp to its target by calling Move(), and handles # any logic when the movement begins and ends. ManageMovement()<suspends>:void=В функции
ManageMovement()создайте выражениеloop, которое будет обрабатывать перемещение. Внутри цикла сначала подождём с помощью функцииSleep()в течениеMoveStartDelayсекунд, а затем вызовемMove().Verse# Loops moving the RootProp to its target by calling Move(), and handles # any logic when the movement begins and ends. ManageMovement()<suspends>:void= loop: Sleep(MoveStartDelay) Move()Когда ваша платформа завершит перемещение, она должна продолжить перемещение, вернуться в исходное положение или остановиться. Чтобы обработать остановку, с помощью выражения
ifпроверим, имеет лиMoveOnceAndStopзначение true. Если да, то выходим из цикла c помощьюbreak. После завершения перемещения подождём с помощью функцииSleep()в течениеMoveEndDelayсекунд. Наконец, в другом выраженииifпроверим, имеет лиShouldResetзначение true, и вызовемReset[], если это так. Готовая функцияManageMovement()должна выглядеть следующим образом:Verse# Loops moving the RootProp to its target by calling Move(), and handles # any logic when the movement begins and ends. ManageMovement()<suspends>:void= loop: Sleep(MoveStartDelay) Move() # If the prop should only move once and stop, then exit the loop. if:Так как в этом классе нет функции
OnBegin(), нужен способ, позволяющий другим классам вызыватьManageMovement()для запуска перемещения платформы. Добавим новую функциюSetup()в определение классаmovable_prop. ВнутриSetup()сначала вызовемSetStartingTransform(), а затем создадим функциюManageMovement(), чтобы начать перемещать платформу. Готовая функцияSetup()должна выглядеть следующим образом:Verse# Set the StartingTransform, then begin movement by spawning ManageMovement. Setup():void= SetStartingTransform() spawn{ManageMovement()}
Далее
Абстрактный класс готов, и на следующем шаге мы разберёмся, как реализовать перемещение объектов с помощью анимации!
Полный код
Ниже приведён полный код, написанный в этом разделе:
movable_prop.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
MoveDurationTip<localizes>:message = "The amount of time in seconds the prop takes to move to its destination."
MoveEaseTypeTip<localizes>:message = "The animation easing applied to the movement."
MoveEndDelayTip<localizes>:message = "The delay after the movement finishes."
MoveOnceAndStopTip<localizes>:message = "Whether the RootProp should stop in place after it finishes moving."
MoveStartDelayTip<localizes>:message = "The delay before the movement starts."