Doris232 发表于 2022-9-15 14:26

UE4 Python批量导入一个文件夹中的FBX模型

FBX文件在虚幻引擎中通常具有三种存储形式:
1.静态网格体(Static Meshes | Unreal Engine 5.0 Documentation)
2.骨骼网格体(Skeletal Meshes | Unreal Engine 5.0 Documentation)
3.动画序列(Animation Sequences in Unreal Engine | Unreal Engine 5.0 Documentation)
认识导入UI界面(Fbx Import UI)

我们在导入FBX文件时,通常都会先看到这样的一个界面:



fbx导入UI-静态网格体

当我们勾选Skeletal Mesh的复选框后,导入UI将会变为如下形式:



fbx导入UI-骨骼网格体

在此时,就需要指定骨骼网格体对应的骨骼,以及是否作为动画序列导入(勾选Import Animations)。
可以看到,我们具体将导入的FBX作为什么样的资产,都是由对这个UI的操作决定的,而具体的属性的配置,也是在这个UI界面中对属性进行调整。那我们的Unreal Python API是否提供了相关的数据类型和操作呢?有!那就是今天我们这里用到的核心类:unreal.FbxImportUI (unreal.FbxImportUI — Unreal Python 4.27 (Experimental) documentation (unrealengine.com))
首先来看一下FbxImportUI类的核心数据(实际是editor properties,友情提示:可以此处可以快速跳过不看):

[*]anim_end_frame (str): The fbx animation end frame
[*]anim_sequence_import_data (FbxAnimSequenceImportData): Import data used when importing animations
[*]anim_start_frame (str): The fbx animation start frame
[*]auto_compute_lod_distances (bool): If checked, the editor will automatically compute screen size values for the static mesh’s LODs. If unchecked, the user can enter custom screen size values for each LOD.
[*]automated_import_should_detect_type (bool): If true the automated import path should detect the import type. If false the import type was specified by the user
[*]create_physics_asset (bool): If checked, create new PhysicsAsset if it doesn’t have it
[*]file_axis_direction (str): The file axis direction, up vector and hand
[*]file_creator (str): The file creator information
[*]file_creator_application (str): The file vendor information, software name and version that was use to create the file
[*]file_sample_rate (str): The fbx animation frame rate
[*]file_units (str): The file units
[*]file_version (str): The fbx file version
[*]import_animations (bool): True to import animations from the FBX File
[*]import_as_skeletal (bool): Whether to import the incoming FBX as a skeletal object
[*]import_materials (bool): If no existing materials are found, whether to automatically create Unreal materials for materials found in the FBX scene
[*]import_mesh (bool): Whether to import the mesh. Allows animation only import when importing a skeletal mesh.
[*]import_rigid_mesh (bool): Enables importing of ‘rigid skeletalmesh’ (unskinned, hierarchy-based animation) from this FBX file, no longer shown, used behind the scenes
[*]import_textures (bool): Whether or not we should import textures. This option is disabled when we are importing materials because textures are always imported in that case.
[*]is_obj_import (bool): Whether or not the imported file is in OBJ format
[*]lod_distance0 (float): Set a screen size value for LOD 0
[*]lod_distance1 (float): Set a screen size value for LOD 1
[*]lod_distance2 (float): Set a screen size value for LOD 2
[*]lod_distance3 (float): Set a screen size value for LOD 3
[*]lod_distance4 (float): Set a screen size value for LOD 4
[*]lod_distance5 (float): Set a screen size value for LOD 5
[*]lod_distance6 (float): Set a screen size value for LOD 6
[*]lod_distance7 (float): Set a screen size value for LOD 7
[*]lod_number (int32): Set the number of LODs for the editor to import. Setting the value to 0 imports the number of LODs found in the file (up to the maximum).
[*]mesh_type_to_import (FBXImportType): Type of asset to import from the FBX file
[*]minimum_lod_number (int32): Set the minimum LOD used for rendering. Setting the value to 0 will use the default value of LOD0.
[*]original_import_type (FBXImportType): The original detected type of this import
[*]override_animation_name (str): Override for the name of the animation to import. By default, it will be the name of FBX *
[*]override_full_name (bool): Use the string in “Name” field as full name of mesh. The option only works when the scene contains one mesh.
[*]physics_asset (PhysicsAsset): If this is set, use this PhysicsAsset. It is possible bCreatePhysicsAsset == false, and PhysicsAsset == NULL. It is possible they do not like to create anything.
[*]reset_to_fbx_on_material_conflict (bool): If true, the imported material sections will automatically be reset to the imported data in case of a reimport conflict.
[*]skeletal_mesh_import_data (FbxSkeletalMeshImportData): Import data used when importing skeletal meshes
[*]skeleton (Skeleton): Skeleton to use for imported asset. When importing a mesh, leaving this as “None” will create a new skeleton. When importing an animation this MUST be specified to import the asset.
[*]static_mesh_import_data (FbxStaticMeshImportData): Import data used when importing static meshes
[*]texture_import_data (FbxTextureImportData): Import data used when importing textures
(直接看这里)非常多是不是,这里可以挑选其中几个最核心的数据:

