I’d like to create an Actor and add a static mesh component to it by Python with Unreal Editor 5.0.3. I refer to this artical [Using Python to Create Unreal Engine Objects | unrealcode.net](https://Using Python to Create Unreal Engine Objects) and my code as below:
import unreal
from typing import Tuple
def create_base_blueprint(package_path: str, asset_name: str) -> unreal.Blueprint:
factory = unreal.BlueprintFactory()
# this works, the saved blueprint is derived from Actor
factory.set_editor_property(name='parent_class', value=unreal.Actor)
# make the blueprint
asset_tools: unreal.AssetTools = unreal.AssetToolsHelpers.get_asset_tools()
asset: object = asset_tools.create_asset(
asset_name=asset_name,
package_path=package_path,
asset_class=None,
factory=factory
)
if not isinstance(asset, unreal.Blueprint):
raise Exception('Failed to create blueprint asset')
blueprint: unreal.Blueprint = asset # noqa
return blueprint
def load_static_mesh(path: str) -> unreal.StaticMesh:
eal = unreal.EditorAssetLibrary
asset: object = eal.load_asset(path)
if not isinstance(asset, unreal.StaticMesh):
raise Exception("Failed to load StaticMesh from {path}")
return asset
def spawn_blueprint_actor(package_path: str, asset_name: str) -> unreal.Actor:
# spawn actor on map
eal = unreal.EditorAssetLibrary
ell = unreal.EditorLevelLibrary
blueprint_class = eal.load_blueprint_class(asset_path=package_path + "/" + asset_name)
assert isinstance(blueprint_class, unreal.BlueprintGeneratedClass)
location = unreal.Vector(0, 0, 0)
rotation = (location - location).rotator()
actor: unreal.Actor = ell.spawn_actor_from_class(actor_class=blueprint_class, location=location, rotation=rotation)
return actor
def add_subobject(subsystem: unreal.SubobjectDataSubsystem,
blueprint: unreal.Blueprint,
new_class,
name: str) -> Tuple[unreal.SubobjectDataHandle, unreal.Object]:
root_data_handle: unreal.SubobjectDataHandle = \
subsystem.k2_gather_subobject_data_for_blueprint(context=blueprint)[0]
sub_handle, fail_reason = subsystem.add_new_subobject(
params=unreal.AddNewSubobjectParams(
parent_handle=root_data_handle,
new_class=new_class,
blueprint_context=blueprint))
if not fail_reason.is_empty():
raise Exception("ERROR from sub_object_subsystem.add_new_subobject: {fail_reason}")
subsystem.rename_subobject(handle=sub_handle, new_name=unreal.Text(name))
# subsystem.attach_subobject(owner_handle=root_data_handle, child_to_add_handle=sub_handle)
BFL = unreal.SubobjectDataBlueprintFunctionLibrary
obj: unreal.Object = BFL.get_object(BFL.get_data(sub_handle))
return sub_handle, obj
with unreal.ScopedEditorTransaction('create_launch_pad_in_python') as trans:
# 2 Construct Launchpad
# 2.1 Create Blueprint
package_path = '/Game/Blueprints'
asset_name = "LaunchPad_Blueprint"
blueprint = create_base_blueprint(package_path=package_path, asset_name=asset_name)
# 2.2 Add cube component
so_subsystem = unreal.get_engine_subsystem(unreal.SubobjectDataSubsystem)
sub_handle, cube_component = add_subobject(
subsystem=so_subsystem,
blueprint=blueprint,
new_class=unreal.StaticMeshComponent,
name='Cube'
)
assert isinstance(cube_component, unreal.StaticMeshComponent)
unreal.log('new_sub_object:{}'.format(cube_component))
cube_mesh: unreal.StaticMesh = load_static_mesh(path='/Engine/BasicShapes/Cube')
cube_component.set_static_mesh(new_mesh=cube_mesh)
# 2.3 Create LaunchPad Actor
launch_pad_actor = spawn_blueprint_actor(package_path, asset_name)
launch_pad_actor.set_actor_label('LaunchPad', True)
The result is this piece of Python script doesn’t work in Unreal Edtor 5.0.3. Static Mesh Component can not be added to Actor, and BFL.get_object(BFL.get_data(sub_handle)) return None. But this piece of Python script can work in Unreal Editor 5.1.0. What should I do to make the script work in Unreal Edtor 5.0.3 ?