Variant Manager の設定をスクリプティングする

エディタのスクリプティング機能を使用して、Variant Manager をすべてのシーン バリアントに設定します。

Choose your operating system:

Windows

macOS

Linux

「Variant Manager の概要」 をすでにお読みになった方は、Variant Manager には、一連のバリアントに関する情報と、それに含まれるバリアントへのランタイムのアクセス、さらにバリアントの動的な切り替え (有効化) に使用可能なブループリント API が備わっていることをご存知でしょう。また、Variant Manager では、エディタ内で実行するスクリプトのみで使用可能な別の API も公開しています。このエディタのみの API を使用して新しい Level Variant Sets アセットおよびアクタを作成し、プログラム的にシーン バリアントに設定することができます。

これは、別のアプリケーションで作成したバリアントまたは設定を反映させるために、Unreal Engine プロジェクト内でシーン バリアントを自動的に設定する必要がある場合に特に便利です。これらのシーン バリアントに関連するデータを Unreal Editor スクリプティング システムで読み取り可能な形式にエクスポートできる場合は、このページで説明する手法を使って Unreal Engine で同じシーンを設定できるはずです。こうすることで、Variant Manager の画面で同じバリアントを手作業で再ビルドする時間と労力を節約することができます。また、これはエラーが発生しにくく、繰り返しやすい方法です。

ブループリントまたは Python のいずれかを使用して、Variant Manager の設定をスクリプト処理することができます。

実装方法を選んでください。

Blueprints

Python

シーン バリアントの設定に最も重要なノードは [Blueprint] パレットの Variant Manager カテゴリにあります。このカテゴリのノードによって、新しい Level Variant Sets アセットを作成してバリアント セットとバリアントをアセットに追加し、アクタをバリアントにバインドして、これらのアクタのプロパティ値をキャプチャすることができます。

現時点では、 「バリアントのアクティベーション時に関数を呼び出す」 で説明されているように、エディタ スクリプティング API を使用して、 Function Caller をアクタにバインドするよう設定することはできません。スクリプティング API を使用して可能なのは、バインドされたアクタのプロパティ値のキャプチャと設定のみです。

以下は、最も頻繁に使うノードのいくつかを説明しています。

Create Level Variant Sets Asset

コンテンツ ブラウザで、名前とパスを指定して新しい空の Level Variant Sets /Game/

Add Variant Set

Add Variant Set

指定したバリアント セットを Level Variant Sets アセットに追加します。これは、Variant Manager の画面で [+ Variant Set (バリアント セットを追加)] ボタンをクリックするのと同等の処理です。ゼロから新しいVariant Set を作成する方法は以下のヒントを参照してください。

Add Actor Binding

Add Actor Binding

指定したアクタを指定したバリアントに追加します。これは、アクタを [World Outliner (アウトライナ)] からドラッグして Variant Manager 画面のバリアントにドロップする操作と同等の処理です。

Get Capturable Properties

Get Capturable Properties

特定のアクタに対して Variant Manager で制御可能なすべてのプロパティの名前を返します。 Capture Property ノード の呼び出し時には、これらの値のいずれも使用することができます。

Capture Property

Capture Property

特定のバリアントでアクタに対して指定したプロパティの値を保存します。

Add Variant

Add Variant

指定したバリアントを特定のバリアント セットの子として追加します。

Level Variant Sets Asset に追加する新しい Variant Set を作成する必要がある場合、または Variant Set に追加する新しい Variant を作成する必要がある場合、 Construct Object from Class ノードを使用することができます。最初の入力に、 VariantSet クラスまたは Variant クラスを指定します (作成対象に合わせて)。2 つめの Outer 入力には常に設定している Level Variant Sets Asset を使用します。最後に出力値を Add ノードに渡します。たとえば、このスニペットでは新しい Variant Set が作成され、それが Asset に追加されて、新しい Variant が作成されて、それが新しい Variant Set に追加されます。

ブループリントの例

以下のエディタ ユーティリティ ウィジェットのグラフでは、 Variant Manager がプログラム的にどうのように設定されているのかを示しています。まず、作業するための新しい Actor ブループリントを作成します。次に新しい Level Variant Sets Asset を作成し、新しい Variant Set を使ってそれを設定します。最後に、2 つの Variant をその Variant Set に追加します。1 てゃアクタが視覚化され、もう 1 つはアクタが非表示となります。

この例を実行すると、レベルの元のポイントにキューブが作成されています。また、Variant を切り替えることでそのキューブの表示/非表示を可能にする新しい Level Variant Sets Asset ができています。

シーン バリアントの設定に最も重要なクラスは unreal.VariantManagerLibrary です。このクラスによって、新しい Level Variant Sets アセットを作成してバリアント セットとバリアントをアセットに追加し、アクタをバリアントにバインドして、これらのアクタのプロパティ値をキャプチャすることができます。

現時点では、 「バリアントのアクティベーション時に関数を呼び出す」 で説明されているように、エディタ スクリプティング API を使用して、 Function Caller をアクタにバインドするよう設定することはできません。スクリプティング API を使用して可能なのは、バインドされたアクタのプロパティ値のキャプチャと設定のみです。

以下の表には、頻繁に使用する関数が示されています。これらの関数の詳細と、 VariantManagerLibrary によって提供される他の関数については、 「Python API リファレンス」 を参照してください。

unreal.VariantManagerLibrary.create_level_variant_sets_asset(asset_name, asset_path)
コンテンツ ブラウザで、名前とパスを指定して新しい空の Level Variant Sets アセットを作成します。

unreal.VariantManagerLibrary.add_variant_set(level_variant_sets, variant_set)
指定したバリアント セットを Level Variant Sets アセットに追加します。 これは、Variant Manager の画面で [+ Variant Set (バリアント セットを追加)] ボタンをクリックするのと同等の処理です。

unreal.VariantManagerLibrary.add_actor_binding(variant, actor)
指定したアクタを指定したバリアントに追加します。これは、アクタを [World Outliner (アウトライナ)] からドラッグして Variant Manager 画面のバリアントにドロップする操作と同等の処理です。

unreal.VariantManagerLibrary.get_capturable_properties(actor_or_class)
特定のアクタに対して Variant Manager で制御可能なすべてのプロパティの名前を返します。 capture_property() の呼び出し時には、これらの値のいずれも使用することができます。

unreal.VariantManagerLibrary.capture_property(variant, actor, property_path)
特定のバリアントでアクタに対して指定したプロパティの値を保存します。

unreal.VariantManagerLibrary.add_variant(variant_set, variant)
指定したバリアントを特定のバリアント セットの子として追加します。

Python の例

次の例では、まったく新しい状態の Level Variant Sets アセットを設定する方法を示しています。

最初にキューブと球体で構成されたシーンを設定し、次にこれらのアクタの位置と可視性を変更するよう Variant Manager を設定します。

import math
import unreal

# スクリプトのこのセクションでは、10 個の親アクタを含む基本的なオープニング シーンを設定します。
# それぞれの親アクタのシーン階層には、キューブと球体の 2 つの子アクタが含まれています。
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)

その結果、それぞれ 2 つのバリアントのあるバリアント セットが 2 つできます。

  • 1 つめのバリアント セットは、直線または円の中にアクタを入れるために、3D 空間の中でアクタの位置を切り替えます。

  • 1 つめのバリアント セットは、キューブ メッシュと球体メッシュの間でアクタを入れ替えます。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
閉じる