A series of disappearing platforms is a staple of platforming game modes like obstacle courses. These require players to time their jumps across a series of platforms, or they'll fall and have to start over.
By following this tutorial, you'll learn how to create a series of platforms that sequentially appear and disappear using one device created with Verse in Unreal Editor for Fortnite (UEFN).
Verse Language Features Used
-
array
: With thearray
type, you can store platform references together for quick access and to avoid code duplication. -
loop
: The platform cycle of platforms appearing and disappearing should start when the game begins and run continuously. This example shows how to create this behavior with the Verseloop
expression. -
block
: With theblock
expression, you can group multiple expressions together so they are executed sequentially. -
for
: With thefor
expression, you can iterate over each platform in your array. -
sync
: With thesync
expression and structured concurrency, you can run multiple async expressions concurrently.
Verse APIs Used
-
Sleep()
: With theSleep()
API, you can choose how long the platforms will be in their invisible and visible states. -
Editable Properties: severalVerse-authored device properties are exposed to UEFN so you can customize them in the Editor – three delays for the platforms' behavior and four device references to the platforms.
Instructions
Follow these steps to learn how to set up a series of platforms that disappear and appear periodically. The complete script is included at the end of this guide for reference.
Setting Up the Level
This tutorial uses the Verse Starter Template as its starting point. To get started, initialize a new project from the Verse Device feature example.
This example uses the following props and devices.
-
1 x Player Spawn Pad Device: This device defines where the player spawns at the start of the game.
-
6 x Creative Prop: Creative props have several behaviors you can call with Verse, such as
Hide()
andShow()
to toggle the platform's visibility and collision. This tutorial uses the Airborne Hoverplatform A as the player-interactable platform, but feel free to change this to suit the needs of your experience.
Follow these steps to set up your level:
-
Add one Airborne Hoverplatform A to your scene. Place it above the floor so the player will fall if they don't jump off the disappearing platform in time. In the Outliner, name the platform SynchronizedPlatform1.
-
Duplicate the platform several times to create a line. Then place Player Spawn Pad device on the platform where you want your player to start. Your complete setup should look like this:
Creating the Device
This example uses a Verse-authored device to define the behavior for toggling the visibility of the platforms. Follow these steps to create this device using Verse.
-
Create a new Verse device named platform_series. To learn how to create a new device in Verse, see Create Your Own Device Using Verse.
-
Drag the platform_series device from the Content Browser into the level.
Editing the Device Properties in UEFN
This section shows how to expose device properties to UEFN so you can customize them in the editor:
-
Three
float
constants to store how long the platforms should be invisible/visible namedHeadStart
,AppearDelay
, andDisappearDelay
. -
Devices references to the creative objects you placed in the level.
Follow these steps to expose these properties from the platform_series device you created in the previous section.
-
Open Verse Explorer and double-click platform_series.verse to open the script in Visual Studio Code.
-
To the
platform_series
class definition, add the following fields:-
An editable
float
namedHeadStart
. This represents how long to wait, in seconds, after platforms start appearing and before platforms start disappearing. Initialize this value to2.5
or two and a half seconds.# How long to wait in seconds after platforms start appearing # before they start disappearing. @editable HeadStart:float = 2.5
-
An editable
float
namedAppearDelay
. This represents how long to wait, in seconds, before the next platform appears. Initialize this value to1.0
, or one second.# How long to wait in seconds before the next platform appears. @editable AppearDelay:float = 1.0
-
An editable
float
namedDisappearDelay
. This represents how long to wait, in seconds, before the next platform disappears. Initialize this value to1.25
, or one and a quarter seconds.# How long to wait in seconds before the next platform disappears. @editable DisappearDelay:float = 1.25
-
An editable
creative_prop
namedDisappearingPlatform
. This is the in-level platform that will disappear and appear. Because your code doesn't yet have a reference to this object in the level, you'll instantiate this with an empty archetypecreative_prop{}
. You'll assign this reference to your floating platform later.# The in-level platform that disappears and reappears. @editable DisappearingPlatform:creative_prop = creative_prop{}
-
-
Your
platform_series
class fields should look like this:# 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 AppearDelay:float = 1.0 # How long to wait in seconds before the next platform disappears. @editable DisappearDelay:float = 1.25 # The in-level platform that disappears and reappears. @editable DisappearingPlatform:creative_prop = creative_prop{}
It's helpful to use the
@editable
attribute to expose values likeAppearDelay
to the editor from your scripts. This lets you customize their values in UEFN without having to rebuild Verse code each time, so you can iterate quickly and find values that fit your gameplay experience. -
Save the script in Visual Studio Code.
-
In the UEFN toolbar, click Verse, and then Build Verse Code to update the platform_series device that's in the level.
-
In the Outliner panel in UEFN, select the platform_series device to open its Details panel.
-
In the Details panel under Platform Series, set DisappearingPlatform to SynchronizedPlatform1 (the creative prop you added to the level) by clicking on the object picker and selecting the platform in the viewport.
Hiding and Showing a Platform
Now that you've set up the level and the first platform, let's add the functionality to show and hide the platform. Follow these steps to add this behavior to the platform_series device:
-
The
creative_prop
class has two methods to toggle its visibility:Hide()
andShow()
. Back in Visual Studio Code, InOnBegin()
, callHide()
and thenShow()
on yourDisappearingPlatform
.# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Hide the platform. DisappearingPlatform.Hide() # Show the platform. DisappearingPlatform.Show()
If you run this code, you won't see the platform disappear and reappear because the calls
Hide()
andShow()
occur immediately after each other. -
To make the platform stay in a visible/invisible state longer, you can add a delay when calling either
Hide()
orShow()
usingSleep()
. TheSleep()
function suspends a routine's execution, and you specify the amount of time (in seconds) to suspend execution by passing in afloat
argument to the function. CallSleep()
before eachHide()
andShow()
call, passing theDisappearDelay
you defined earlier.# 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. DisappearingPlatform.Show()
If you run this code, the
Platform
will be invisible for one second (the amount defined byDisappearDelay
) before it becomes visible for the rest of the game.The
Sleep()
function can only be called in an asynchronous context. TheOnBegin()
method is already an asynchronous context since it has thesuspends
specifier, so you don't need to do anything further. To learn more about thesuspends
specifier, see Specifiers and Attributes.
Hiding and Showing Multiple Platforms
While you could repeat the code in the previous step for every platform in the level that you want to disappear, creating an array to store all the device references is more efficient. This will let you iterate through each platform in the array, executing code on each without having to duplicate the Verse device multiple times. Follow these steps to hide and show multiple platforms:
-
In your
platform_series
class definition, change theDisappearingPlatform
field to an array ofcreative_prop
namedDisappearingPlatforms
. You'll use this array to iterate over the platforms in order. Initialize the variable with the default valuearray{}
, an empty array.# The in-level platforms that disappear and reappear in sequence. @editable DisappearingPlatforms:[]creative_prop = array{}
-
You can use the
for
expression to iterate over each element in the array. Thefor
expression uses theX -> Y
pattern, to give you an index-value pairing. The index is bound to the left part (X
) and the value is bound to the right part (Y
). In this case,X
is the platform's number / index andY
is each platform reference retrieved from the array. First, create afor
expression to iterate over each element, and get the index of each number in a variablePlatformNumber
.~~~(verse) # Runs when the device is started in a running game OnBegin
() :void= for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: ~~~ -
Print out the number of the platform, and call
Hide()
to hide the platform. ThenSleep()
for aDisappearDelay
amount of seconds.# 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)
-
To show the platforms against, you'll use a second
for
expression after the first. Iterate over each platform inDisappearingPlatforms
in the same way, except this time callShow()
to show the platform, andSleep()
for anAppearDelay
amount of seconds.~~~(verse) # For each platform in DisappearingPlatforms, make it visible and sleep. for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: # Show the platform. DisappearingPlatform.Show() Print("Platform {PlatformNumber} is now visible") Sleep(AppearDelay) ~~~
-
When writing code, it's a good idea to put code you might want to reuse into separate functions. This lets you call the code from different contexts, and avoid having to rewrite the same code over and over. Depending on your experience you may want to hide and show the platforms during different situations, so you'll make functions to handle each of these. Add two new functions named
HideAllPlatforms()
andShowAllPlatforms()
to yourplatform_series
class definition. Move thefor
expression that handles hiding the platforms intoHideAllPlatforms()
, and the expression that handles showing the platforms intoShowAllPlatforms()
. Since you're using theSleep()
function, these functions need to be asynchronous, so add the<suspends>
modifier to each. Then inOnBegin()
, callHideAllPlatforms()
, thenShowAllPlatforms()
.# 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: # Hide the platform DisappearingPlatform.Hide() Print("Platform {PlatformNumber} is now hidden") Sleep(DisappearDelay) ShowAllPlatforms()<suspends>:void= # For each platform in DisappearingPlatforms, make it visible and sleep. for: PlatformNumber -> DisappearingPlatform:DisappearingPlatforms do: # Show the platform. DisappearingPlatform.Show() Print("Platform {PlatformNumber} is now visible") Sleep(AppearDelay)
-
As it stands, this code will only run once. To make the platforms disappear and reappear for as long as the game is running, you can use the
loop
expression to repeat this behavior. To handle this, add aloop
expression toOnBegin()
that includes the calls toHideAllPlatforms()
andShowAllPlatforms()
In this example, you want to toggle the visibility of the platforms for as long as the game is running, so there's no need to add abreak
expression to exit theloop
.# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= loop: # Hide all platforms. HideAllPlatforms() # Show all platforms. ShowAllPlatforms()
If you run this code, the platforms will all disappear in sequence first and then all reappear in the same order, repeating until the game ends.
-
Save your code and compile it. In the Outliner panel in UEFN, select the platform_series device to open its Details panel.
-
In the Details panel under DisappearingPlatforms, add an array element for each platform in the level. Add new elements to the array with the "Add Element" button, then click on the object picker and select the creative prop in the viewport. Make sure that the order of this array matches the order you want to iterate over:
Now if you run this code, the platforms will all disappear in sequence first then reappear in the same order, repeating until the game ends.
Synchronize the Platforms Disappearing and Reappearing
To add more urgency as the player jumps across the tiles, you can make the platforms start disappearing while platforms later in the sequence are still appearing. That way, the player will have to rush across the series or they'll fall. To create this behavior, both routines (ShowAllPlatforms()
and HideAllPlatforms()
) must run at the same time, with the second lagging behind the first, so that the player has a head start to jump to the next platform before it disappears.
Follow these steps to make the platforms all hide and show at the same time.
-
To have
HideAllPlatforms()
andShowAllPlatforms()
run concurrently, you can use thesync
expression. Thesync
expression executes the two or more asynchronous expressions in its code block at the same time, and waits until all its expressions are finished before continuing. InOnBegin()
, inside theloop
expression, add async
expression onHideAllPlatforms()
andShowAllPlatforms()
# 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()
-
If you run this code as is, hiding and showing a platform will happen simultaneously. This isn't the desired result, so you'll need to delay platform disappearance by a little bit. To give the player a head start, you'll want to use
Sleep()
, passing in theHeadStart
value. Since thesync
expression executes all the expressions in its code block at the same time, you must use theblock
expression to nest theSleep()
andHideAllPlatforms()
. Addblock
expression that coversSleep()
andHideAllPlatforms()
. Now the sync will run two expressions. The first callsShowAllPlatforms()
, and the second callsSleep()
, and afterwards callsHideAllPlatforms()
.# 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. ShowAllPlatforms()
-
Save the script and click Verse, and then Build Verse Code to compile the code.
-
Click Launch Session in the UEFN toolbar to playtest the level.
When you playtest the level now, the platforms start disappearing in sequence while the platforms later in the sequence reappear, and this pattern repeats for as long as the game is running.
Complete Script
The following code is the complete script for making a series of platforms that appear and disappear in sequence.
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
# before they start disappearing.
@editable
HeadStart:float = 2.5
# How long to wait in seconds before the next platform appears.
@editable
AppearDelay:float = 1.0
# How long to wait in seconds before the next platform disappears.
@editable
DisappearDelay:float = 1.25
# The in-level platforms that disappear and reappear in sequence.
@editable
DisappearingPlatforms:[]creative_prop = array{}
# Runs when the device is started in a running game
OnBegin<override>()<suspends>:void=
<#
Verse's structured concurrency makes it very expressive to describe concurrent operations and how they should run.
In this case, there are two coroutines:
- One starts immediately and makes the platforms visible in the same order they're stored in the array
- The other waits to start before making the same platforms invisible in the same order they're stored in the array
#>
loop:
# Run both expressions concurrently using sync.
sync:
# The block expression starts immediately at the same time as ShowAllPlatforms(). All expressions in this code block are executed sequentially.
block:
Sleep(HeadStart)
# Hide all platforms.
HideAllPlatforms()
# Show all platforms. This coroutine starts immediately and is executed the same time as the block expression.
ShowAllPlatforms()
HideAllPlatforms()<suspends>:void=
# 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)
ShowAllPlatforms()<suspends>:void=
# For each platform in DisappearingPlatforms, make it visible and sleep.
for:
PlatformNumber -> DisappearingPlatform:DisappearingPlatforms
do:
# Show the platform.
DisappearingPlatform.Show()
Print("Platform {PlatformNumber} is now visible")
Sleep(AppearDelay)
On Your Own
By completing this tutorial, you've learned how to create a device using Verse that toggles the visibility of a series of platforms for as long as the game runs.
Using what you've learned, try the following:
-
Change the order the platforms appear and disappear.
-
Apply the same concepts to periodically call functions on other device types, such as the Prop Mover Device.