"""Run inside Unreal (Python console / Execute Python Script). Imports the tree (FBX) and rock (OBJ) meshes from DemoAssets as StaticMesh assets, so generate_procedural_terrain.py has something to scatter. """ import os, unreal DEMO_ROOT = r"C:\Users\koleg\Documents\Unreal Projects\ExampleProject\DemoAssets" DEST_ROOT = "/Game/ImportedAssets" # folder under DEMO_ROOT -> (destination subfolder, file extension) SOURCES = { "trees": ("Trees", ".fbx"), "rocks": ("Rocks", ".obj"), } asset_tools = unreal.AssetToolsHelpers.get_asset_tools() def import_task(filename, name, dest_path, options=None): task = unreal.AssetImportTask() task.filename = filename task.destination_path = dest_path task.destination_name = name task.automated = True task.save = True task.replace_existing = True if options: task.options = options asset_tools.import_asset_tasks([task]) return unreal.load_asset(f"{dest_path}/{name}") def import_static_mesh(filename, name, dest_path): ext = os.path.splitext(filename)[1].lower() options = None if ext == ".fbx": options = unreal.FbxImportUI() options.mesh_type_to_import = unreal.FBXImportType.FBXIT_STATIC_MESH options.import_mesh = True options.import_as_skeletal = False options.import_materials = True options.import_textures = True options.static_mesh_import_data.combine_meshes = True # OBJ has no import-options struct exposed to Python; Interchange picks sane defaults. return import_task(filename, name, dest_path, options) imported = [] for src_folder, (dest_subfolder, ext) in SOURCES.items(): src_dir = os.path.join(DEMO_ROOT, src_folder) if not os.path.isdir(src_dir): continue dest_path = f"{DEST_ROOT}/{dest_subfolder}" for f in sorted(os.listdir(src_dir)): stem, file_ext = os.path.splitext(f) if file_ext.lower() != ext: continue name = f"SM_{stem}" mesh = import_static_mesh(os.path.join(src_dir, f), name, dest_path) imported.append(f"{dest_path}/{name}") print(f"Imported {len(imported)} static mesh(es):") for path in imported: print(f" {path}")