Choose your operating system:
Windows
macOS
Linux
If you've read through the Variant Manager Overview , you've seen that the Variant Manager offers a Blueprint API that you can use at runtime to access information about the variant sets and variants that it contains, and to switch variants on dynamically. However, the Variant Manager also exposes a separate API that is only available to scripts that run in the Editor. You can use this Editor-only API to create new Level Variant Sets Assets and Actors, and to set them up with your scene variants programmatically.
This may be particularly useful if you need to set up scene variants in your Unreal Engine Project automatically to reflect variants or settings that you've already authored in another application. If you can export the data about those scene variants into a format that the Unreal Editor scripting systems can read, you may be able to use the methods described on this page to set up the same scene variants in Unreal Engine. This saves you the time and effort of rebuilding the same variants by hand in the Variant Manager UI. It may also be less error-prone, and more repeatable.
Variant Manager scripting is currently only available in Python.
Python
The most important class involved in setting up your scene variants is
unreal.VariantManagerLibrary
. This class lets you create new
Level Variant Sets
Assets, add Variant Sets and Variants to that Asset, bind Actors to Variants, and capture property values for those Actors.
You can't currently use the Editor scripting API to set up a bound Actor with a Function Caller as described in Calling Functions on Variant Activation . You can only use the scripting API to capture and set property values on bound Actors.
The following table describes the functions you'll use most often. For details on these and other functions offered by the
VariantManagerLibrary
, see the
Python API Reference
.
|
|
|
|
|
|
Example
The following example shows how to set up a new Level Variant Sets Asset from scratch.
It first sets up a scene consisting of cubes and spheres, then sets up the Variant Manager to change the positions and visibility of those Actors.
import math
import unreal
# This section of the script sets up a basic starting scene that contains 10 parent Actors.
# Each parent Actor has two child Actors in the scene hierarchy: a sphere and a cube.
sphere_mesh = unreal.EditorAssetLibrary.load_asset('/Engine/BasicShapes/Sphere')
cube_mesh = unreal.EditorAssetLibrary.load_asset('/Engine/BasicShapes/Cube')
parent_actors = []
sphere_actors = []
cube_actors = []
for i in range(0,10):
parent_actor = unreal.EditorLevelLibrary.spawn_actor_from_class(unreal.StaticMeshActor, unreal.Vector(0, 0, 0), unreal.Rotator(0, 0, 0))
parent_actor.root_component.set_editor_property("mobility", unreal.ComponentMobility.MOVABLE)
parent_actor.set_actor_label("actor_" + str(i).zfill(3))
sphere_actor = unreal.EditorLevelLibrary.spawn_actor_from_class(unreal.StaticMeshActor, unreal.Vector(0, 0, 0), unreal.Rotator(0, 0, 0))
sphere_actor.static_mesh_component.set_static_mesh(sphere_mesh)
sphere_actor.root_component.set_editor_property("mobility", unreal.ComponentMobility.MOVABLE)
sphere_actor.attach_to_actor(parent_actor, unreal.Name(), unreal.AttachmentRule.KEEP_WORLD, unreal.AttachmentRule.KEEP_WORLD, unreal.AttachmentRule.KEEP_WORLD, False)
sphere_actor.set_actor_label("sphere_" + str(i).zfill(3))
cube_actor = unreal.EditorLevelLibrary.spawn_actor_from_class(unreal.StaticMeshActor, unreal.Vector(0, 0, 0), unreal.Rotator(0, 0, 0))
cube_actor.static_mesh_component.set_static_mesh(cube_mesh)
cube_actor.root_component.set_editor_property("mobility", unreal.ComponentMobility.MOVABLE)
cube_actor.attach_to_component(parent_actor.root_component, unreal.Name(), unreal.AttachmentRule.KEEP_WORLD, unreal.AttachmentRule.KEEP_WORLD, unreal.AttachmentRule.KEEP_WORLD, False)
cube_actor.set_actor_label("cube_" + str(i).zfill(3))
parent_actors.append(parent_actor)
sphere_actors.append(sphere_actor)
cube_actors.append(cube_actor)
# Create a Level Variant Set Asset with the specified name and path in the Content Browser.
# The path should always begin with /Game/.
lvs = unreal.VariantManagerLibrary.create_level_variant_sets_asset('ProceduralVariants', '/Game')
# Create a new Variant Set to manage position variants.
position_variant_set = unreal.VariantSet()
position_variant_set.set_display_text('Position')
# Add the empty Variant Set to the Level Variant Sets Asset.
unreal.VariantManagerLibrary.add_variant_set(lvs, position_variant_set)
# This section sets up a new Variant that will position the parent Actors in a line.
# First, create the Variant.
position_variant_0 = unreal.Variant()
position_variant_0.set_display_text('Line')
# For each parent Actor...
for i, actor in enumerate(parent_actors):
# Position the Actor in line along the X axis.
actor.set_actor_location_and_rotation(unreal.Vector(i*200, 0, 0), unreal.Rotator(0, 0, 0), False, True)
# Bind the Actor to the Variant.
unreal.VariantManagerLibrary.add_actor_binding(position_variant_0, actor)
# Capture the relative location and rotation properties of the Actor's Static Mesh Component, and store their current values.
unreal.VariantManagerLibrary.capture_property(position_variant_0, actor, 'Static Mesh Component / Relative Location')
unreal.VariantManagerLibrary.capture_property(position_variant_0, actor, 'Static Mesh Component / Relative Rotation')
# Now that the Variant is set up, add it to the Variant Set.
unreal.VariantManagerLibrary.add_variant(position_variant_set, position_variant_0)
# This section follows the same process to set up a second Variant,
# but this time it positions the parent Actors in a circle rather than a line.
position_variant_1 = unreal.Variant()
position_variant_1.set_display_text('Circle')
for i, actor in enumerate(parent_actors):
actor.set_actor_location_and_rotation(unreal.Vector(1000*math.cos(i*360.0/(len(parent_actors)-1)), 1000*math.sin(i*360.0/(len(parent_actors)-1)), 0), unreal.Rotator(0, 0, 0), False, True)
unreal.VariantManagerLibrary.add_actor_binding(position_variant_1, actor)
unreal.VariantManagerLibrary.capture_property(position_variant_1, actor, 'Static Mesh Component / Relative Location')
unreal.VariantManagerLibrary.capture_property(position_variant_1, actor, 'Static Mesh Component / Relative Rotation')
unreal.VariantManagerLibrary.add_variant(position_variant_set, position_variant_1)
# Create a new Variant Set to manage showing and hiding Actors with different shapes.
shape_variant_set = unreal.VariantSet()
shape_variant_set.set_display_text('Shape')
unreal.VariantManagerLibrary.add_variant_set(lvs, shape_variant_set)
# Create two Variants: one that shows the spheres and hides the cubes, and the other
# that shows the cubes and hides the spheres.
shape_variant_0 = unreal.Variant()
shape_variant_0.set_display_text('Sphere')
shape_variant_1 = unreal.Variant()
shape_variant_1.set_display_text('Cube')
# Bind each sphere Actor to the two Variants, and capture the Visible property of its Static Mesh Component.
for i, actor in enumerate(sphere_actors):
actor.root_component.set_visibility(True)
unreal.VariantManagerLibrary.add_actor_binding(shape_variant_0, actor)
unreal.VariantManagerLibrary.capture_property(shape_variant_0, actor, 'Static Mesh Component / Visible')
actor.root_component.set_visibility(False)
unreal.VariantManagerLibrary.add_actor_binding(shape_variant_1, actor)
unreal.VariantManagerLibrary.capture_property(shape_variant_1, actor, 'Static Mesh Component / Visible')
# Bind each sphere Actor to the two Variants, and capture the Visible property of its Static Mesh Component,
# but save the opposite visibility values from the sphere Actors above.
for i, actor in enumerate(cube_actors):
actor.root_component.set_visibility(False)
unreal.VariantManagerLibrary.add_actor_binding(shape_variant_0, actor)
unreal.VariantManagerLibrary.capture_property(shape_variant_0, actor, 'Static Mesh Component / Visible')
actor.root_component.set_visibility(True)
unreal.VariantManagerLibrary.add_actor_binding(shape_variant_1, actor)
unreal.VariantManagerLibrary.capture_property(shape_variant_1, actor, 'Static Mesh Component / Visible')
# Finally, add the two Variants to the Variant Set.
unreal.VariantManagerLibrary.add_variant(shape_variant_set, shape_variant_0)
unreal.VariantManagerLibrary.add_variant(shape_variant_set, shape_variant_1)
# Add the Level Variants Sets Asset to the current Level, so that you can use it from Blueprints at runtime.
lvs_actor = unreal.VariantManagerLibrary.create_level_variant_sets_actor(lvs)
The result is as follows: two Variant Sets, each with two Variants.
-
The first Variant Set switches the positions of the Actors in 3D space to arrange them into a straight line or a circle.
-
The second Variant Set swaps the Actors between a cube mesh and a spherical mesh.