diff --git a/Content/Python/auto_import_pipeline.py b/Content/Python/auto_import_pipeline.py index 370466d..f922f10 100644 --- a/Content/Python/auto_import_pipeline.py +++ b/Content/Python/auto_import_pipeline.py @@ -6,9 +6,9 @@ dialog, and wires the textures into a Material Instance per mesh. """ import os, unreal -SRC_DIR = r"C:\Users\koleg\Documents\Unreal Projects\ExampleProject\DemoAssets\RobotPolice" -DEST_PATH = "/Game/ImportedAssets" -MASTER_MATERIAL = f"{DEST_PATH}/M_Master" +DEMO_ROOT = r"C:\Users\koleg\Documents\Unreal Projects\ExampleProject\DemoAssets" +DEST_ROOT = "/Game/ImportedAssets" +MASTER_MATERIAL = f"{DEST_ROOT}/M_Master" # suffix -> (texture parameter name, material property, sampled channel) PARAMS = { @@ -27,19 +27,19 @@ def get_or_create_master_material(): if unreal.EditorAssetLibrary.does_asset_exist(MASTER_MATERIAL): return unreal.EditorAssetLibrary.load_asset(MASTER_MATERIAL) - material = asset_tools.create_asset("M_Master", DEST_PATH, unreal.Material, unreal.MaterialFactoryNew()) + material = asset_tools.create_asset("M_Master", DEST_ROOT, unreal.Material, unreal.MaterialFactoryNew()) for i, (suffix, (param, prop, channel)) in enumerate(PARAMS.items()): - tex = mel.new_material_expression(material, unreal.MaterialExpressionTextureSampleParameter2D, -400, i * 200) + tex = mel.create_material_expression(material, unreal.MaterialExpressionTextureSampleParameter2D, -400, i * 200) tex.set_editor_property("parameter_name", param) mel.connect_material_property(tex, channel, prop) mel.recompile_material(material) return material -def import_task(filename, name, options=None): +def import_task(filename, name, dest_path, options=None): task = unreal.AssetImportTask() task.filename = filename - task.destination_path = DEST_PATH + task.destination_path = dest_path task.destination_name = name task.automated = True task.save = True @@ -47,10 +47,10 @@ def import_task(filename, name, options=None): if options: task.options = options asset_tools.import_asset_tasks([task]) - return unreal.load_asset(f"{DEST_PATH}/{name}") + return unreal.load_asset(f"{dest_path}/{name}") -def import_fbx(filename, name): +def import_fbx(filename, name, dest_path): options = unreal.FbxImportUI() options.mesh_type_to_import = unreal.FBXImportType.FBXIT_SKELETAL_MESH options.import_mesh = True @@ -59,39 +59,56 @@ def import_fbx(filename, name): options.create_physics_asset = False options.import_materials = False options.import_textures = False - return import_task(filename, name, options) + return import_task(filename, name, dest_path, options) + + +def assign_material(skeletal_mesh, material): + slots = skeletal_mesh.get_editor_property("materials") + for slot in slots: + slot.set_editor_property("material_interface", material) + skeletal_mesh.set_editor_property("materials", slots) + unreal.EditorAssetLibrary.save_asset(skeletal_mesh.get_path_name()) master = get_or_create_master_material() -# group source files by base name: {"RobotPolice": {"fbx": "...", "_BC": "...", ...}} -groups = {} -for f in os.listdir(SRC_DIR): - stem, ext = os.path.splitext(f) - if ext.lower() == ".fbx": - groups.setdefault(stem, {})["fbx"] = f +asset_count = 0 +for asset_folder in os.listdir(DEMO_ROOT): + src_dir = os.path.join(DEMO_ROOT, asset_folder) + if not os.path.isdir(src_dir): continue - for suffix in PARAMS: - if stem.endswith(suffix): - groups.setdefault(stem[: -len(suffix)], {})[suffix] = f - break + dest_path = f"{DEST_ROOT}/{asset_folder}" -for base_name, files in groups.items(): - if "fbx" not in files: - continue - - import_fbx(os.path.join(SRC_DIR, files["fbx"]), base_name) - - mi = asset_tools.create_asset(f"MI_{base_name}", DEST_PATH, unreal.MaterialInstanceConstant, - unreal.MaterialInstanceConstantFactoryNew()) - mel.set_material_instance_parent(mi, master) - - for suffix, (param, _, _) in PARAMS.items(): - if suffix not in files: + # group source files by base name: {"RobotPolice": {"fbx": "...", "_BC": "...", ...}} + groups = {} + for f in os.listdir(src_dir): + stem, ext = os.path.splitext(f) + if ext.lower() == ".fbx": + groups.setdefault(stem, {})["fbx"] = f continue - texture = import_task(os.path.join(SRC_DIR, files[suffix]), f"T_{base_name}{suffix}") - mel.set_material_instance_texture_parameter_value(mi, param, texture) + for suffix in PARAMS: + if stem.endswith(suffix): + groups.setdefault(stem[: -len(suffix)], {})[suffix] = f + break - unreal.EditorAssetLibrary.save_asset(mi.get_path_name()) + for base_name, files in groups.items(): + if "fbx" not in files: + continue -print(f"Imported {len(groups)} asset(s) into {DEST_PATH}") + mesh = import_fbx(os.path.join(src_dir, files["fbx"]), base_name, dest_path) + + mi = asset_tools.create_asset(f"MI_{base_name}", dest_path, unreal.MaterialInstanceConstant, + unreal.MaterialInstanceConstantFactoryNew()) + mel.set_material_instance_parent(mi, master) + + for suffix, (param, _, _) in PARAMS.items(): + if suffix not in files: + continue + texture = import_task(os.path.join(src_dir, files[suffix]), f"T_{base_name}{suffix}", dest_path) + mel.set_material_instance_texture_parameter_value(mi, param, texture) + + unreal.EditorAssetLibrary.save_asset(mi.get_path_name()) + assign_material(mesh, mi) + asset_count += 1 + +print(f"Imported {asset_count} asset(s) into {DEST_ROOT}") diff --git a/DemoAssets/spiderman/spiderman.fbx b/DemoAssets/spiderman/spiderman.fbx new file mode 100644 index 0000000..6ad92cf Binary files /dev/null and b/DemoAssets/spiderman/spiderman.fbx differ diff --git a/DemoAssets/spiderman/spiderman_BC.jpeg b/DemoAssets/spiderman/spiderman_BC.jpeg new file mode 100644 index 0000000..618ab7c Binary files /dev/null and b/DemoAssets/spiderman/spiderman_BC.jpeg differ