[*]import_animations (bool): True to import animations from the FBX File(是否导入动画)
[*]import_as_skeletal (bool): Whether to import the incoming FBX as a skeletal object(是否作为骨骼网格体导入)
[*]import_materials (bool): If no existing materials are found, whether to automatically create Unreal materials for materials found in the FBX scene(是否导入材质,没有找到会自动根据材质插槽创建材质)
[*]automated_import_should_detect_type (bool): If true the automated import path should detect the import type. If false the import type was specified by the user(会自动检测导入物体是否带骨骼,如果带的话会自动判定为骨骼网格体类型,这一项的优先级最高!!!如果不将此项设置为False的话,用户的选择将会失效)
[*]skeletal_mesh_import_data (FbxSkeletalMeshImportData): Import data used when importing skeletal meshes(导入骨骼网格体的具体细节配置)
[*]skeleton (Skeleton): Skeleton to use for imported asset. When importing a mesh, leaving this as “None” will create a new skeleton. When importing an animation this MUST be specified to import the asset.(如果作为骨骼网格体导入的话,这里是需要指定的骨骼资产)
[*]static_mesh_import_data (FbxStaticMeshImportData): Import data used when importing static meshes(导入静态网格体的具体细节配置)
[*]texture_import_data (FbxTextureImportData): Import data used when importing textures(导入材质的具体细节配置)
其中三个具体细节配置概念可能会有点难以理解,这里解释一下。当我们在导入UI中选择具体的导入类型时,会出现不同类型独有的导入配置数据,例如导入骨骼网格体时,会有这样一个选项:import_morph_targets(与混合变形有关),在导入静态网格体时就没有这个属性。具体可以参考这几个类的定义:
unreal.FbxSkeletalMeshImportData — Unreal Python 4.27 (Experimental) documentation (unrealengine.com)
unreal.FbxStaticMeshImportData — Unreal Python 4.27 (Experimental) documentation (unrealengine.com)
unreal.FbxTextureImportData — Unreal Python 4.27 (Experimental) documentation (unrealengine.com)
这里以static mesh的导入为例,使用Python构建FbxStaticMeshImportData与FbxImportUI,同时演示了如果需要对其中的一个选项做配置,可以如何传入参数。
def build_static_mesh_import_options(self, replace_vertex_color = False):
      options = unreal.FbxImportUI()
      options.set_editor_property('automated_import_should_detect_type', False)
      options.set_editor_property('mesh_type_to_import', unreal.FBXImportType.FBXIT_STATIC_MESH)
      options.set_editor_property('import_as_skeletal', False)# 是否当作骨骼物体来导入
      options.set_editor_property('import_animations', False)
      options.set_editor_property('import_materials', False)
      options.set_editor_property('import_textures', False)
      #上面是设置fbx import UI的数据
      options.static_mesh_import_data.set_editor_property('import_translation', unreal.Vector(0.0, 0.0, 0.0))
      options.static_mesh_import_data.set_editor_property('import_rotation', unreal.Rotator(0, 0, 0))
      options.static_mesh_import_data.set_editor_property('import_uniform_scale', 1.0)
   
      options.static_mesh_import_data.set_editor_property('combine_meshes', False)
      options.static_mesh_import_data.set_editor_property('generate_lightmap_u_vs', False)
      options.static_mesh_import_data.set_editor_property('auto_generate_collision', False)

      options.static_mesh_import_data.set_editor_property('one_convex_hull_per_ucx', True)
      options.static_mesh_import_data.set_editor_property('reorder_material_to_fbx_order', True)

      if replace_vertex_color == True:
            options.static_mesh_import_data.set_editor_property("vertex_color_import_option", unreal.VertexColorImportOption.REPLACE)
      else:
            options.static_mesh_import_data.set_editor_property("vertex_color_import_option", unreal.VertexColorImportOption.IGNORE)
      #上面是设置static_mesh_import_data的数据   
      
      return options根据对以上内容的认识,我们就可以配置出一个选项勾选完毕的导入UI界面了。但是如何才能唤起这个界面呢?唤起界面还需要经过两步,第一个是创建导入任务,第二个是执行导入任务。
创建导入任务(AssetImportTask)

