Choose your operating system:
Windows
macOS
Linux
对 变量管理器概述 完成学习后,应知道变体管理器提供蓝图API,可在运行时用于访问其所含变体集和变体的相关信息,并可动态切换变体。变体管理器同时还公开单独的API,仅对编辑器中运行的脚本可用。可使用此纯编辑器API新建关卡变体集资产和Actor,并使用场景变体进行编程设置。
需在虚幻引擎项目中自动设置场景变体,以反映已在其他应用程序中创建的变体或设置时,此方法十分有用。若可将此类场景变体的数据导出为虚幻编辑器脚本系统可读取的格式,则可使用本页所述方式在虚幻引擎中设置相同场景变体。利用此法无需在变体管理器UI中手动重新编译相同变体。同时其不易出错,且可重复性更高。
你可以使用蓝图或Python来为变体管理器编写设置脚本。
选择实现方法:
Blueprints
Python
设置场景变体所涉及的最重要的节点位于蓝图控制板的 变量管理器(Variant Manager) 类别下。此类别中的节点可用于新建 关卡变体集(Level Variant Sets) 资产,向该资产添加变体集和变体,将Actor绑定至变体,以及采集此类Actor的属性值。
目前,您无法使用编辑器脚本API为绑定Actor设置 变体激活时调用函数 中所述的 函数调用方(Function Caller) 。仅可使用脚本API采集和设置绑定Actor上的属性值。
下表介绍了您可能最常用的部分节点:
|
创建关卡变体集资产(Create Level Variant Sets Asset) |
在内容浏览器中使用指定名称和路径新建空白
关卡变体集(Level Variant Sets)
|
|
添加变体集(Add Variant Set) |
将指定变体集添加到关卡变体集资产。这相当于单击变体管理器UI中的 +变体集(+ Variant Set) 按钮。请参见下列提示,以了解从头开始新建变体集的说明。 |
|
添加Actor绑定(Add Actor Binding) |
将指定Actor添加到指定变体。这相当于将Actor从 世界大纲视图(World Outliner) 拖放到变体管理器UI中的变体上。 |
|
获取可采集的属性(Get Capturable Properties) |
返回变体管理器可为指定Actor控制的所有属性的名称。调用 采集属性(Capture Property) 节点时可使用任意此类值。 |
|
采集属性(Capture Property) |
保存您为指定变体中的Actor而指定的属性值。 |
|
添加变体(Add Variant) |
将指定变体添加为指定变体集的子级。 |
如果您需要新建变体集以添加到关卡变体集资产,或需要新建变体以添加到变体集,则可使用 从类构造对象(Construct Object from Class) 节点。在第一个输入中,指定 变体集(VariantSet) 或 变体(Variant) 类,具体取决于需创建的类。在第二个 外部(Outer) 输入中,始终使用正在设置的关卡变体集资产。最后,将输出值传递给 添加(Add) 节点。例如,此片段会新建变体集并将其添加到资产,然后新建变体并将其添加到新建变体集:
点击查看大图。
蓝图示例
下图来自编辑器工具控件,显示了如何通过编程设置变体管理器。首先,创建要使用的新Actor。然后,新建关卡变体集资产并使用新的变体集对其进行设置。最后,向此变体集添加两个变体:一个为Actor在其中处于可见状态的变体,另一个为Actor在其中处于隐藏状态的变体。
点击查看大图。
运行此示例后,您将看到关卡起始点处新建了立方体。您还将拥有新的关卡变体集资产,它们使您能够通过切换变体来显示和隐藏此立方体。
设置场景变体涉及最重要的类为
unreal.VariantManagerLibrary
。利用此类可新建
关卡变体集
资产,向该资产添加变体集和变体,将Actor绑定至变体,以及捕捉此类Actor的属性值。
目前不可使用编辑器脚本API设置拥有 函数调用器 的绑定Actor, 变体激活时调用函数 中对此调用器进行了描述。仅可使用脚本API捕捉和设置绑定Actor上的属性值。
下表对最常用函数进行说明。欲了解
VariantManagerLibrary
提供的此类函数的详情,参阅
Python API说明
。
|
|
|
|
|
|
Python示例
下例显示了从头设置新 关卡变体集 资产的方法。
首先设置由立方体和球体组成的场景,然后设置变体管理器以修改此类Actor的位置和可视性。
import math
import unreal
# 此段脚本将设置包含10个父Actor的基本起始场景。
# 各父Actor在场景层级中拥有两个子Actor:一个球体和一个立方体。
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)
# 在内容浏览器中创建使用指定命名和路径的关卡变体集资产。
# 此路径固定以 /Game/ 开头。
lvs = unreal.VariantManagerLibrary.create_level_variant_sets_asset('ProceduralVariants', '/Game')
# 新建变体集以管理位置变体。
position_variant_set = unreal.VariantSet()
position_variant_set.set_display_text('Position')
# 向关卡变体集资产添加空白变体集。
unreal.VariantManagerLibrary.add_variant_set(lvs, position_variant_set)
# 此段将设置新变体,将父Actor排成一行。
# 首先创建变体。
position_variant_0 = unreal.Variant()
position_variant_0.set_display_text('Line')
# 对于各父Actor...
for i, actor in enumerate(parent_actors):
# 沿X轴将Actor排成一行。
actor.set_actor_location_and_rotation(unreal.Vector(i*200, 0, 0), unreal.Rotator(0, 0, 0), False, True)
# 将Actor绑定到变体。
unreal.VariantManagerLibrary.add_actor_binding(position_variant_0, actor)
# 捕捉Actor的静态网格体组件相对位置和旋转属性,并存储其当前值。
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')
# 设置变体后将其添加到变体集。
unreal.VariantManagerLibrary.add_variant(position_variant_set, position_variant_0)
# 此段将以同样流程设置第二个变体。
# 但其会将父Actor围成一圈,而非排成一行。
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)
# 新建变体集,以管理显示和隐藏不同形状的Actor。
shape_variant_set = unreal.VariantSet()
shape_variant_set.set_display_text('Shape')
unreal.VariantManagerLibrary.add_variant_set(lvs, shape_variant_set)
# 创建两个变体,一个显示球体和隐藏立方体,另一个
# 显示立方体并隐藏球体。
shape_variant_0 = unreal.Variant()
shape_variant_0.set_display_text('Sphere')
shape_variant_1 = unreal.Variant()
shape_variant_1.set_display_text('Cube')
# 将各球体Actor绑定至这两个变体,捕捉其静态网格体组件的可视属性。
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')
# 将各球体Actor绑定至这两个变体,捕捉其静态网格体组件的可视属性,
# 但保存与上述球体Actor相反的可视性值。
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')
# 最后,向变体集添加这两个变体。
unreal.VariantManagerLibrary.add_variant(shape_variant_set, shape_variant_0)
unreal.VariantManagerLibrary.add_variant(shape_variant_set, shape_variant_1)
# 向当前关卡添加关卡变体集资产,以便运行时在蓝图中进行使用。
lvs_actor = unreal.VariantManagerLibrary.create_level_variant_sets_actor(lvs)
结果如下:两个变体集,均含两个变体。
-
第一个变体集切换Actor在3D空间中的位置,将其排成直线或圆圈。
-
第二个变体集在立方体网格体与球体网格体之间切换Actor。