def print_static_switch_params(asset_path): # asset_registry = unreal.AssetRegistryHelpers.get_asset_registry() # all_assets = asset_registry.get_assets_by_path(asset_path, recursive=True) material = unreal.EditorAssetLibrary.load_asset(asset_path) color = unreal.LinearColor(r=0.0, g=0.0, b=0.0, a=0.0) unreal.MaterialEditingLibrary.set_material_instance_vector_parameter_value( material, "BoxMax", color)
def setDirectoryColor_EXAMPLE(): base_path = '/Game/PythonGenerated/' path = base_path + 'BasicLinearColor' color = unreal.LinearColor(0, 1, 1, 1) AssetFunctions.setDirectoryColor(path, color) AssetFunctions.createDirectory( path) # Note: Only call this line if the folder is not already created
def set_parameter(material_instance, parameter_name, parameter_value): """Set a parameter value on a material instance from a Python type :param <MaterialInstance:material_instance> Material instance to set on :param <str:parameter_name> Name of the parameter to set :param <value:parameter_value> Value to set - the correct type will calculated by the function """ if (isinstance(parameter_value, float) or isinstance(parameter_value, int)): unreal.MaterialEditingLibrary.set_material_instance_scalar_parameter_value( material_instance, parameter_name, float(parameter_value)) elif (isinstance(parameter_value, list) or isinstance(parameter_value, tuple)): value = unreal.LinearColor(r=parameter_value[0], g=parameter_value[1], b=parameter_value[2], a=parameter_value[3]) unreal.MaterialEditingLibrary.set_material_instance_vector_parameter_value( material_instance, parameter_name, value) elif (isinstance(parameter_value, bool)): tools_library.log.error( "Material instance bool parameter setting not implemented")
def setDirectoryColorGradient_EXAMPLE(): base_path = '/Game/PythonGenerated/' for x in range(100, 400): # Get Gradient Color z = x - 100 if z < 100: r = 1.0 - z / 100.0 g = 0.0 + z / 100.0 b = 0.0 elif z < 200: r = 0.0 g = 1.0 - (z - 100) / 100.0 b = 0.0 + (z - 100) / 100.0 else: r = 0.0 + (z - 200) / 100.0 g = 0.0 b = 1.0 - (z - 200) / 100.0 color = unreal.LinearColor(r, g, b, 1) # Set Directory Color path = base_path + str(x) AssetFunctions.setDirectoryColor(path, color) AssetFunctions.createDirectory( path ) # Note: Only call this line if the folder is not already created
def ImportTask(): # New import task # Property if asset_data["type"] == "Animation": find_asset = unreal.find_asset( asset_data["animation_skeleton_path"]) if isinstance(find_asset, unreal.Skeleton): OriginSkeleton = find_asset elif isinstance(find_asset, unreal.SkeletalMesh): OriginSkeleton = find_asset.skeleton else: OriginSkeleton = None task = unreal.AssetImportTask() if asset_data["type"] == "Alembic": task.filename = asset_data["abc_path"] else: task.filename = asset_data["fbx_path"] task.destination_path = os.path.normpath( asset_data["full_import_path"]).replace('\\', '/') task.automated = True task.save = True task.replace_existing = True if asset_data["type"] == "Alembic": task.set_editor_property('options', unreal.AbcImportSettings()) else: task.set_editor_property('options', unreal.FbxImportUI()) # #################################[Change] # unreal.FbxImportUI # https://docs.unrealengine.com/en-US/PythonAPI/class/FbxImportUI.html?highlight=fbximportui#unreal.FbxImportUI if asset_data["type"] == "Alembic": task.get_editor_property('options').set_editor_property( 'import_type', unreal.AlembicImportType.SKELETAL) else: if asset_data["type"] == "Animation": if OriginSkeleton: task.get_editor_property( 'options').set_editor_property( 'Skeleton', OriginSkeleton) else: ImportFailList.append( 'Skeleton ' + asset_data["animation_skeleton_path"] + ' Not found for ' + asset_data["name"] + ' asset.') return if asset_data["type"] == "StaticMesh": task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_STATIC_MESH) elif asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_ANIMATION) else: task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_SKELETAL_MESH) if asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'import_materials', False) else: task.get_editor_property('options').set_editor_property( 'import_materials', True) task.get_editor_property('options').set_editor_property( 'import_textures', False) if asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'import_animations', True) task.get_editor_property('options').set_editor_property( 'import_mesh', False) task.get_editor_property('options').set_editor_property( 'create_physics_asset', False) else: task.get_editor_property('options').set_editor_property( 'import_animations', False) task.get_editor_property('options').set_editor_property( 'import_mesh', True) if "create_physics_asset" in asset_data: task.get_editor_property( 'options').set_editor_property( 'create_physics_asset', asset_data["create_physics_asset"]) # unreal.FbxMeshImportData if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": if "material_search_location" in asset_data: # unreal.FbxTextureImportData if asset_data["material_search_location"] == "Local": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.LOCAL) if asset_data[ "material_search_location"] == "UnderParent": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.UNDER_PARENT) if asset_data[ "material_search_location"] == "UnderRoot": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.UNDER_ROOT) if asset_data[ "material_search_location"] == "AllAssets": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.ALL_ASSETS) if asset_data["type"] == "StaticMesh": # unreal.FbxStaticMeshImportData task.get_editor_property( 'options').static_mesh_import_data.set_editor_property( 'combine_meshes', True) if "auto_generate_collision" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'auto_generate_collision', asset_data["auto_generate_collision"]) if "static_mesh_lod_group" in asset_data: if asset_data["static_mesh_lod_group"]: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'static_mesh_lod_group', asset_data["static_mesh_lod_group"]) if "generate_lightmap_u_vs" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'generate_lightmap_u_vs', asset_data["generate_lightmap_u_vs"]) if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": vertex_color_import_option = unreal.VertexColorImportOption.REPLACE # Default if "vertex_override_color" in asset_data: vertex_override_color = unreal.LinearColor( asset_data["vertex_override_color"][0], asset_data["vertex_override_color"][1], asset_data["vertex_override_color"][2]) if "vertex_color_import_option" in asset_data: if asset_data[ "vertex_color_import_option"] == "IGNORE": vertex_color_import_option = unreal.VertexColorImportOption.IGNORE elif asset_data[ "vertex_color_import_option"] == "OVERRIDE": vertex_color_import_option = unreal.VertexColorImportOption.OVERRIDE elif asset_data[ "vertex_color_import_option"] == "REPLACE": vertex_color_import_option = unreal.VertexColorImportOption.REPLACE if asset_data["type"] == "StaticMesh": # unreal.FbxSkeletalMeshImportData if "vertex_color_import_option" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'vertex_color_import_option', vertex_color_import_option) if "vertex_override_color" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) if asset_data["type"] == "SkeletalMesh": # unreal.FbxSkeletalMeshImportData if "vertex_color_import_option" in asset_data: task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'vertex_color_import_option', vertex_color_import_option) if "vertex_override_color" in asset_data: task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) if asset_data["type"] == "SkeletalMesh" or asset_data[ "type"] == "Animation": # unreal.FbxSkeletalMeshImportData task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'import_morph_targets', True) task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'convert_scene', True) task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'normal_import_method', unreal.FBXNormalImportMethod. FBXNIM_IMPORT_NORMALS_AND_TANGENTS) # ###############[ import asset ]################ print("Import task") if asset_data["type"] == "Animation": ''' For animation the script will import a skeletal mesh and remove after. If the skeletal mesh alredy exist try to remove. ''' # task.destination_name = "TempAnimationImportName" # unreal.EditorAssetLibrary.delete_asset("SkeletalMesh'"+asset_data["full_import_path"]+"/TempAnimationImportName.TempAnimationImportName'") unreal.EditorAssetLibrary.delete_asset( "SkeletalMesh'" + asset_data["full_import_path"] + "/" + asset_data["name"] + "." + asset_data["name"] + "'") print( unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks( [task])) if len(task.imported_object_paths) > 0: asset = unreal.find_asset(task.imported_object_paths[0]) else: asset = None if asset is None: ImportFailList.append('Error zero imported object for: ' + asset_data["name"]) return if asset_data["type"] == "Animation": # For animation remove the extra mesh p = task.imported_object_paths[0] if type(unreal.find_asset(p)) is not unreal.AnimSequence: animAssetName = p.split('.')[0] + '_anim.' + p.split( '.')[1] + '_anim' animAssetNameDesiredPath = p.split('.')[0] + '.' + p.split( '.')[1] animAsset = unreal.find_asset(animAssetName) if animAsset is not None: unreal.EditorAssetLibrary.delete_asset(p) unreal.EditorAssetLibrary.rename_asset( animAssetName, animAssetNameDesiredPath) asset = animAsset else: ImportFailList.append('animAsset ' + asset_data["name"] + ' not found for after inport: ' + animAssetName) return # ###############[ Post treatment ]################ if asset_data["type"] == "StaticMesh": if "static_mesh_lod_group" in asset_data: if asset_data["static_mesh_lod_group"]: asset.set_editor_property( 'lod_group', asset_data["static_mesh_lod_group"]) if "light_map_resolution" in asset_data: asset.set_editor_property( 'light_map_resolution', asset_data["light_map_resolution"]) if "collision_trace_flag" in asset_data: if asset_data["collision_trace_flag"] == "CTF_UseDefault": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal.CollisionTraceFlag.CTF_USE_DEFAULT) elif asset_data[ "collision_trace_flag"] == "CTF_UseSimpleAndComplex": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_SIMPLE_AND_COMPLEX) elif asset_data[ "collision_trace_flag"] == "CTF_UseSimpleAsComplex": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_SIMPLE_AS_COMPLEX) elif asset_data[ "collision_trace_flag"] == "CTF_UseComplexAsSimple": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_COMPLEX_AS_SIMPLE) if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": vertex_color_import_option = unreal.VertexColorImportOption.REPLACE # Default if "vertex_override_color" in asset_data: vertex_override_color = unreal.LinearColor( asset_data["vertex_override_color"][0], asset_data["vertex_override_color"][1], asset_data["vertex_override_color"][2]) if "vertex_color_import_option" in asset_data: if asset_data["vertex_color_import_option"] == "IGNORE": vertex_color_import_option = unreal.VertexColorImportOption.IGNORE elif asset_data[ "vertex_color_import_option"] == "OVERRIDE": vertex_color_import_option = unreal.VertexColorImportOption.OVERRIDE elif asset_data["vertex_color_import_option"] == "REPLACE": vertex_color_import_option = unreal.VertexColorImportOption.REPLACE if "vertex_color_import_option" in asset_data: asset.get_editor_property( 'asset_import_data').set_editor_property( 'vertex_color_import_option', vertex_color_import_option) if "vertex_override_color" in asset_data: asset.get_editor_property( 'asset_import_data').set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) if asset_data["type"] == "StaticMesh": if "generate_lightmap_u_vs" in asset_data: asset.get_editor_property( 'asset_import_data').set_editor_property( 'generate_lightmap_u_vs', asset_data["generate_lightmap_u_vs"] ) # Import data unreal.EditorStaticMeshLibrary.set_generate_lightmap_uv( asset, asset_data["generate_lightmap_u_vs"] ) # Build settings at lod if asset_data["type"] == "SkeletalMesh": asset.get_editor_property( 'asset_import_data').set_editor_property( 'normal_import_method', unreal.FBXNormalImportMethod. FBXNIM_IMPORT_NORMALS_AND_TANGENTS) # with open(asset_data["additional_tracks_path"], "r") as json_file: # asset_tracks = json.load(json_file) # Socket if asset_data["type"] == "SkeletalMesh": # Import the SkeletalMesh socket(s) sockets_to_add = GetOptionByIniFile( asset_data["additional_tracks_path"], 'Sockets', True) skeleton = asset.get_editor_property('skeleton') for socket in sockets_to_add: pass # Create socket # new_socket = unreal.SkeletalMeshSocket('', skeleton) # new_socket.SocketName = socket[0] # Lod if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": if asset_data["type"] == "StaticMesh": unreal.EditorStaticMeshLibrary.remove_lods( asset) # Import the StaticMesh lod(s) if asset_data["type"] == "SkeletalMesh" or asset_data[ "type"] == "StaticMesh": lods_to_add = GetOptionByIniFile( asset_data["additional_tracks_path"], 'LevelOfDetail') # Import the SkeletalMesh lod(s) for x, lod in enumerate(lods_to_add): if asset_data["type"] == "StaticMesh": lodTask = unreal.AssetImportTask() lodTask.filename = lod lodTask.destination_path = os.path.normpath( asset_data["full_import_path"]).replace( '\\', '/') lodTask.automated = True lodTask.replace_existing = True unreal.AssetToolsHelpers.get_asset_tools( ).import_asset_tasks([lodTask]) lodAsset = unreal.find_asset( lodTask.imported_object_paths[0]) slot_replaced = unreal.EditorStaticMeshLibrary.set_lod_from_static_mesh( asset, x + 1, lodAsset, 0, True) unreal.EditorAssetLibrary.delete_asset( lodTask.imported_object_paths[0]) elif asset_data["type"] == "SkeletalMesh": pass unreal.FbxMeshUtils.ImportSkeletalMeshLOD( asset, lod, x + 1 ) # Vania unreal python dont have unreal.FbxMeshUtils. # #################################[EndChange] if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": unreal.EditorAssetLibrary.save_loaded_asset(asset) ImportedList.append([asset, asset_data["type"]])
colorTexNode, "RGBA", unreal.MaterialProperty.MP_BASE_COLOR) colorTexNode.texture = importedTex if len(mtlData.alphaMap) > 0: ME.connect_material_property( colorTexNode, "A", unreal.MaterialProperty.MP_OPACITY_MASK) matInstance.set_editor_property( 'blend_mode', unreal.BlendMode.BLEND_MASKED) else: colorNode = ME.create_material_expression( matInstance, unreal.MaterialExpressionConstant4Vector, -350, -200) col = unreal.LinearColor() if mtlData.isAccessory: col.set_editor_property( "r", pow(mtlData.diffuse[0] + 0.5 * mtlData.ambient[0], 2.2)) col.set_editor_property( "g", pow(mtlData.diffuse[1] + 0.5 * mtlData.ambient[1], 2.2)) col.set_editor_property( "b", pow(mtlData.diffuse[2] + 0.5 * mtlData.ambient[2], 2.2)) col.set_editor_property("a", mtlData.trans) else:
def ImportTask(): # New import task # Property if asset_data["type"] == "Animation": find_asset = unreal.find_asset( asset_data["animation_skeleton_path"]) if isinstance(find_asset, unreal.Skeleton): OriginSkeleton = find_asset elif isinstance(find_asset, unreal.SkeletalMesh): OriginSkeleton = find_asset.skeleton else: OriginSkeleton = None # docs.unrealengine.com/4.26/en-US/PythonAPI/class/AssetImportTask.html task = unreal.AssetImportTask() def GetStaticMeshImportData(): if asset_data["type"] == "StaticMesh": return task.get_editor_property( 'options').static_mesh_import_data return None def GetSkeletalMeshImportData(): if asset_data["type"] == "SkeletalMesh": return task.get_editor_property( 'options').skeletal_mesh_import_data return None def GetAnimationImportData(): if asset_data["type"] == "Animation": return task.get_editor_property( 'options').anim_sequence_import_data return None def GetAlembicImportData(): if asset_data["type"] == "Alembic": return task.get_editor_property('options') return None def GetMeshImportData(): if asset_data["type"] == "StaticMesh": return GetStaticMeshImportData() if asset_data["type"] == "SkeletalMesh": return GetSkeletalMeshImportData() return None if asset_data["type"] == "Alembic": task.filename = asset_data["abc_path"] else: task.filename = asset_data["fbx_path"] task.destination_path = os.path.normpath( asset_data["full_import_path"]).replace('\\', '/') task.automated = True # task.automated = False #Debug for show dialog task.save = True task.replace_existing = True if asset_data["type"] == "Alembic": task.set_editor_property('options', unreal.AbcImportSettings()) else: task.set_editor_property('options', unreal.FbxImportUI()) # Alembic if GetAlembicImportData(): GetAlembicImportData( ).static_mesh_settings.set_editor_property( "merge_meshes", True) GetAlembicImportData().set_editor_property( "import_type", unreal.AlembicImportType.SKELETAL) GetAlembicImportData().conversion_settings.set_editor_property( "flip_u", False) GetAlembicImportData().conversion_settings.set_editor_property( "flip_v", True) GetAlembicImportData().conversion_settings.set_editor_property( "scale", unreal.Vector(100, -100, 100)) GetAlembicImportData().conversion_settings.set_editor_property( "rotation", unreal.Vector(90, 0, 0)) # Vertex color vertex_override_color = None vertex_color_import_option = None if additional_data: if "vertex_color_import_option" in additional_data: if additional_data[ "vertex_color_import_option"] == "IGNORE": vertex_color_import_option = unreal.VertexColorImportOption.IGNORE elif additional_data[ "vertex_color_import_option"] == "OVERRIDE": vertex_color_import_option = unreal.VertexColorImportOption.OVERRIDE elif additional_data[ "vertex_color_import_option"] == "REPLACE": vertex_color_import_option = unreal.VertexColorImportOption.REPLACE vertex_color_import_option = unreal.VertexColorImportOption.REPLACE # Default if "vertex_override_color" in additional_data: vertex_override_color = unreal.LinearColor( additional_data["vertex_override_color"][0], additional_data["vertex_override_color"][1], additional_data["vertex_override_color"][2]) # #################################[Change] # unreal.FbxImportUI # https://docs.unrealengine.com/4.26/en-US/PythonAPI/class/FbxImportUI.html # Import transform anim_sequence_import_data = GetAnimationImportData() if anim_sequence_import_data: anim_sequence_import_data.import_translation = unreal.Vector( 0, 0, 0) # Vertex color if vertex_color_import_option and GetMeshImportData(): GetMeshImportData().set_editor_property( 'vertex_color_import_option', vertex_color_import_option) if vertex_override_color and GetMeshImportData(): GetMeshImportData().set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) if asset_data["type"] == "Alembic": task.get_editor_property('options').set_editor_property( 'import_type', unreal.AlembicImportType.SKELETAL) else: if asset_data["type"] == "Animation": if OriginSkeleton: task.get_editor_property( 'options').set_editor_property( 'Skeleton', OriginSkeleton) else: ImportFailList.append( 'Skeleton ' + asset_data["animation_skeleton_path"] + ' Not found for ' + asset_data["name"] + ' asset.') return if asset_data["type"] == "StaticMesh": task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_STATIC_MESH) elif asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_ANIMATION) else: task.get_editor_property('options').set_editor_property( 'original_import_type', unreal.FBXImportType.FBXIT_SKELETAL_MESH) if asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'import_materials', False) else: task.get_editor_property('options').set_editor_property( 'import_materials', True) task.get_editor_property('options').set_editor_property( 'import_textures', False) if asset_data["type"] == "Animation": task.get_editor_property('options').set_editor_property( 'import_animations', True) task.get_editor_property('options').set_editor_property( 'import_mesh', False) task.get_editor_property('options').set_editor_property( 'create_physics_asset', False) else: task.get_editor_property('options').set_editor_property( 'import_animations', False) task.get_editor_property('options').set_editor_property( 'import_mesh', True) if "create_physics_asset" in asset_data: task.get_editor_property( 'options').set_editor_property( 'create_physics_asset', asset_data["create_physics_asset"]) # unreal.FbxMeshImportData if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": if "material_search_location" in asset_data: # unreal.FbxTextureImportData if asset_data["material_search_location"] == "Local": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.LOCAL) if asset_data[ "material_search_location"] == "UnderParent": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.UNDER_PARENT) if asset_data[ "material_search_location"] == "UnderRoot": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.UNDER_ROOT) if asset_data[ "material_search_location"] == "AllAssets": task.get_editor_property( 'options' ).texture_import_data.set_editor_property( 'material_search_location', unreal.MaterialSearchLocation.ALL_ASSETS) if asset_data["type"] == "StaticMesh": # unreal.FbxStaticMeshImportData task.get_editor_property( 'options').static_mesh_import_data.set_editor_property( 'combine_meshes', True) if "auto_generate_collision" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'auto_generate_collision', asset_data["auto_generate_collision"]) if "static_mesh_lod_group" in asset_data: if asset_data["static_mesh_lod_group"]: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'static_mesh_lod_group', asset_data["static_mesh_lod_group"]) if "generate_lightmap_u_vs" in asset_data: task.get_editor_property( 'options' ).static_mesh_import_data.set_editor_property( 'generate_lightmap_u_vs', asset_data["generate_lightmap_u_vs"]) if asset_data["type"] == "SkeletalMesh" or asset_data[ "type"] == "Animation": # unreal.FbxSkeletalMeshImportData task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'import_morph_targets', True) task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'convert_scene', True) task.get_editor_property( 'options' ).skeletal_mesh_import_data.set_editor_property( 'normal_import_method', unreal.FBXNormalImportMethod. FBXNIM_IMPORT_NORMALS_AND_TANGENTS) # ###############[ pre import ]################ # Check is the file alredy exit if additional_data: if "preview_import_path" in additional_data: task_asset_full_path = task.destination_path + "/" + additional_data[ "preview_import_path"] + "." + additional_data[ "preview_import_path"] find_asset = unreal.find_asset(task_asset_full_path) if find_asset: # Vertex color asset_import_data = find_asset.get_editor_property( 'asset_import_data') if vertex_color_import_option: asset_import_data.set_editor_property( 'vertex_color_import_option', vertex_color_import_option) if vertex_override_color: asset_import_data.set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) # ###############[ import asset ]################ print("Import task") if asset_data["type"] == "Animation": ''' For animation the script will import a skeletal mesh and remove after. If the skeletal mesh alredy exist try to remove. ''' AssetName = asset_data["name"] AssetName = ValidUnrealAssetsName(AssetName) AssetPath = "SkeletalMesh'" + asset_data[ "full_import_path"] + "/" + AssetName + "." + AssetName + "'" if unreal.EditorAssetLibrary.does_asset_exist(AssetPath): oldAsset = unreal.EditorAssetLibrary.find_asset_data( AssetPath) if oldAsset.asset_class == "SkeletalMesh": unreal.EditorAssetLibrary.delete_asset(AssetPath) unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks( [task]) if len(task.imported_object_paths) > 0: asset = unreal.find_asset(task.imported_object_paths[0]) else: asset = None if asset is None: ImportFailList.append('Error zero imported object for: ' + asset_data["name"]) return if asset_data["type"] == "Animation": # For animation remove the extra mesh p = task.imported_object_paths[0] if type(unreal.find_asset(p)) is not unreal.AnimSequence: animAssetName = p.split('.')[0] + '_anim.' + p.split( '.')[1] + '_anim' animAssetNameDesiredPath = p.split('.')[0] + '.' + p.split( '.')[1] animAsset = unreal.find_asset(animAssetName) if animAsset is not None: unreal.EditorAssetLibrary.delete_asset(p) unreal.EditorAssetLibrary.rename_asset( animAssetName, animAssetNameDesiredPath) asset = animAsset else: ImportFailList.append('animAsset ' + asset_data["name"] + ' not found for after inport: ' + animAssetName) return # ###############[ Post treatment ]################ asset_import_data = asset.get_editor_property('asset_import_data') if asset_data["type"] == "StaticMesh": if "static_mesh_lod_group" in asset_data: if asset_data["static_mesh_lod_group"]: asset.set_editor_property( 'lod_group', asset_data["static_mesh_lod_group"]) if "use_custom_light_map_resolution" in asset_data: if asset_data["use_custom_light_map_resolution"]: if "light_map_resolution" in asset_data: asset.set_editor_property( 'light_map_resolution', asset_data["light_map_resolution"]) if "collision_trace_flag" in asset_data: if asset_data["collision_trace_flag"] == "CTF_UseDefault": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal.CollisionTraceFlag.CTF_USE_DEFAULT) elif asset_data[ "collision_trace_flag"] == "CTF_UseSimpleAndComplex": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_SIMPLE_AND_COMPLEX) elif asset_data[ "collision_trace_flag"] == "CTF_UseSimpleAsComplex": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_SIMPLE_AS_COMPLEX) elif asset_data[ "collision_trace_flag"] == "CTF_UseComplexAsSimple": asset.get_editor_property( 'body_setup').set_editor_property( 'collision_trace_flag', unreal. CollisionTraceFlag.CTF_USE_COMPLEX_AS_SIMPLE) if asset_data["type"] == "StaticMesh": if "generate_lightmap_u_vs" in asset_data: asset_import_data.set_editor_property( 'generate_lightmap_u_vs', asset_data["generate_lightmap_u_vs"]) # Import data unreal.EditorStaticMeshLibrary.set_generate_lightmap_uv( asset, asset_data["generate_lightmap_u_vs"] ) # Build settings at lod if asset_data["type"] == "SkeletalMesh": asset_import_data.set_editor_property( 'normal_import_method', unreal.FBXNormalImportMethod. FBXNIM_IMPORT_NORMALS_AND_TANGENTS) # Socket if asset_data["type"] == "SkeletalMesh": # Import the SkeletalMesh socket(s) sockets_to_add = additional_data["Sockets"] skeleton = asset.get_editor_property('skeleton') for socket in sockets_to_add: old_socket = asset.find_socket(socket["SocketName"]) if old_socket: # Edit socket pass # old_socket.relative_location = socket["Location"] # old_socket.relative_rotation = socket["Rotation"] # old_socket.relative_scale = socket["Scale"] else: # Create socket pass # new_socket = unreal.SkeletalMeshSocket(asset) # new_socket.socket_name = socket["SocketName"] # new_socket.bone_name = socket["BoneName"] # new_socket.relative_location = socket["Location"] # new_socket.relative_rotation = socket["Rotation"] # new_socket.relative_scale = socket["Scale"] # NEED UNREAL ENGINE IMPLEMENTATION IN PYTHON API. # skeleton.add_socket(new_socket) # Lod if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": if asset_data["type"] == "StaticMesh": unreal.EditorStaticMeshLibrary.remove_lods( asset) # Import the StaticMesh lod(s) if asset_data["type"] == "SkeletalMesh" or asset_data[ "type"] == "StaticMesh": def ImportStaticLod(lod_name, lod_number): if "LevelOfDetail" in additional_data: if lod_name in additional_data["LevelOfDetail"]: lodTask = unreal.AssetImportTask() lodTask.filename = additional_data[ "LevelOfDetail"][lod_name] destination_path = os.path.normpath( asset_data["full_import_path"]).replace( '\\', '/') lodTask.destination_path = destination_path lodTask.automated = True lodTask.replace_existing = True print( destination_path, additional_data["LevelOfDetail"][lod_name]) unreal.AssetToolsHelpers.get_asset_tools( ).import_asset_tasks([lodTask]) if len(lodTask.imported_object_paths) > 0: lodAsset = unreal.find_asset( lodTask.imported_object_paths[0]) slot_replaced = unreal.EditorStaticMeshLibrary.set_lod_from_static_mesh( asset, lod_number, lodAsset, 0, True) unreal.EditorAssetLibrary.delete_asset( lodTask.imported_object_paths[0]) def ImportSkeletalLod(lod_name, lod_number): if "LevelOfDetail" in additional_data: if lod_name in additional_data["LevelOfDetail"]: # Unreal python no longer support Skeletal mesh LODS import. pass if asset_data["type"] == "StaticMesh": ImportStaticLod("lod_1", 1) ImportStaticLod("lod_2", 2) ImportStaticLod("lod_3", 3) ImportStaticLod("lod_4", 4) ImportStaticLod("lod_5", 5) elif asset_data["type"] == "SkeletalMesh": ImportSkeletalLod("lod_1", 1) ImportSkeletalLod("lod_2", 2) ImportSkeletalLod("lod_3", 3) ImportSkeletalLod("lod_4", 4) ImportSkeletalLod("lod_5", 5) # Vertex color if vertex_override_color: asset_import_data.set_editor_property( 'vertex_override_color', vertex_override_color.to_rgbe()) if vertex_color_import_option: asset_import_data.set_editor_property( 'vertex_color_import_option', vertex_color_import_option) # #################################[EndChange] if asset_data["type"] == "StaticMesh" or asset_data[ "type"] == "SkeletalMesh": unreal.EditorAssetLibrary.save_loaded_asset(asset) ImportedList.append([asset, asset_data["type"]])
def getGradientColor(x): x = float(x) / 100 return unreal.LinearColor(x, 1 - x, 1 - x, 1)
elif type_str == "int": prop.set_value_int(2) elif type_str == "float": prop.set_value_float(2.0) elif type_str == "object": cube = unreal.EditorAssetLibrary.load_asset( "StaticMesh'/Engine/BasicShapes/Cube.Cube'") prop.set_value_object(cube) elif type_str == "strint": prop.set_value_string("new string") elif type_str == "rotator": prop.set_value_rotator(unreal.Rotator(11, 12, 13)) elif type_str == "color": prop.set_value_color(unreal.Color(21, 22, 23, 24)) elif type_str == "linear_color": prop.set_value_linear_color(unreal.LinearColor(0.31, 0.32, 0.33, 0.34)) elif type_str == "vector": prop.set_value_vector(unreal.Vector(41, 42, 43)) elif type_str == "quat": prop.set_value_quat(unreal.Quat(0.51, 0.52, 0.53, 0.54)) elif type_str == "vector4": prop.set_value_vector4(unreal.Vector4(6.1, 6.2, 6.3, 6.4)) elif type_str == "Vector2D": prop.set_value_vector2d(unreal.Vector2D(7.1, 7.2)) elif type_str == "int_Point": prop.set_value_int_point(unreal.IntPoint(81, 82)) # Easier to print using getattr for prop in captured_props: type_str = prop.get_property_type_string() print(getattr(prop, "get_value_" + type_str)())
def render_sequence_to_movie(sequencer_asset_path): # 1) Create an instance of our UAutomatedLevelSequenceCapture and override all of the settings on it. This class is currently # set as a config class so settings will leak between the Unreal Sequencer Render-to-Movie UI and this object. To work around # this, we set every setting via the script so that no changes the user has made via the UI will affect the script version. # The users UI settings will be reset as an unfortunate side effect of this. capture_settings = unreal.AutomatedLevelSequenceCapture() # Set all POD settings on the UMovieSceneCapture capture_settings.settings.output_directory = unreal.DirectoryPath( "../../../QAGame/Saved/VideoCaptures/") # If you game mode is implemented in Blueprint, load_asset(...) is going to return you the C++ type ('Blueprint') and not what the BP says it inherits from. # Instead, because game_mode_override is a TSubclassOf<AGameModeBase> we can use unreal.load_class to get the UClass which is implicitly convertable. # ie: capture_settings.settings.game_mode_override = unreal.load_class(None, "/Game/AI/TestingSupport/AITestingGameMode.AITestingGameMode_C") capture_settings.settings.game_mode_override = None capture_settings.settings.output_format = "{world}" capture_settings.settings.overwrite_existing = True capture_settings.settings.use_relative_frame_numbers = False capture_settings.settings.handle_frames = 0 capture_settings.settings.zero_pad_frame_numbers = 4 capture_settings.settings.frame_rate = unreal.FrameRate(24, 1) capture_settings.settings.resolution.res_x = 1280 capture_settings.settings.resolution.res_y = 720 capture_settings.settings.enable_texture_streaming = False capture_settings.settings.cinematic_engine_scalability = True capture_settings.settings.cinematic_mode = True capture_settings.settings.allow_movement = False # Requires cinematic_mode = True capture_settings.settings.allow_turning = False # Requires cinematic_mode = True capture_settings.settings.show_player = False # Requires cinematic_mode = True capture_settings.settings.show_hud = False # Requires cinematic_mode = True capture_settings.use_separate_process = False capture_settings.close_editor_when_capture_starts = False # Requires use_separate_process = True capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES" # Requires use_separate_process = True capture_settings.inherited_command_line_arguments = "" # Requires use_separate_process = True # Set all the POD settings on UAutomatedLevelSequenceCapture capture_settings.use_custom_start_frame = False # If False, the system will automatically calculate the start based on sequence content capture_settings.use_custom_end_frame = False # If False, the system will automatically calculate the end based on sequence content capture_settings.custom_start_frame = unreal.FrameNumber( 0) # Requires use_custom_start_frame = True capture_settings.custom_end_frame = unreal.FrameNumber( 0) # Requires use_custom_end_frame = True capture_settings.warm_up_frame_count = 0.0 capture_settings.delay_before_warm_up = 0 # ToDo: Test int -> float capture_settings.delay_before_shot_warm_up = 0.0 capture_settings.write_edit_decision_list = True # Tell the capture settings which level sequence to render with these settings. The asset does not need to be loaded, # as we're only capturing the path to it and when the PIE instance is created it will load the specified asset. # If you only had a reference to the level sequence, you could use "unreal.SoftObjectPath(mysequence.get_path_name())" capture_settings.level_sequence_asset = unreal.SoftObjectPath( sequencer_asset_path) # Now let's work on setting some more complex settings. The image capture is composed of two fields that need to correspond to each other. # The first field is the CaptureType ("Output Format" on the UI). This is how you specify if you want to output custom render passes, a video sequence, etc. # Then, once you decide on a capture type you also need to create an instance of the settings object specific to that capture type and assign it. # In this example, we will be using a Custom Render Passes output as it is the most complicated one to set up. # # The settings classes for each capture protocol can be found in the /Engine/Source/Runtime/MovieSceneCapture/Public/Protocols folder. # The identifier comes from MovieSceneCaptureModule.cpp ("CustomRenderPasses", "Video", "PNG", "JPG", "BMP") capture_settings.capture_type.identifier = "CustomRenderPasses" protocol_settings = unreal.CompositionGraphCaptureSettings() # The passes comes from BufferVisualizationData.cpp protocol_settings.include_render_passes.value.append("BaseColor") protocol_settings.include_render_passes.value.append("SceneDepth") protocol_settings.include_render_passes.value.append("Roughness") protocol_settings.capture_frames_in_hdr = False protocol_settings.hdr_compression_quality = 1 # Requires capture_frames_in_hdr = True, 0 means no compression, 1 means standard. protocol_settings.capture_gamut = unreal.HDRCaptureGamut.HCGM_REC709 # Requires capture_frames_in_hdr = True # protocol_settings.post_processing_material = unreal.SoftObjectPath("/Game/Path/To/Material") protocol_settings.post_processing_material = unreal.SoftObjectPath( "") # Soft Object Paths use an empty string for None. protocol_settings.disable_screen_percentage = True # The other complex settings is the burn-in. Create an instance of the LevelSequenceBurnInOptions which is used to # specify if we should use a burn in, and then which settings. burn_in_options = unreal.LevelSequenceBurnInOptions() burn_in_options.use_burn_in = True # You have to specify a path to a class to use for the burn in (if use_burn_in = True), and this class specifies a UClass to define the # settings object type. We've created a convinence function which takes the class path, loads the class at that path and assigns it to # the Settings object. burn_in_options.set_burn_in( unreal.SoftClassPath( "/Engine/Sequencer/DefaultBurnIn.DefaultBurnIn_C")) # The default burn in is implemented entirely in Blueprint which means that the method we've been using to set properties will not # work for it. The python bindings that turn bSomeVariableName into "some_variable_name" only work for C++ classes with # UPROPERTY(BlueprintReadWrite) marked fields. Python doesn't know about the existence of Blueprint classes and their fields, so we # have to use an alternative method. burn_in_options.settings.set_editor_property( 'TopLeftText', "{FocalLength}mm,{Aperture},{FocusDistance}") burn_in_options.settings.set_editor_property( 'TopCenterText', "{MasterName} - {Date} - {EngineVersion}") burn_in_options.settings.set_editor_property( 'TopRightText', "{TranslationX} {TranslationY} {TranslationZ}, {RotationX} {RotationY} {RotationZ}" ) burn_in_options.settings.set_editor_property('BottomLeftText', "{ShotName}") burn_in_options.settings.set_editor_property( 'BottomCenterText', "{hh}:{mm}:{ss}:{ff} ({MasterFrame})") burn_in_options.settings.set_editor_property('BottomRightText', "{ShotFrame}") # Load a Texture2D asset and assign it to the UTexture2D reference that Watermark is. # burn_in_settings.set_editor_property('Watermark', None) burn_in_options.settings.set_editor_property( 'Watermark', unreal.load_asset("/Engine/EngineResources/AICON-Green")) burn_in_options.settings.set_editor_property( 'WatermarkTint', unreal.LinearColor(1.0, 0.5, 0.5, 0.5)) # Create a FLinearColor to tint our Watermark # Assign our created instances to our original capture_settings object. capture_settings.burn_in_options = burn_in_options capture_settings.protocol_settings = protocol_settings # Finally invoke Sequencer's Render to Movie functionality. This will examine the specified settings object and either construct a new PIE instance to render in, # or create and launch a new process (optionally shutting down your editor). unreal.SequencerTools.render_movie(capture_settings)
#-------------------------------------------------------- # Create a Material mat_fullpath = "/Game/TestFolder/M_Test_00" new_mat_asset = create_material(mat_fullpath) print(new_mat_asset) # Create a Material Instance mic_fullpath = "/Game/TestFolder/MIC_Test_00" new_mic_asset = create_material_instance(mic_fullpath) print(new_mic_asset) #-------------------------------------------------------- # Set Material Instance parent material mic_asset = get_asset_from_path("/Game/TestFolder/MIC_Test_00") parent_material_asset = get_asset_from_path( "/Game/MyContentFolder/MyMaterialTest_01") set_material_instance_parent(mic_asset, parent_material_asset) # Set Material Instance scalar parameter mic_asset = get_asset_from_path("/Game/TestFolder/MIC_Test_00") set_material_instance_param(mic_asset, "myscale", 34.0) # Set Material Instance texture parameter mic_asset = get_asset_from_path("/Game/TestFolder/MIC_Test_00") texture_asset = get_asset_from_path('/Engine/EngineResources/AICON-Green') set_material_instance_param(mic_asset, "mytexture", texture_asset) # Set Material Instance vector parameter mic_asset = get_asset_from_path("/Game/TestFolder/MIC_Test_00") vector = unreal.LinearColor(1, 2, 3, 1) set_material_instance_param(mic_asset, "mycolor", vector)
def createMaterialInstance(self , NewMatName = "MI_test",parameterNames = [], parameters = []): EditorLibrary=self.EditorLibrary if parameters[3] == "y" or parameters[3] == "True" or parameters[3] == "yes": writeParameters = True else: writeParameters = False if unreal.EditorAssetLibrary.does_asset_exist(self.UEMaterialDirectory + '/' + self.legalizeName(NewMatName)): #unreal.log_warning("material already exists, skipping") #TODO if the overwrite command is set, set parameters for that material anyway. NewMaterial = unreal.EditorAssetLibrary.load_asset(self.UEMaterialDirectory + '/' + self.legalizeName(NewMatName)) else: writeParameters = True NewMaterial = self.AssetTools.create_asset(asset_name=self.legalizeName(NewMatName),package_path=self.UEMaterialDirectory,asset_class = unreal.MaterialInstanceConstant, factory=unreal.MaterialInstanceConstantFactoryNew()) #EditorLibrary.save_asset(NewMaterial.get_path_name(),True) #TODO Fix error? if writeParameters ==True: index = 0 for parameterName in parameterNames: try: if index == 2: unreal.log("foundParent") parentPath = parameters[index] if not parentPath.startswith("/"): parentPath = "/"+parentPath if EditorLibrary.does_asset_exist(parentPath): unreal.log("parent confirmed") parentMaterial = EditorLibrary.load_asset(parentPath) unreal.MaterialEditingLibrary.set_material_instance_parent(NewMaterial,parentMaterial) else: unreal.log_error("No parent material found for:" + NewMaterial.get_path_name()) break elif parameterName.startswith('T_') and parameters[index]: if parameters[index].startswith('/Game/'): texPath = parameters[index] else: texPath = UEImporter.UEMaterialDirectory + "/"+parameters[index] if EditorLibrary.does_asset_exist(texPath): unreal.MaterialEditingLibrary.set_material_instance_texture_parameter_value(NewMaterial,parameterName[2:],EditorLibrary.load_asset(texPath)) else: unreal.log_warning("Texture not found for ")# + NewMaterial.get_path_name() + ": " + parameters[index]) #TODO FIX ERROR ? elif parameterName.startswith('S_') and parameters[index]: #unreal.log("foundScalar") unreal.MaterialEditingLibrary.set_material_instance_scalar_parameter_value(NewMaterial,parameterName[2:],float(parameters[index])) elif parameterName.startswith('V_') and parameters[index]: unreal.log("foundVector3") colorfour = parameters[index] if colorfour.startswith("["): colorfour = colorfour [1:-1] colorfour = colorfour.split(",") color = unreal.LinearColor(r=float(colorfour[0]), g=float(colorfour[1]), b=float(colorfour[2]), a=1) unreal.MaterialEditingLibrary.set_material_instance_vector_parameter_value(NewMaterial,parameterName[2:],color) ''' doesn't work elif parameterName.startswith('B_') and parameters[index]: unreal.log("foundBool") unreal.MaterialEditingLibrary.set_material_instance_boolean_parameter_value(NewMaterial,parameterName[2:],False) #if parameters[index] == "True" or parameters[index] == "TRUE" or parameters[index] == "yes" or parameters[index] == "yes" or parameters[index] == "true" or parameters[index] == "y": # unreal.MaterialEditingLibrary.set_material_instance_boolean_parameter_value(NewMaterial,parameterName[2:],True) #elif parameters[index] == "False" or parameters[index] == "FALSE" or parameters[index] == "false" or parameters[index] == "FALSE" or parameters[index] == "no" or parameters[index] == "n": # unreal.MaterialEditingLibrary.set_material_instance_boolean_parameter_value(NewMaterial,parameterName[2:],False) ''' except Exception: unreal.log("no index") unreal.log_warning(index) index += 1 return
def render_sequence_to_movie(sequencer_asset_path): # 1) Create an instance of our UAutomatedLevelSequenceCapture and override all of the settings on it. This class is currently # set as a config class so settings will leak between the Unreal Sequencer Render-to-Movie UI and this object. To work around # this, we set every setting via the script so that no changes the user has made via the UI will affect the script version. # The users UI settings will be reset as an unfortunate side effect of this. capture_settings = unreal.AutomatedLevelSequenceCapture() # Set all POD settings on the UMovieSceneCapture capture_settings.settings.output_directory = unreal.DirectoryPath( "../../../QAGame/Saved/VideoCaptures/") # If you game mode is implemented in Blueprint, load_asset(...) is going to return you the C++ type ('Blueprint') and not what the BP says it inherits from. # Instead, because game_mode_override is a TSubclassOf<AGameModeBase> we can use unreal.load_class to get the UClass which is implicitly convertable. # ie: capture_settings.settings.game_mode_override = unreal.load_class(None, "/Game/AI/TestingSupport/AITestingGameMode.AITestingGameMode_C") capture_settings.settings.game_mode_override = None capture_settings.settings.output_format = "{world}" capture_settings.settings.overwrite_existing = True capture_settings.settings.use_relative_frame_numbers = False capture_settings.settings.handle_frames = 0 capture_settings.settings.zero_pad_frame_numbers = 4 # If you wish to override the output framerate you can use these two lines, otherwise the framerate will be derived from the sequence being rendered capture_settings.settings.use_custom_frame_rate = True capture_settings.settings.custom_frame_rate = unreal.FrameRate(24, 1) capture_settings.settings.resolution.res_x = 1280 capture_settings.settings.resolution.res_y = 720 capture_settings.settings.enable_texture_streaming = False capture_settings.settings.cinematic_engine_scalability = True capture_settings.settings.cinematic_mode = True capture_settings.settings.allow_movement = False # Requires cinematic_mode = True capture_settings.settings.allow_turning = False # Requires cinematic_mode = True capture_settings.settings.show_player = False # Requires cinematic_mode = True capture_settings.settings.show_hud = False # Requires cinematic_mode = True capture_settings.use_separate_process = False capture_settings.close_editor_when_capture_starts = False # Requires use_separate_process = True capture_settings.additional_command_line_arguments = "-NOSCREENMESSAGES" # Requires use_separate_process = True capture_settings.inherited_command_line_arguments = "" # Requires use_separate_process = True # Set all the POD settings on UAutomatedLevelSequenceCapture capture_settings.use_custom_start_frame = False # If False, the system will automatically calculate the start based on sequence content capture_settings.use_custom_end_frame = False # If False, the system will automatically calculate the end based on sequence content capture_settings.custom_start_frame = unreal.FrameNumber( 0) # Requires use_custom_start_frame = True capture_settings.custom_end_frame = unreal.FrameNumber( 0) # Requires use_custom_end_frame = True capture_settings.warm_up_frame_count = 0.0 capture_settings.delay_before_warm_up = 0 capture_settings.delay_before_shot_warm_up = 0.0 capture_settings.write_edit_decision_list = True # Tell the capture settings which level sequence to render with these settings. The asset does not need to be loaded, # as we're only capturing the path to it and when the PIE instance is created it will load the specified asset. # If you only had a reference to the level sequence, you could use "unreal.SoftObjectPath(mysequence.get_path_name())" capture_settings.level_sequence_asset = unreal.SoftObjectPath( sequencer_asset_path) # To configure the video output we need to tell the capture settings which capture protocol to use. The various supported # capture protocols can be found by setting the Unreal Content Browser to "Engine C++ Classes" and filtering for "Protocol" # ie: CompositionGraphCaptureProtocol, ImageSequenceProtocol_PNG, etc. Do note that some of the listed protocols are not intended # to be used directly. # Right click on a Protocol and use "Copy Reference" and then remove the extra formatting around it. ie: # Class'/Script/MovieSceneCapture.ImageSequenceProtocol_PNG' gets transformed into "/Script/MovieSceneCapture.ImageSequenceProtocol_PNG" capture_settings.set_image_capture_protocol_type( unreal.load_class( None, "/Script/MovieSceneCapture.ImageSequenceProtocol_PNG")) # After we have set the capture protocol to a soft class path we can start editing the settings for the instance of the protocol that is internallyc reated. capture_settings.get_image_capture_protocol().compression_quality = 100 # The other complex settings is the burn-in. Create an instance of the LevelSequenceBurnInOptions which is used to # specify if we should use a burn in, and then which settings. burn_in_options = unreal.LevelSequenceBurnInOptions() burn_in_options.use_burn_in = True # You have to specify a path to a class to use for the burn in (if use_burn_in = True), and this class specifies a UClass to define the # settings object type. We've created a convinence function which takes the class path, loads the class at that path and assigns it to # the Settings object. burn_in_options.set_burn_in( unreal.SoftClassPath( "/Engine/Sequencer/DefaultBurnIn.DefaultBurnIn_C")) # The default burn in is implemented entirely in Blueprint which means that the method we've been using to set properties will not # work for it. The python bindings that turn bSomeVariableName into "some_variable_name" only work for C++ classes with # UPROPERTY(BlueprintReadWrite) marked fields. Python doesn't know about the existence of Blueprint classes and their fields, so we # have to use an alternative method. burn_in_options.settings.set_editor_property( 'TopLeftText', "{FocalLength}mm,{Aperture},{FocusDistance}") burn_in_options.settings.set_editor_property( 'TopCenterText', "{MasterName} - {Date} - {EngineVersion}") burn_in_options.settings.set_editor_property( 'TopRightText', "{TranslationX} {TranslationY} {TranslationZ}, {RotationX} {RotationY} {RotationZ}" ) burn_in_options.settings.set_editor_property('BottomLeftText', "{ShotName}") burn_in_options.settings.set_editor_property( 'BottomCenterText', "{hh}:{mm}:{ss}:{ff} ({MasterFrame})") burn_in_options.settings.set_editor_property('BottomRightText', "{ShotFrame}") # Load a Texture2D asset and assign it to the UTexture2D reference that Watermark is. # burn_in_settings.set_editor_property('Watermark', None) # Note that this example creates a really obvious watermark (a big blurry green smiley face) just so that you know it's working! burn_in_options.settings.set_editor_property( 'Watermark', unreal.load_asset("/Engine/EngineResources/AICON-Green")) burn_in_options.settings.set_editor_property( 'WatermarkTint', unreal.LinearColor(1.0, 0.5, 0.5, 0.5)) # Create a FLinearColor to tint our Watermark # Assign our created instances to our original capture_settings object. capture_settings.burn_in_options = burn_in_options # Finally invoke Sequencer's Render to Movie functionality. This will examine the specified settings object and either construct a new PIE instance to render in, # or create and launch a new process (optionally shutting down your editor). unreal.SequencerTools.render_movie(capture_settings, on_finished_callback)