创建导入任务需要使用API中的另一个类,那就是unreal.AssetImportTask
unreal.AssetImportTask — Unreal Python 4.27 (Experimental) documentation (unrealengine.com)
asset import task是实际导入的执行者,他也有几个属性可以去配置,这里挑几个重要的讲一下:

[*]automated (bool): Avoid dialogs(是否自动导入不弹出对话框)
[*]destination_path (str): Path where asset will be imported to(目标导入地址,推荐使用虚幻抽象后的路径,即/Game/开头的路径)
[*]factory (Factory): Optional factory to use(工厂,可选项,决定具体的导入类型,关于有哪些可以选择的factory可以参考:Search — Unreal Python 4.27 (Experimental) documentation (unrealengine.com),比如说FontFactory,BlueprintFactory,FbxFactory等等)
[*]filename (str): Filename to import(欲导入文件的绝对路径,包含文件名)
[*]options (Object): Import options specific to the type of asset(导入配置,这里我们使用FbxImportUI,在使用options后,可以不指定factory)
[*]replace_existing (bool): Overwrite existing assets(是否替换已存在资产)
[*]replace_existing_settings (bool): Replace existing settings when overwriting existing assets(是否替换现有资产设置)
[*]result (Array(Object)): Imported objects(导入结果)
[*]save (bool): Save after importing(是否自动保存导入的资产)
这里同样以static mesh的导入为例,构建一个AssetImportTask:
def creatImportTask(filename, Destination_path, options=None):

    importtask = unreal.AssetImportTask()
    importtask.set_editor_property("automated", True)
    importtask.set_editor_property('destination_path', Destination_path)
    importtask.set_editor_property('filename', filename)
    importtask.set_editor_property('replace_existing', True)
    importtask.set_editor_property('options', options)
    importtask.set_editor_property('save', True)

    return import_task到这里,我们就将导入的任务创建完成啦。接下来只要执行导入任务,就可以导入fbx资源了。
执行资源导入(AssetTools)

这一步非常简单,只需要获取到资产工具asset tool,然后执行上面配置好的导入就可以了。
unreal.AssetTools — Unreal Python 4.27 (Experimental) documentation (unrealengine.com)
def execute_import_tasks(tasks):
    asset_tools = unreal.AssetToolsHelpers.get_asset_tools()# 创建一个资产工具
    asset_tools.import_asset_tasks()# 导入资产总结

结合以上的内容,我们就可以配置好导入的基本设置然后进行fbx文件导入啦!
options = build_static_mesh_import_options()
execute_import_tasks(creatImportTask(StaticMesh_path, Destination_path, options))具体的过程就是:
1.配置好导入UI和欲导入数据类型的细节数据(FbxImportUI以及其中的import_data);
2.创建导入任务,并将导入属性(options)配置到导入任务(asset import task)中;
3.执行资源导入,通过资产工具(asset tools)执行import_asset_tasks;
那么如何进行指定文件夹目录中fbx的批量导入呢,这里提供一个实现的思路:
1.在获取指定文件目录的前提下,使用python的os模块获取目录下的所有fbx文件(这里可以根据命名规范排除一些不需要导入的文件,如命名中有LOD、Test等等的文件)
files = os.listdir(source)
fbxFiles = []
for file in files:
    if(file.endswith(('.FBX','.fbx')) and file.find('_LOD') == -1):
      fbxFiles.append(file)2.针对每一个fbx file path进行逐个导入
for file in fbxFiles:
    tasks.append(creatImportTask(get_directory() + '\\' + file, destPath, options))
execute_import_tasks(tasks)可以注意的细节

1.我们在导入导出时设定的导入路径和源文件路径一定要进行路径规范的检查,例如导入的源文件目录下是否存在fbx文件?导入的目的地文件夹是否是项目content的根目录(最好不要把资产直接放在根目录中)?是不是不在content的子目录下(引擎会识别不到)?
2.根据不同的资产类型,可以提前预先设定好几种导入配置。通常在一个项目中,资产导入的属性配置是较为稳定的,变数不大;可以跟美术同学讨论好具体的几种配置,然后让艺术家在导入的时候进行选择。同时,可以将是否弹出对话框这个选项进行暴露,供艺术家在特殊情况下进行定制。
3.尤其要注意的一点,在设置导入配置时,一定要确保automated_import_should_detect_type属性被设置为False,血的教训,不要再踩坑了!!!
4.在导入后,可以对一些基本属性进行配置,例如顶点颜色,LOD等等,减少艺术家后期设置的工序。
有任何疑问欢迎私信。
页: [1]
查看完整版本: UE4 Python批量导入一个文件夹中的FBX模型