Hi @BadookaSlam I thought I did above. This is what I use daily. I’ll give you exactly what I use that also exports out fbx(s) as well from linked sequences automatically and removes the annoying game folder in the directory as well. Notice that it requires another module reference to do it properly and I called it “path_config”
import unreal
import importlib
import os
import shutil
ll = unreal.LevelSequenceEditorBlueprintLibrary
ues = unreal.EditorLevelLibrary()
level_editor_subsystem = unreal.get_editor_subsystem(unreal.LevelEditorSubsystem)
world = level_editor_subsystem.get_current_level()
world = ues.get_editor_world()
eas = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
msbp = unreal.MovieSceneBindingProxy
mst = unreal.MovieSceneTrack
s = unreal.SequencerTools
from unreal import LevelEditorSubsystem
task = unreal.AssetExportTask()
task.automated = 1
task.prompt = 0
task.write_empty_files = 1
task.use_file_archive = 0
task.replace_identical = 1
ait = unreal.AssetImportTask()
ait.automated = 1
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
binding = ll.get_selected_bindings()[0]
eul = unreal.EditorUtilityLibrary()
d = eul.get_selected_asset_data()
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
import path_config as pc
importlib.reload(pc)
main_path = pc.main_path + '/animations'
level_sequence = ll.get_focused_level_sequence()
bindings = ll.get_selected_bindings()
ase = unreal.AnimSequenceExporterFBX()
"""
SceneComponent
asset_user_data
get_child_component
get_children_components
unreal.SkeletalMesh.skeleton
"""
les = unreal.get_editor_subsystem(LevelEditorSubsystem)
def print_names(object):
for i in object: print(i.get_display_name())
def export_anim(path="/Game/"):
path = path.replace("/All/", "/")
#s.export_anim_sequence()
anim_factory = unreal.AnimSequenceFactory()
level_sequence = ll.get_focused_level_sequence()
bindings = ll.get_selected_bindings()
exported_assets = []
anim_seqs = []
cur_assets = asset_registry.get_assets_by_path(path)
for binding in bindings:
parent = binding.get_parent()
parent_name = parent.get_name().replace("(", "_").replace(")", "_")
object_binding_id = level_sequence.get_binding_id(binding) #finally got the binding id
skmc = ll.get_bound_objects(object_binding_id)[0]
skm = skmc.skeletal_mesh
name = skm.get_name()
# name = '_'.join(name.split("_")[0:2])
name = parent_name + "_" + name
name = name.replace(" ", "_")
count = 0
for asset in cur_assets:
if(name in str(asset.asset_name)):
count += 1
if(count > 0):
name += "_{0}".format(count)
sk = skm.skeleton
anim_factory.preview_skeletal_mesh = skm
anim_factory.target_skeleton = sk
anim_factory.set_editor_property("asset_import_task", ait)
anim_factory.set_editor_property("edit_after_new", False)
anim_seq_class = unreal.AnimSequence
anim_sequence = asset_tools.create_asset(name, path, anim_seq_class, anim_factory)
asset = asset_registry.get_asset_by_object_path(anim_sequence.get_path_name())
# Anim Sequence Object.. asset? idk
# anim_sequence = unreal.load_asset("/Game/Anim_test", anim_seq_class)
export_option = unreal.AnimSeqExportOption()
export_option.export_transforms = True
export_option.export_morph_targets = True
export_option.export_attribute_curves = True
export_option.export_material_curves = True
export_option.record_in_world_space = True
export_option.evaluate_all_skeletal_mesh_components = True
export_option.transact_recording = True
s.export_anim_sequence(world, level_sequence, anim_sequence, export_option, binding, create_link=1)
# link = s.link_anim_sequence(level_sequence, anim_sequence, export_option, binding)
exported_assets.append(asset)
anim_seqs.append(anim_sequence)
export_fbxs(exported_assets=exported_assets, anim_seqs=anim_seqs)
# export fbx for all exported_assets
return
def export_fbxs(exported_assets, anim_seqs):
fe = unreal.FbxExportOption()
bt = unreal.MovieSceneBakeType.BAKE_TRANSFORMS
bn = unreal.MovieSceneBakeType.NONE
fe.ascii = 0
fe.bake_actor_animation = bn
fe.bake_camera_and_light_animation = bt
fe.collision = 0
fe.export_local_time = 1
fe.export_morph_targets = 0
fe.export_preview_mesh = 1
fe.export_source_mesh = 0
fe.force_front_x_axis = 0
fe.level_of_detail = 0
fe.map_skeletal_motion_to_root = 0
fe.vertex_color = 0
asset_tools.export_assets([x.package_name for x in exported_assets], main_path) # Works but makes stupid path, trying to avoid
move_game_files(main_path)
def move_game_files(path):
base_dir = path
game_folder = os.path.join(base_dir, "Game")
# Recursively find all .fbx files in the Game folder
for root, dirs, files in os.walk(game_folder):
for filename in files:
if filename.lower().endswith(".fbx"):
# Construct full source and destination paths
source_path = os.path.join(root, filename)
dest_path = os.path.join(base_dir, filename)
# Move the file
shutil.move(source_path, dest_path)
print(f"Moved: {filename} from {root} to {base_dir}")
print("All .fbx files have been moved to the animations folder.")
shutil.rmtree(game_folder)
print(f"Removed the folder: {game_folder}")
My path config module called path_config.py
import unreal
import os
ll = unreal.LevelSequenceEditorBlueprintLibrary
def change_shot_name(shot):
if("pal" in shot.lower()):
return shot.replace("Pal", "shot")
elif("dock" in shot.lower()):
return shot.replace("Dock_sh", "SQ")
else:
return shot
def get_output_dir(shot_name):
path = main_path
if(os.path.exists(path)==False):
os.makedirs(path)
versions = os.listdir(path)
if(len(versions)==0):
os.makedirs(os.path.join(path, "v0001"))
path = os.path.join(path, "v0001")
return path
else:
sorted_versions = [int(v.replace("v", "")) for v in versions]
latest_version = max(sorted_versions)
latest_version += 1
path = os.path.join(path, "v{:04d}".format(latest_version))
return path
main_path = "L:/ALL HOUDINI FILES/ASC_INSPIRATION/{main_project}/{project}/{shot}/"
lev = ll.get_focused_level_sequence()
shot = lev.get_name()
# shot = '_'.join(shot.split("_")[0:2])
shot = change_shot_name(shot)
main_project, project = unreal.Paths.get_project_file_path().split("/")[-2].split("_") #FinalBattle2
if(main_project.lower() == "exo"): main_project = "Exodus"
main_path = main_path.format(main_project=main_project, project=project, shot=shot)