With gameplay tags, you can find actors marked with a specific tag while the game is running. Gameplay tags let you work with multiple actors without needing to set up properties and assign references in Unreal Editor for Fortnite (UEFN). Gameplay tags are created in Verse code and assigned in UEFN.
Using gameplay tags can open up interesting gameplay opportunities, such as:
Altering the level setup without having to add or modify device references to your Verse-authored device.
Finding all actors with a specific tag and operating them based on their type, such as turning on lights or toggling barriers.
Dynamically changing which actors are active as the player progresses through the game.
Conditionally enabling actors for an obstacle run based on a player-selected difficulty option.
What Can Be Tagged?
Currently, gameplay tags can be assigned to the following:
The following sections show how to create and work with gameplay tags in your project.
Creating a Gameplay Tag
Follow these steps to create a new gameplay tag using Verse:
Open your Verse file in Visual Studio Code with Verse Explorer.
At the top of your Verse file, add the following code to enable referencing the
tag
class.Verseusing { /Verse.org/Simulation/Tags }
Create a new class that inherits from the
tag
class. The name of your class determines the name of the tag. In this example, the class is namedmytag
, so the gameplay tag's name is mytag.Verse# Derive from the `tag` class in the Verse.org/Simulation/Tags module to create a new gameplay tag. mytag := class(tag){}
Your Verse file should look like this:
Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /Verse.org/Simulation/Tags } # Derive from the `tag` class in the Verse.org/Simulation/Tags module to create a new gameplay tag. mytag := class(tag){}
Save your Verse file and click Build Verse Scripts in the UEFN toolbar to compile your code so you can use your new gameplay tag.
Gameplay tags are hierarchical labels. These tags can have any number of hierarchical levels, separated by the _
character in the class name.
When the gameplay tag name appears in the editor, the _
characters are converted to ".".
For example, a gameplay tag with three levels would have the class name family_genus_species
and appear in the editor as "family.genus.species", with "family" being the broadest identifier in the hierarchy, and "species" being the most specific.
Note that the existence of "family.genus.species" does not implicitly mean that "family.genus" and "family" gameplay tags also exist. You must create these gameplay tags in Verse with the class names family
and family_genus
to create the hierarchical levels.
Assigning a Gameplay Tag
Follow these steps to assign a gameplay tag. This example uses a device, but the steps are the same for other actors.
In UEFN in the Outliner, select the device that you want to tag to open its Details panel. In this example, the device is a Button device.
In the Details panel, click Add New Component and choose Verse Tag Markup from the dropdown.
Select the VerseTagMarkup component to view its settings in the Details panel.
Under Gameplay Tags, edit the Tags property and add your gameplay tag. In this example, mytag is added to the device.
You can add multiple tags to the same actor, so each actor can belong to multiple groups at the same time. When you have an actor with multiple tags, you’ll be able to find the actor by any tag it has.
For example, an actor with the tags mytag1 and mytag2 will be found when calling either GetCreativeObjectsWithTag(mytag1{})
or GetCreativeObjectsWithTag(mytag2{})
.
Finding Actors with a Gameplay Tag
Once you have actors with gameplay tags assigned, you can find them by gameplay tag during a game using the Verse function GetCreativeObjectsWithTag()
. In the following example, calling GetCreativeObjectsWithTag(mytag{})
results in TaggedDevices
containing all the actors that have mytag assigned to them:
TaggedActors := GetCreativeObjectsWithTag(mytag{})
The GetCreativeObjectsWithTag()
function call returns an array of all objects that implement creative_object_interface
. For example, if you assigned mytag to both a Button device and a Customizable Light device in the level, then this function call would return both devices.
You can convert the result of GetCreativeObjectsWithTag()
to one of its implementing classes (called type casting) using the syntax NewObjectReference := object_type_to_cast_to[ObjectReference]
, where object_type_to_cast_to
is the object type you want. For example, if you want to turn a Customizable Light device off or on, you must convert the result to customizable_light_device
before calling the function TurnOff()
or TurnOn()
.
Type casting is a failable expression because the type conversion will fail if the device can't be converted to that type, such as if it's a different type of device. For example, you can't convert a Button device to a customizable_light_device
class, because a Button device and a Customizable Light device are not the same type of device.
With for
expressions, you can use failable expressions as a filter and create new variables to use in the for
code block. For example, you can add the type conversion of customizable_light_device
to the iteration expression in for
. Since the device will be converted to customizable_light_device
, you'll be able to use the functions specific to that class, such as TurnOff()
to turn the light off.
TaggedActors := GetCreativeObjectsWithTag(mytag{})
for (TaggedActor : TaggedActors, LightDevice := customizable_light_device[TaggedActor]):
LightDevice.TurnOff()
The following example shows how to conditionally check the type of the actor and call different functions based on the type. The example checks if the tagged actor is a Customizable Light device that can call TurnOff()
to turn the light off, or if the actor is a Barrier device that can call Disable()
to turn it off.
TaggedActors := GetCreativeObjectsWithTag(mytag{})
for (TaggedActor : TaggedActors):
if (LightDevice := customizable_light_device[TaggedActor]):
# If the tagged actor is a Customizable Light device, turn it off
LightDevice.TurnOff()
else if (BarrierDevice := barrier_device[TaggedActor]):
# If the tagged actor is a Barrier device, turn it off
BarrierDevice.Disable()
When calling GetCreativeObjectsWithTag()
, the resulting list isn't ordered by any method you can know or affect ahead of time. In cases where you add or remove actors between calls to GetCreativeObjectsWithTag()
using the same tag, the resulting list might be in a different order for each call result.
If your game needs to handle actors in a specific order, then you should use an editable array instead of gameplay tags, since the result for GetCreativeObjectsWithTag()
is an unordered list of actors.
Finding Position By Type with Gameplay Tags
Here is an example of how to filter the actors returned from GetCreativeObjectsWithTag()
by type and print their position.
# find all actors with the all_tag
AllCreativeObjects : []creative_object_interface := GetCreativeObjectsWithTag(all_tag{})
# Print the position of all creative_prop actors with the all_tag
for (Prop : AllCreativeObjects):
if (Prop := creative_prop[Prop]):
Print("Prop found with all_tag at position: {Prop.GetTransform().Translation}")
# Print the position of all device actors with the all_tag
for (Device:AllCreativeObjects):
Exploring Tutorials That Use Gameplay Tags
The following tutorials show how to use Gameplay Tags in a game.
Tagged Lights Puzzle
Create a puzzle where the player has to find the right combination of lights on and off to spawn an item, using a device created with Verse.