I’m trying to make a python script to attach Static Mesh Components to a Skeletal Mesh Component inside a Blueprint Class.
This is what I want:
With this code I can create the same structure:
#---create_bluprint_actor---#
factory = unreal.BlueprintFactory()
factory.set_editor_property("ParentClass", unreal.Actor)
# make the blueprint
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
bp_actor = asset_tools.create_asset(blueprint_name, asset_path, None, factory)
unreal.EditorAssetLibrary.save_loaded_asset( bp_actor )
# get the root data handle
subsystem = unreal.get_engine_subsystem(unreal.SubobjectDataSubsystem)
root_data_handle = subsystem.k2_gather_subobject_data_for_blueprint(bp_actor)[0]
skeletalmesh = unreal.SkeletalMeshComponent
#add new component
sub_handle, fail_reson = subsystem.add_new_subobject(
params=unreal.AddNewSubobjectParams(
parent_handle=root_data_handle,
new_class=skeletalmesh,
blueprint_context=bp_actor))
#rename
subsystem.rename_subobject(handle=sub_handle, new_name=unreal.Text("skeleton"))
root_data_handle = subsystem.k2_gather_subobject_data_for_blueprint(bp_actor)[2]
for x in range(1,7,1):
staticmesh = unreal.StaticMeshComponent
#add new component
sub_handle, fail_reson = subsystem.add_new_subobject(
params=unreal.AddNewSubobjectParams(
parent_handle=root_data_handle,
new_class=staticmesh,
blueprint_context=bp_actor))
#rename
subsystem.rename_subobject(handle=sub_handle, new_name=unreal.Text( "piece" + str(x) ))
But how do I change the properties of each Component?
For the skeleton I need to set the Skeletal Mesh Asset to a custom skeletal mesh in the content browser, and for the pieces I need to set the Static Mesh slot to a unreal.load_asset( “mypiece” ) and set the Parent Socket to the bone I want to parent it to.
Hey Havard,
Nice work on script.
I have some idea of doing a similar thing in unreal 4.27.
I am wanting to have a python script that basically going over a list of blueprint assets in content browser and with each blueprint I want check whether if the static mesh component is has a mesh or not.
Any help would be much appreciated!
It’s a bit out of topic to this tread but I can try to help, dont know if this works in unreal 4.27, tested it in 5.1. This loops trough all the components inside a blueprint and checks if it has a “static_mesh” assigned.
import unreal
bp_asset = unreal.load_asset( '/Game/BP_myblueprint' )
subsystem: unreal.SubobjectDataSubsystem = unreal.get_engine_subsystem(unreal.SubobjectDataSubsystem)
root_data_handle: unreal.SubobjectDataHandle = subsystem.k2_gather_subobject_data_for_blueprint(context=bp_asset)
objects = []
#get components in blueprint
for handle in root_data_handle:
subobject = subsystem.k2_find_subobject_data_from_handle( handle )
objects.append( unreal.SubobjectDataBlueprintFunctionLibrary.get_object( subobject ) )
#remove duplicates
objects = list(dict.fromkeys(objects))
#check if StaticMeshComponent and check the static_mesh parameter
for object in objects:
if "StaticMeshComponent" in str(object):
static_mesh = object.get_editor_property("static_mesh")
if str(static_mesh) == "None":
print( "StaticMeshComponent: " + str(object) + " has no static_mesh" )
Thanks Havard! That’s awesome and I have tested in Unreal 5 and it works perfectly. But not so much in 4.27. Will keep looking for other method of doing it!
Hey Havard,
I’m trying to do the same thing, I have created a new blueprint and a new component, then how do I change the properties of each Component? Have you solved this problem?
Any help would be highly appreciated!
import unreal
def set_static_mesh_for_blueprint(bp, mesh):
bp_asset = unreal.load_asset(bp.package_name)
mesh_asset = unreal.load_asset(mesh.package_name)
subsystem: unreal.SubobjectDataSubsystem = unreal.get_engine_subsystem(unreal.SubobjectDataSubsystem)
root_data_handle: unreal.SubobjectDataHandle = subsystem.k2_gather_subobject_data_for_blueprint(context=bp_asset)
objects = []
#get components in blueprint
for handle in root_data_handle:
subobject = subsystem.k2_find_subobject_data_from_handle( handle )
objects.append( unreal.SubobjectDataBlueprintFunctionLibrary.get_object( subobject ) )
#check if StaticMeshComponent and check the static_mesh parameter
for object in objects:
if "StaticMeshComponent" in str(object):
static_mesh = object.get_editor_property("static_mesh")
#print(static_mesh)
if str(static_mesh) == "None":
print( "StaticMeshComponent: " + str(object) + " has no static_mesh" )
break
object.set_editor_property("static_mesh", mesh_asset)
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
prefabs = asset_registry.get_assets_by_path("/Game/Blueprints/Actors")
meshes = asset_registry.get_assets_by_path("/Game/Meshes/StaticMeshes")
i = 0
for prefab in prefabs:
set_static_mesh_for_blueprint(prefab, meshes[i])
i = i + 1
Here’s how I did it.
In my example I made a mass static mesh change script that for each actor it gets the corresponding static mesh from another folder
In particular the line “object.set_editor_property(“static_mesh”, mesh_asset)” is what makes the change