Scripting the Variant Manager Setup

Use Editor Scripting to set up the Variant Manager with all your scene variants.

Windows
MacOS
Linux
On this page

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.

unreal.VariantManagerLibrary.create_level_variant_sets_asset(asset_name, asset_path)
Creates a new, empty Level Variant Sets Asset in the Content Browser, with the specified name and path.

unreal.VariantManagerLibrary.add_variant_set(level_variant_sets, variant_set)
Adds the specified Variant Set to the Level Variant Sets Asset. This is the equivalent to clicking the + Variant Set button in the Variant Manager UI.

unreal.VariantManagerLibrary.add_actor_binding(variant, actor)
Adds the specified Actor to the specified Variant. This is the equivalent of dragging the Actor from the World Outliner and dropping it on to the Variant in the Variant Manager UI.

unreal.VariantManagerLibrary.get_capturable_properties(actor_or_class)
Returns the names of all the properties that the Variant Manager can control for the specified Actor. You can use any of these values when you call capture_property().

unreal.VariantManagerLibrary.capture_property(variant, actor, property_path)
Saves the value of the property you specify for an Actor in the specified Variant.

unreal.VariantManagerLibrary.add_variant(variant_set, variant)
Adds the specified Variant as a child of the specified Variant Set.

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.

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback