from unreal import EditorAssetLibrary, MaterialInstanceConstant # consolidate together Material Instances assets having the same name # WARNING: will erase consolidated assets # retrieves all assets from the directory and its sub directories all_asset_names = EditorAssetLibrary.list_assets("/Game/Test/", True, False) # loads all assets of the MaterialInstanceConstant class material_assets = [] for asset_name in all_asset_names: loaded_asset = EditorAssetLibrary.load_asset(asset_name) if loaded_asset.__class__ == MaterialInstanceConstant: material_assets.append(loaded_asset) # regroup assets having identical names asset_consolidation = {} for i in range(0, len(material_assets)): name = material_assets[i].get_name() if not name in asset_consolidation: asset_consolidation[name] = [] asset_consolidation[name].append(i) # consolidate references of identical assets for asset_name, assets_ids in asset_consolidation.items(): if len(assets_ids) < 2: continue EditorAssetLibrary.consolidate_assets( material_assets[assets_ids[0]], [material_assets[i] for i in assets_ids[1:]])
def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) # Perform extraction self.log.info("Performing extraction..") # Check if the loaded level is the same of the instance current_level = ell.get_editor_world().get_path_name() assert current_level == instance.data.get("level"), \ "Wrong level loaded" json_data = [] for member in instance[:]: actor = ell.get_actor_reference(member) mesh = None # Check type the type of mesh if actor.get_class().get_name() == 'SkeletalMeshActor': mesh = actor.skeletal_mesh_component.skeletal_mesh elif actor.get_class().get_name() == 'StaticMeshActor': mesh = actor.static_mesh_component.static_mesh if mesh: # Search the reference to the Asset Container for the object path = unreal.Paths.get_path(mesh.get_path_name()) filter = unreal.ARFilter( class_names=["AssetContainer"], package_paths=[path]) ar = unreal.AssetRegistryHelpers.get_asset_registry() try: asset_container = ar.get_assets(filter)[0].get_asset() except IndexError: self.log.error("AssetContainer not found.") return parent = eal.get_metadata_tag(asset_container, "parent") family = eal.get_metadata_tag(asset_container, "family") self.log.info("Parent: {}".format(parent)) blend = io.find_one( { "type": "representation", "parent": io.ObjectId(parent), "name": "blend" }, projection={"_id": True}) blend_id = blend["_id"] json_element = {} json_element["reference"] = str(blend_id) json_element["family"] = family json_element["instance_name"] = actor.get_name() json_element["asset_name"] = mesh.get_name() import_data = mesh.get_editor_property("asset_import_data") json_element["file_path"] = import_data.get_first_filename() transform = actor.get_actor_transform() json_element["transform"] = { "translation": { "x": transform.translation.x, "y": transform.translation.y, "z": transform.translation.z }, "rotation": { "x": math.radians(transform.rotation.euler().x), "y": math.radians(transform.rotation.euler().y), "z": math.radians(transform.rotation.euler().z), }, "scale": { "x": transform.scale3d.x, "y": transform.scale3d.y, "z": transform.scale3d.z } } json_data.append(json_element) json_filename = "{}.json".format(instance.name) json_path = os.path.join(stagingdir, json_filename) with open(json_path, "w+") as file: json.dump(json_data, fp=file, indent=2) if "representations" not in instance.data: instance.data["representations"] = [] json_representation = { 'name': 'json', 'ext': 'json', 'files': json_filename, "stagingDir": stagingdir, } instance.data["representations"].append(json_representation)
FBXNormalGenerationMethod, MaterialSearchLocation) # Fix Python PATH Script Issue #9 filename = inspect.getframeinfo(inspect.currentframe()).filename currentPath = os.path.dirname(os.path.abspath(filename)) jsonSetting = open( os.path.normpath( os.path.join(currentPath, "..", "Data", "unrealenginesetting.json")), "r").read() jsonSetting = json.loads(jsonSetting) targetFolder = "/" + os.path.join( "Game", "Blender", jsonSetting["subfolder"]).replace(os.sep, "/") if EditorAssetLibrary.does_directory_exist(directory_path=targetFolder): EditorAssetLibrary.make_directory(directory_path=targetFolder) for file in jsonSetting["files"]: sourceFile = os.path.join(jsonSetting["folder"], file["name"] + ".fbx").replace(os.sep, "/") if os.path.exists(sourceFile): importOptions = FbxImportUI() importOptions.set_editor_property("import_mesh", True) importOptions.set_editor_property("import_as_skeletal", False) importOptions.set_editor_property('import_animations', False) importOptions.static_mesh_import_data.set_editor_property( "auto_generate_collision", (jsonSetting["auto_generate_collision"],
proxy_option.mesh_proxy_settings.allow_distance_field = False proxy_option.mesh_proxy_settings.allow_vertex_colors = False proxy_option.mesh_proxy_settings.calculate_correct_lod_model = False proxy_option.mesh_proxy_settings.compute_light_map_resolution = False proxy_option.mesh_proxy_settings.create_collision = False proxy_option.mesh_proxy_settings.generate_lightmap_u_vs = False proxy_option.mesh_proxy_settings.hard_angle_threshold = 89 # increased normal texture size to capture more details proxy_option.mesh_proxy_settings.material_settings.texture_size = (2048, 2048) proxy_option.mesh_proxy_settings.max_ray_cast_dist = 10.0 proxy_option.mesh_proxy_settings.merge_distance = 1.0 proxy_option.mesh_proxy_settings.override_transfer_distance = True proxy_option.mesh_proxy_settings.override_voxel_size = True proxy_option.mesh_proxy_settings.recalculate_normals = False proxy_option.mesh_proxy_settings.reuse_mesh_lightmap_u_vs = False # affects decimation quality proxy_option.mesh_proxy_settings.screen_size = 800 proxy_option.mesh_proxy_settings.use_hard_angle_threshold = True proxy_option.mesh_proxy_settings.voxel_size = 0.5 # create proxy and retrieve spawned actor proxy_actor = EditorLevelLibrary.create_proxy_mesh_actor(actors_to_merge, proxy_option) proxy_mesh = proxy_actor.static_mesh_component.static_mesh EditorLevelLibrary.destroy_actor(proxy_actor) slow_task.enter_progress_frame(1) for actor in level_actors: EditorLevelLibrary.destroy_actor(actor) EditorStaticMeshLibrary.set_lod_from_static_mesh(merged_mesh, 1, proxy_mesh, 0, True) EditorAssetLibrary.delete_loaded_asset(proxy_mesh)