diff --git a/Release log.txt b/Release log.txt index 0b0b9144..58116c00 100644 --- a/Release log.txt +++ b/Release log.txt @@ -302,20 +302,21 @@ It is now possible to force the duration of an animation according to the scene == Rev 0.2.8 == -- New: Change: Better UI and Optimized +- New: Change: Better UI and Optimized. - New: Auto-Rig Pro support (Needed for convert armature durring the export) - New: You can now choose the preview collision color. -- New: You can set a light map res depending on the surface Area -- New: New button for update light map res depending on the surface Area -- New: You can now use ../ for up one directory in folder names -- New: You can now set Socket name in object property if needed +- New: You can set a light map res depending on the surface Area. +- New: New button for update light map res depending on the surface Area. +- New: You can now use ../ for up one directory in folder names. +- New: You can now set Socket name in object property if needed. - New: You can now set skeleton name to use for import script (Proxy use) - New: You can now set directly the desired export name for each objects. - New: More option for action names. - New: Camera Sensor Width and Height are now added in additional tracks. -- New: Cached animation to export in UI for better optimisation -- New: Skeleton search mode for import animation with specific skeleton -- New: Option for export only selected object and active action +- New: Cached animation to export in UI for better optimisation. +- New: Skeleton search mode for import animation with specific skeleton. +- New: Option for export only selected object and active action. +- New: Option for export collections with Subfolder. - Change: New potential error: Check if the unit scale is equal to 0.01 (You can disable this potential error in addon_prefs) - Change: Better check and potential errors info for Armature. - Change: Some potential errors can have button to the documentation. diff --git a/blender-for-unrealengine/__init__.py b/blender-for-unrealengine/__init__.py index d1783a86..b9191a05 100644 --- a/blender-for-unrealengine/__init__.py +++ b/blender-for-unrealengine/__init__.py @@ -67,9 +67,7 @@ 'blender': (2, 80, 0), 'location': 'View3D > UI > Unreal Engine 4', 'warning': '', - "wiki_url": "https://github.com/xavier150/" \ - "Blender-For-UnrealEngine-Addons" \ - "/blob/master/docs/How%20export%20assets%20from%20Blender.md", + "wiki_url": "https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki", 'tracker_url': 'https://github.com/xavier150/Blender-For-UnrealEngine-Addons/issues', 'support': 'COMMUNITY', 'category': 'Import-Export'} diff --git a/blender-for-unrealengine/bfu_addon_pref.py b/blender-for-unrealengine/bfu_addon_pref.py index 2b318bce..fc14b504 100644 --- a/blender-for-unrealengine/bfu_addon_pref.py +++ b/blender-for-unrealengine/bfu_addon_pref.py @@ -220,9 +220,8 @@ class BFU_OT_OpenDocumentationTargetPage(Operator): def execute(self, context): os.system( "start \"\" " + - "https://github.com/xavier150/" + - "Blender-For-UnrealEngine-Addons/blob/master/docs/" + - "How%20export%20assets%20from%20Blender.md"+self.octicon + "https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki/How-export-assets" + + "#"+self.octicon ) return {'FINISHED'} @@ -270,7 +269,7 @@ def PropWithDocButton(tagetlayout, name, docOcticon): LabelWithDocButton( rootBone, "SKELETON & ROOT BONE", - "#skeleton--root-bone" + "skeleton--root-bone" ) rootBone.prop(self, "removeSkeletonRootBone") rootBoneName = rootBone.column() @@ -296,7 +295,7 @@ def PropWithDocButton(tagetlayout, name, docOcticon): data = boxColumn.box() data.label(text='DATA') data.prop(self, "ignoreNLAForAction") - PropWithDocButton(data, "correctExtremUVScale", "#uv") + PropWithDocButton(data, "correctExtremUVScale", "uv") data.prop(self, "bakeArmatureAction") data.prop(self, "exportWithCustomProps") data.prop(self, "exportWithMetaData") diff --git a/blender-for-unrealengine/bfu_basics.py b/blender-for-unrealengine/bfu_basics.py index 77c88e7f..a57ddf86 100644 --- a/blender-for-unrealengine/bfu_basics.py +++ b/blender-for-unrealengine/bfu_basics.py @@ -236,6 +236,8 @@ def VerifiDirs(directory): if not os.path.exists(directory): os.makedirs(directory) + return True + return False def ValidFilename(filename): diff --git a/blender-for-unrealengine/bfu_export_asset.py b/blender-for-unrealengine/bfu_export_asset.py index 131a58c3..b2327ca6 100644 --- a/blender-for-unrealengine/bfu_export_asset.py +++ b/blender-for-unrealengine/bfu_export_asset.py @@ -160,13 +160,15 @@ def UpdateProgress(time=None): if scene.static_collection_export: for col in GetCollectionToExport(scene): if col in targetcollection: - # StaticMesh collection - ExportSingleStaticMeshCollection( - scene, - GetCollectionExportDir(), - GetCollectionExportFileName(col), - col - ) + # Save current start/end frame + UserStartFrame = scene.frame_start + UserEndFrame = scene.frame_end + + ProcessCollectionExport(col) + + # Resets previous start/end frame + scene.frame_start = UserStartFrame + scene.frame_end = UserEndFrame UpdateProgress() # Export assets @@ -296,13 +298,21 @@ def ExportForUnrealEngine(): RemoveFolderTree(bpy.path.abspath(scene.export_camera_file_path)) RemoveFolderTree(bpy.path.abspath(scene.export_other_file_path)) - obj_list = [] # Do a simple list of objects to export - action_list = [] # Do a simple list of objects to export + obj_list = [] # Do a simple list of Objects to export + action_list = [] # Do a simple list of Action to export + col_list = [] # Do a simple list of Collection to export AssetToExport = GetFinalAssetToExport() for Asset in AssetToExport: if Asset.type == "Action" or Asset.type == "Pose": if Asset.obj not in action_list: action_list.append(Asset.action.name) + if Asset.obj not in obj_list: + obj_list.append(Asset.obj) + + elif Asset.type == "Collection StaticMesh": + if Asset.obj not in col_list: + col_list.append(Asset.obj) + else: if Asset.obj not in obj_list: obj_list.append(Asset.obj) @@ -310,7 +320,7 @@ def ExportForUnrealEngine(): ExportAllAssetByList( targetobjects=obj_list, targetActionName=action_list, - targetcollection=MyCurrentDataSave.collection_names, + targetcollection=col_list, ) MyCurrentDataSave.ResetSelectByName() diff --git a/blender-for-unrealengine/bfu_export_single_static_mesh.py b/blender-for-unrealengine/bfu_export_single_static_mesh.py index 9bdef61a..a154b77b 100644 --- a/blender-for-unrealengine/bfu_export_single_static_mesh.py +++ b/blender-for-unrealengine/bfu_export_single_static_mesh.py @@ -53,7 +53,7 @@ def ProcessStaticMeshExport(obj): MyAsset = scene.UnrealExportedAssetsList.add() MyAsset.StartAssetExport(obj) - ExportSingleStaticMesh(scene, dirpath, GetObjExportFileName(obj), obj) + ExportSingleStaticMesh(dirpath, GetObjExportFileName(obj), obj) file = MyAsset.files.add() file.name = GetObjExportFileName(obj) file.path = dirpath @@ -72,7 +72,6 @@ def ProcessStaticMeshExport(obj): def ExportSingleStaticMesh( - originalScene, dirpath, filename, obj diff --git a/blender-for-unrealengine/bfu_export_single_static_mesh_collection.py b/blender-for-unrealengine/bfu_export_single_static_mesh_collection.py index 730f5f2f..5d375b46 100644 --- a/blender-for-unrealengine/bfu_export_single_static_mesh_collection.py +++ b/blender-for-unrealengine/bfu_export_single_static_mesh_collection.py @@ -48,8 +48,39 @@ from . import bfu_check_potential_error +def ProcessCollectionExport(col): + + addon_prefs = bpy.context.preferences.addons[__package__].preferences + dirpath = GetCollectionExportDir(bpy.data.collections[col]) + absdirpath = bpy.path.abspath(dirpath) + scene = bpy.context.scene + + MyAsset = scene.UnrealExportedAssetsList.add() + MyAsset.StartAssetExport(collection=col) + + obj = ExportSingleStaticMeshCollection(dirpath, GetCollectionExportFileName(col), col) + + MyAsset.SetObjData(obj) + + file = MyAsset.files.add() + file.name = GetCollectionExportFileName(col) + file.path = dirpath + file.type = "FBX" + + if (scene.text_AdditionalData and addon_prefs.useGeneratedScripts): + + ExportSingleAdditionalParameterMesh(absdirpath, GetCollectionExportFileName(col, "_AdditionalTrack.json"), obj) + file = MyAsset.files.add() + file.name = GetCollectionExportFileName(col, "_AdditionalTrack.json") + file.path = dirpath + file.type = "AdditionalTrack" + + CleanSingleStaticMeshCollection(obj) + MyAsset.EndAssetExport(True) + return MyAsset + + def ExportSingleStaticMeshCollection( - originalScene, dirpath, filename, collectionName @@ -60,13 +91,19 @@ def ExportSingleStaticMeshCollection( #COLLECTION ##################################################### ''' + collection = bpy.data.collections[collectionName] + # create collection and export it obj = bpy.data.objects.new("EmptyCollectionForUnrealExport_Temp", None) bpy.context.scene.collection.objects.link(obj) obj.instance_type = 'COLLECTION' - obj.instance_collection = bpy.data.collections[collectionName] - ExportSingleStaticMesh(originalScene, dirpath, filename, obj) + obj.instance_collection = collection + ExportSingleStaticMesh(dirpath, filename, obj) + obj.exportFolderName = collection.exportFolderName + return obj + +def CleanSingleStaticMeshCollection(obj): # Remove the created collection SelectSpecificObject(obj) CleanDeleteObjects(bpy.context.selected_objects) diff --git a/blender-for-unrealengine/bfu_ui.py b/blender-for-unrealengine/bfu_ui.py index 74446e77..f07b6d8c 100644 --- a/blender-for-unrealengine/bfu_ui.py +++ b/blender-for-unrealengine/bfu_ui.py @@ -121,6 +121,18 @@ class BFU_PT_BlenderForUnrealObject(bpy.types.Panel): subtype='FILE_NAME' ) + bpy.types.Collection.exportFolderName = StringProperty( + name="Sub folder name", + description=( + 'The name of sub folder.' + + ' You can now use ../ for up one directory.' + ), + + maxlen=64, + default="", + subtype='FILE_NAME' + ) + bpy.types.Object.bfu_export_fbx_camera = BoolProperty( name="Export camera fbx", description=( @@ -294,7 +306,7 @@ class BFU_PT_BlenderForUnrealObject(bpy.types.Panel): name="", description=( "The full reference of the skeleton in Unreal. " + - "Skeleton not the skeletal mesh. (Use right clic on asset and copy reference.)" + "(Use right clic on asset and copy reference.)" ), default="SkeletalMesh'/Game/ImportedFbx/SK_MySketonName_Skeleton.SK_MySketonName_Skeleton'" ) @@ -762,15 +774,13 @@ class BFU_PT_BlenderForUnrealObject(bpy.types.Panel): class BFU_OT_OpenDocumentationPage(Operator): bl_label = "Documentation" - bl_idname = "object.open_documentation_page" + bl_idname = "object.bfu_open_documentation_page" bl_description = "Clic for open documentation page on GitHub" def execute(self, context): os.system( "start \"\" " + - "https://github.com/xavier150/" + - "Blender-For-UnrealEngine-Addons/blob/master/" + - "docs/How%20export%20assets%20from%20Blender.md" + "https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki" ) return {'FINISHED'} @@ -955,12 +965,14 @@ class BFU_OT_AddObjectGlobalPropertiesPreset(AddPresetBase, Operator): # Common variable used for all preset values preset_defines = [ 'obj = bpy.context.object', + 'col = bpy.context.collection', 'scene = bpy.context.scene' ] # Properties to store in the preset preset_values = [ 'obj.exportFolderName', + 'col.exportFolderName', 'obj.bfu_export_fbx_camera', 'obj.ExportAsAlembic', 'obj.ExportAsLod', @@ -1018,6 +1030,7 @@ class BFU_OT_AddObjectGlobalPropertiesPreset(AddPresetBase, Operator): preset_subdir = 'blender-for-unrealengine/global-properties-presets' class BFU_UL_CollectionExportTarget(bpy.types.UIList): + def draw_item( self, context, @@ -1041,7 +1054,7 @@ def draw_item( "name", text="", emboss=False, - icon="GROUP") + icon="OUTLINER_COLLECTION") layout.prop(item, "use", text="") else: dataText = ( @@ -1122,7 +1135,7 @@ def draw(self, contex): credit_box = layout.box() credit_box.label(text=ti('intro')+' Version: '+str(version)) - credit_box.operator("object.open_documentation_page", icon="HELP") + credit_box.operator("object.bfu_open_documentation_page", icon="HELP") row = layout.row(align=True) row.menu( @@ -1487,11 +1500,16 @@ def draw(self, contex): "object.updatecollectionlist", icon='RECOVER_LAST') + col_name = scene.CollectionExportList[scene.active_CollectionExportList].name + col = bpy.data.collections[col_name] + col_prop = layout + col_prop.prop(col, 'exportFolderName', icon='FILE_FOLDER') + collectionPropertyInfo = layout.row().box().split(factor=0.75) collectionNum = len(GetCollectionToExport(scene)) collectionFeedback = ( str(collectionNum) + - " Collection(s) will be exported with this armature.") + " Collection(s) will be exported.") collectionPropertyInfo.label(text=collectionFeedback, icon='INFO') collectionPropertyInfo.operator("object.showscenecollection") layout.label(text='Note: The collection are exported like StaticMesh.') @@ -1789,19 +1807,29 @@ class BFU_OT_UnrealExportedAsset(bpy.types.PropertyGroup): asset_name: StringProperty(default="None") asset_type: StringProperty(default="None") # return from GetAssetType() + folder_name: StringProperty(default="None") files: CollectionProperty(type=BFU_OT_FileExport) object: PointerProperty(type=bpy.types.Object) export_start_time: FloatProperty(default=0) export_end_time: FloatProperty(default=0) export_success: BoolProperty(default=False) - def StartAssetExport(self, obj, action=None): + def SetObjData(self, obj): self.object = obj self.asset_name = obj.name - if action: - self.asset_type = GetActionType(action) - else: + self.folder_name = obj.exportFolderName + + def StartAssetExport(self, obj=None, action=None, collection=None): + if obj: + self.SetObjData(obj) + + if obj: self.asset_type = GetAssetType(obj) + if action: + self.asset_type = GetActionType(action) # Override + if collection: + self.asset_type = GetCollectionType(collection) # Override + self.export_start_time = time.perf_counter() def EndAssetExport(self, success): @@ -2096,11 +2124,8 @@ class BFU_OT_OpenPotentialErrorDocs(Operator): def execute(self, context): os.system( "start \"\" " + - "https://github.com/xavier150/" + - "Blender-For-UnrealEngine-Addons/" + - "blob/master/docs/" + - "Potential%20Error%20with%20Blender%20export%20" + - "to%20Unreal.md#"+self.octicon) + "https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki/How-avoid-potential-errors" + + "#"+self.octicon) return {'FINISHED'} def execute(self, context): diff --git a/blender-for-unrealengine/bfu_utils.py b/blender-for-unrealengine/bfu_utils.py index a38a9aa7..c80c389e 100644 --- a/blender-for-unrealengine/bfu_utils.py +++ b/blender-for-unrealengine/bfu_utils.py @@ -714,6 +714,12 @@ def GetActionType(action): return "Action" +def GetCollectionType(collection): + # return collection type + + return "Collection StaticMesh" + + def GetIsAnimation(type): # return True if type(string) is a animation if (type == "NlAnim" or type == "Action" or type == "Pose"): @@ -1128,14 +1134,18 @@ def ValidUnrealAssetename(filename): return filename -def GetCollectionExportDir(abspath=False): +def GetCollectionExportDir(col, abspath=False): # Generate assset folder path scene = bpy.context.scene + dirpath = os.path.join( + scene.export_static_file_path, + col.exportFolderName) + if abspath: return bpy.path.abspath(dirpath) else: - return os.path.join(scene.export_static_file_path, "") + return dirpath def GetObjExportName(obj): diff --git a/blender-for-unrealengine/bfu_write_import_asset_script.py b/blender-for-unrealengine/bfu_write_import_asset_script.py index 63e56ddc..7460e4a7 100644 --- a/blender-for-unrealengine/bfu_write_import_asset_script.py +++ b/blender-for-unrealengine/bfu_write_import_asset_script.py @@ -60,9 +60,11 @@ def WriteImportAssetScript(): data['assets'] = [] for asset in scene.UnrealExportedAssetsList: asset_data = {} - asset_data["name"] = asset.object.name + asset_data["name"] = asset.asset_name if GetIsAnimation(asset.asset_type): asset_data["type"] = "Animation" + elif asset.asset_type == "Collection StaticMesh": + asset_data["type"] = "StaticMesh" else: asset_data["type"] = asset.asset_type if asset.asset_type == "StaticMesh" or asset.asset_type == "SkeletalMesh": @@ -72,9 +74,9 @@ def WriteImportAssetScript(): asset_data["lod"] = 0 if GetIsAnimation(asset.asset_type): - relative_import_path = os.path.join(asset.object.exportFolderName, scene.anim_subfolder_name) + relative_import_path = os.path.join(asset.folder_name, scene.anim_subfolder_name) else: - relative_import_path = asset.object.exportFolderName + relative_import_path = asset.folder_name asset_data["full_import_path"] = "/Game/" + os.path.join(scene.unreal_import_location, relative_import_path).replace('\\', '/').rstrip('/') @@ -95,15 +97,15 @@ def WriteImportAssetScript(): if GetIsAnimation(asset.asset_type): if(asset.object.bfu_skeleton_search_mode) == "auto": - customName = scene.skeletal_prefix_export_name+ValidUnrealAssetename(asset.object.name)+"_Skeleton" + customName = scene.skeletal_prefix_export_name+ValidUnrealAssetename(asset.asset_name)+"_Skeleton" SkeletonName = customName+"."+customName - SkeletonLoc = os.path.join(asset.object.exportFolderName, SkeletonName) + SkeletonLoc = os.path.join(asset.folder_name, SkeletonName) asset_data["animation_skeleton_path"] = os.path.join("/Game/", scene.unreal_import_location, SkeletonLoc).replace('\\', '/') elif(asset.object.bfu_skeleton_search_mode) == "custom_name": customName = ValidUnrealAssetename(asset.object.bfu_target_skeleton_custom_name) SkeletonName = customName+"."+customName - SkeletonLoc = os.path.join(asset.object.exportFolderName, SkeletonName) + SkeletonLoc = os.path.join(asset.folder_name, SkeletonName) asset_data["animation_skeleton_path"] = os.path.join("/Game/", scene.unreal_import_location, SkeletonLoc).replace('\\', '/') elif(asset.object.bfu_skeleton_search_mode) == "custom_path_name": @@ -115,26 +117,27 @@ def WriteImportAssetScript(): elif(asset.object.bfu_skeleton_search_mode) == "custom_reference": asset_data["animation_skeleton_path"] = asset.object.bfu_target_skeleton_custom_ref.replace('\\', '/') - asset_data["create_physics_asset"] = asset.object.CreatePhysicsAsset - asset_data["material_search_location"] = asset.object.MaterialSearchLocation + if asset.object: + asset_data["create_physics_asset"] = asset.object.CreatePhysicsAsset + asset_data["material_search_location"] = asset.object.MaterialSearchLocation - asset_data["auto_generate_collision"] = asset.object.AutoGenerateCollision - if (asset.object.UseStaticMeshLODGroup): - asset_data["static_mesh_lod_group"] = asset.object.StaticMeshLODGroup - else: - asset_data["static_mesh_lod_group"] = None - asset_data["generate_lightmap_u_vs"] = asset.object.GenerateLightmapUVs - - asset_data["custom_light_map_resolution"] = ExportCompuntedLightMapValue(asset.object) - asset_data["light_map_resolution"] = GetCompuntedLightMap(asset.object) - asset_data["collision_trace_flag"] = asset.object.CollisionTraceFlag - asset_data["vertex_color_import_option"] = asset.object.VertexColorImportOption - vertex_override_color = ( - asset.object.VertexOverrideColor[0], # R - asset.object.VertexOverrideColor[1], # G - asset.object.VertexOverrideColor[2] # B - ) # Color to Json - asset_data["vertex_override_color"] = vertex_override_color + asset_data["auto_generate_collision"] = asset.object.AutoGenerateCollision + if (asset.object.UseStaticMeshLODGroup): + asset_data["static_mesh_lod_group"] = asset.object.StaticMeshLODGroup + else: + asset_data["static_mesh_lod_group"] = None + asset_data["generate_lightmap_u_vs"] = asset.object.GenerateLightmapUVs + + asset_data["custom_light_map_resolution"] = ExportCompuntedLightMapValue(asset.object) + asset_data["light_map_resolution"] = GetCompuntedLightMap(asset.object) + asset_data["collision_trace_flag"] = asset.object.CollisionTraceFlag + asset_data["vertex_color_import_option"] = asset.object.VertexColorImportOption + vertex_override_color = ( + asset.object.VertexOverrideColor[0], # R + asset.object.VertexOverrideColor[1], # G + asset.object.VertexOverrideColor[2] # B + ) # Color to Json + asset_data["vertex_override_color"] = vertex_override_color data['assets'].append(asset_data) return data diff --git a/blender-for-unrealengine/bfu_write_text.py b/blender-for-unrealengine/bfu_write_text.py index bfbdb389..d70d9632 100644 --- a/blender-for-unrealengine/bfu_write_text.py +++ b/blender-for-unrealengine/bfu_write_text.py @@ -148,8 +148,11 @@ def WriteExportLog(): elif (asset.asset_type == "Pose"): primaryInfo = "Animation (Pose)" else: - if asset.object.ExportAsLod: - primaryInfo = asset.asset_type+" (LOD)" + if asset.object: + if asset.object.ExportAsLod: + primaryInfo = asset.asset_type+" (LOD)" + else: + primaryInfo = asset.asset_type else: primaryInfo = asset.asset_type @@ -363,9 +366,10 @@ def EvaluateTracks(self, camera, frame_start, frame_end): # Write Aperture (Depth of Field) keys if scene.render.engine == "BLENDER_EEVEE" or scene.render.engine == "CYCLES" or scene.render.engine == "BLENDER_WORKBENCH": - self.aperture_fstop[frame] = getOneKeysByFcurves(camera, "dof.aperture_fstop", camera.data.dof.aperture_fstop, frame) + key = getOneKeysByFcurves(camera, "dof.aperture_fstop", camera.data.dof.aperture_fstop, frame) + self.aperture_fstop[frame] = key / bpy.context.scene.unit_settings.scale_length else: - self.aperture_fstop[frame] = 21 # 21 is default value in ue4 + self.aperture_fstop[frame] = 2.8 # 2.8 is default value in ue4 boolKey = getOneKeysByFcurves(camera, "hide_viewport", camera.hide_viewport, frame, False) self.hide_viewport[frame] = (boolKey < 1) # Inversed for convert hide to spawn diff --git a/blender-for-unrealengine/import/asset_import_script.py b/blender-for-unrealengine/import/asset_import_script.py index 9a9b7dbf..e2526ca2 100644 --- a/blender-for-unrealengine/import/asset_import_script.py +++ b/blender-for-unrealengine/import/asset_import_script.py @@ -43,7 +43,7 @@ def ImportAllAssets(): def GetOptionByIniFile(FileLoc, OptionName, literal=False): return [] - #To do with Json + # To do with Json Config = ConfigParser.ConfigParser() Config.read(FileLoc) Options = [] @@ -69,8 +69,9 @@ def ImportAsset(asset_data): print("Import asset " + counter + ": ", asset_data["name"]) if asset_data["type"] == "StaticMesh" or asset_data["type"] == "SkeletalMesh": - if asset_data["lod"] > 0: # Lod should not be imported here. - return + if "lod" in asset_data: + if asset_data["lod"] > 0: # Lod should not be imported here so return if lod is not 0. + return if asset_data["type"] == "Alembic": FileType = "ABC" @@ -85,7 +86,14 @@ def ImportTask(): # New import task # Property if asset_data["type"] == "Animation": - OriginSkeleton = unreal.find_asset(asset_data["animation_skeleton_path"]) + 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": @@ -103,14 +111,13 @@ def ImportTask(): 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) @@ -133,60 +140,72 @@ def ImportTask(): 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) - task.get_editor_property('options').set_editor_property('create_physics_asset', asset_data["create_physics_asset"]) + 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": - # 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 "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) - task.get_editor_property('options').static_mesh_import_data.set_editor_property('auto_generate_collision', asset_data["auto_generate_collision"]) - 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"]) - task.get_editor_property('options').static_mesh_import_data.set_editor_property('generate_lightmap_u_vs', asset_data["generate_lightmap_u_vs"]) + 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 - vertex_override_color = unreal.LinearColor( - asset_data["vertex_override_color"][0], - asset_data["vertex_override_color"][1], - asset_data["vertex_override_color"][2] - ) - - 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_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 - task.get_editor_property('options').static_mesh_import_data.set_editor_property('vertex_color_import_option', vertex_color_import_option) - task.get_editor_property('options').static_mesh_import_data.set_editor_property('vertex_override_color', vertex_override_color.to_rgbe()) + 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 - task.get_editor_property('options').skeletal_mesh_import_data.set_editor_property('vertex_color_import_option', vertex_color_import_option) - task.get_editor_property('options').skeletal_mesh_import_data.set_editor_property('vertex_override_color', vertex_override_color.to_rgbe()) + 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 @@ -225,38 +244,47 @@ def ImportTask(): # ###############[ Post treatment ]################ if asset_data["type"] == "StaticMesh": - if asset_data["static_mesh_lod_group"]: - asset.set_editor_property('lod_group', asset_data["static_mesh_lod_group"]) - asset.set_editor_property('light_map_resolution', asset_data["light_map_resolution"]) - - 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 "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 - vertex_override_color = unreal.LinearColor( - asset_data["vertex_override_color"][0], - asset_data["vertex_override_color"][1], - asset_data["vertex_override_color"][2] - ) - - 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 - - asset.get_editor_property('asset_import_data').set_editor_property('vertex_color_import_option', vertex_color_import_option) - asset.get_editor_property('asset_import_data').set_editor_property('vertex_override_color', vertex_override_color.to_rgbe()) - 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 "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) @@ -305,10 +333,10 @@ def ImportTask(): ImportTask() - # Process import print('========================= Import started ! =========================') + print(import_assets_data["assets"]) # Import assets with a specific order diff --git a/docs/Examples/AssetsExample_Collections.blend b/docs/Examples/AssetsExample_Collections.blend index cc2d1512..ff992bd8 100644 Binary files a/docs/Examples/AssetsExample_Collections.blend and b/docs/Examples/AssetsExample_Collections.blend differ diff --git a/docs/Examples/AssetsExample_ModularExport.blend b/docs/Examples/AssetsExample_ModularExport.blend index 4b936e55..1c7af559 100644 Binary files a/docs/Examples/AssetsExample_ModularExport.blend and b/docs/Examples/AssetsExample_ModularExport.blend differ