交换框架(Interchange Framework) 是虚幻引擎的导入和导出框架。它与文件格式无关,异步,可自定义,可在运行时使用。
交换导入接口
交换使用可扩展的代码库,并提供可自定义的管线堆栈。这样你就可以根据项目的需求自由地使用蓝图或Python编辑导入管线。
重要概念和术语
- 管线(Pipeline) :处理所导入数据的操作的集合。管线公开了用于自定义导入过程的选项。
- 管线堆栈(Pipeline Stack) :处理所导入文件的管线的有序列表。管线在堆栈中组合并指定为特定文件格式。管线堆栈位于 项目设置(Project Settings)> 交换(Interchange) 中。
- 工厂(Factory) :从导入的数据生成资产的操作。
启用交换插件
交换框架需要 交换编辑器(Interchange Editor) 和 交换框架(Interchange Framework) 插件,这些插件默认启用。如果在你的项目中没有启用,请在项目的项目设置中将其启用。如需详细了解如何启用插件,请参阅使用插件。
导入资产
在虚幻引擎中,导入资产的方法有很多种。你可以使用内容侧滑菜单或内容浏览器导入资产,也可以从主菜单选择 文件(File)> 导入到关卡中(Import Into Level) 来导入资产。如需详细了解如何导入文件,请参阅直接导入资产。
导入到关卡中(Import Into Level) 目前适用于glTF和 MaterialX 文件格式。
导入过程
这些方法会触发导入过程。
- 使用上面列出的方法之一开始导入过程。
- 这会打开 交换管线(Interchange Pipeline) 配置窗口。
- 从 选择管线堆栈(Choose Pipeline Stack) 下拉菜单选择要使用的管线堆栈。
- 配置你的设置,并按 导入(Import) 完成该过程。
使用该接口选择你的导入设置并点击"导入(Import)"继续。
对于每种方法,引擎都会检查文件格式是否受交换框架支持。如果支持,交换会使用适合你的格式的导入管线堆栈,并经历以下过程:
- 交换会将导入的数据转化为虚幻引擎中的中间节点结构。
- 交换会遍历管线堆栈,并按照导入说明操作。
- 使用工厂从结果生成资产。
如果文件格式不受交换支持,虚幻引擎将使用旧版框架导入文件。
使用交换重新导入资产
当你重新导入之前使用交换导入的资产时,虚幻引擎会记住使用的管线堆栈和选项,并显示这些选项。
使用蓝图导入资产
你可以使用蓝图通过交换框架将资产导入到虚幻引擎中。
蓝图示例会创建一个在运行时使用交换导入文件的对象。
例如,你可以使用此功能,在基于虚幻引擎的应用程序中在运行时使用交换来导入文件。上面的示例创建了一个函数,它会使用默认纹理管线堆栈将纹理文件导入指定文件位置。这种导入方法目前不支持骨骼网格体或动画数据。
创建新的蓝图类
要重新创建示例,请执行以下步骤:
- 在你的项目中创建新的Actor蓝图类,以包含该函数。右键点击 内容浏览器(Content Browser) 并从上下文菜单选择 蓝图类(Blueprint Class) 。
-
在 选择父类(Pick Parent Class) 窗口中,选择 Actor 并将新蓝图类命名为 InterchangeActor 。
选择新蓝图的父类。
添加函数
- 双击该新蓝图,打开编辑器。
-
在 我的蓝图(My Blueprint) 面板中,点击 函数(Functions) 分段中的 + 按钮,并将新函数命名为 InterchangeImport 。
创建新函数
添加和连接节点
- 添加 Sequence 节点并将其连接到函数的输出。
- 拖移 Then 0 输出并创建 Create Source Data 节点,以引用将导入的现有文件。
- 拖移 Create Source Data 上的 输入文件名(In File Name) 输入,并从上下文菜单选择 提升到变量(Promote to Variable) 。
- 将新的字符串变量命名为 FilePath 。这会保存将导入的文件的位置。
- 在蓝图中,选择新变量并选中 实例可编辑(Instance Editable) 复选框。这样可按蓝图实例编辑该变量。
- 将 Create Source Data 节点的输出提升到名为 SourceData 的新变量。
- 拖移Sequence上的 Then 1 输出,并创建 Get Interchange Manager Scripted 节点。这会创建要在下一步中使用的交换管理器的指针。
- 拖移 Get Interchange Manager Scripted 的输出并创建 Import Asset 节点。将 Get Interchange Manager Scripted 的返回值连接到 Import Asset 上的 目标输入(Target input) 。
- 拖移 内容路径(Content Path) 输入并将其提升到名为 SavePath 的新变量。这会保存新导入的文件的位置。
- 在蓝图中,选择新变量并选中 实例可编辑(Instance Editable) 复选框。
- 获取"源数据(Source Data)"变量的引用,并将其连接到 Import Asset 上的"源数据(Source Data)"输入。
-
拖移 导入资产参数(Import Asset Parameters) 输入并创建 Make Input Asset Parameters 节点。
点击查看大图。
使函数在运行时可用
- 在 我的蓝图(My Blueprints) 面板中,点击 InterchangeImport 函数并在 细节(Details) 面板中选中 在编辑器中调用(Call In Editor) 旁边的复选框。此选项将使函数在运行时在 InterchangeActor 对象的 细节(Details) 中可用。
- 保存(Save) 并 编译(Compile) 你的蓝图。
使用你的新蓝图
- 将InterchangeActor蓝图的副本拖入关卡中。
- 点击 播放(Play) 。
- 选择 大纲视图(Outliner) 中的 InterchangeActor 。
- 填写 细节(Details) 面板中的 FilePath 和 SavePath 。
- 点击 交换导入(Interchange Import) 按钮导入你的文件。
使用上面的蓝图示例添加 Import Scene 节点会将资产直接生成到场景中。
在烘焙的应用程序中使用交换
如果你计划在运行时在烘焙的应用程序中使用交换框架,请将 Interchange 文件夹添加到项目设置的 项目 - 打包(Project - Packaging) 分段中的 要烘焙的其他资产目录(Additional Asset Directories to Cook) 。
点击查看大图。
使用Python导入资产
你可以使用Python脚本通过交换框架将资产导入到虚幻引擎中。
import unreal
gltf_path = "D:/projectPS/gltf/sketchfab/ship_in_a_bottle/scene.gltf"
source_data = unreal.InterchangeManager.create_source_data(gltf_path)
import_asset_parameters = unreal.ImportAssetParameters()
import_asset_parameters.is_automated = True
eas = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
import_asset_parameters.override_pipelines.append(eas.load_asset("/Interchange/Pipelines/DefaultSceneAssetsPipeline"))
import_asset_parameters.override_pipelines.append(eas.load_asset("/Interchange/Pipelines/DefaultSceneLevelPipeline"))
ic_mng = unreal.InterchangeManager.get_interchange_manager_scripted()
ic_mng.import_scene("/game/testinterchange/autopython/",source_data,import_asset_parameters)
在上面的示例中,Python脚本用于导入scene.gltf文件,导入过程类似于蓝图示例。
编辑管线堆栈
交换框架的一大优势是,能够选择和自定义管线堆栈,这是一个可自定义的过程堆栈,而这些过程用于处理资产数据。 你可以将管线添加到默认管线堆栈,以添加导入过程中的行为。
虚幻引擎随附以下默认管线:
- 默认资产管线
- 默认材质管线
- 默认纹理管线
- 默认场景资产管线
- 默认场景关卡管线
- 默认图表检查器管线
每个默认管线都包含用于该类型导入的最常见选项。你可以进一步自定义这些管线,满足项目的特定需要。
编辑现有管线
每个默认管线都可自定义,以满足项目和团队的需要。
下面是为项目自定义导入选项的方法:
- 在你的 项目设置(Project Settings) 中添加、删除、重新排序现有管线堆栈。
- 更改默认使用的管线。
- 修改现有默认管线。
- 创建自定义管线。
编辑项目设置
你可以在 项目设置(Project Settings) 中的 引擎(Engine)> 交换(Interchange) 下找到管线堆栈:
项目设置中的管线堆栈。
管线堆栈包含以下各项的默认设置:
- 导入内容
- 导入到关卡中
- 编辑器接口
- 通用
- 编辑器通用管线类
导入内容
虚幻引擎会使用这些设置将内容导入到 内容侧滑菜单 或 内容浏览器 中。
点击查看大图。
你可以为列出的每种内容类型改变设置。你还可以根据需要添加额外的标题。例如,默认配置包含 资产(Assets) 、 材质(Materials) 和 纹理(Textures) 。你可以将一个额外的分段添加到动画的管线堆栈,然后能够添加一个或多个自定义管线来处理传入的动画文件。
导入到关卡中
在编辑器窗口的主菜单中, 文件(File)> 导入到关卡中(Import Into Level) 选项在将内容导入到引擎中时使用这些设置。默认情况下,这将使用一起工作的两个管线,从文件导入Actor数据,然后在关卡中生成Actor:
点击查看大图。
- DefaultSceneAssetPipeline 基于与DefaultAssetPipeline相同的类,并且设计用于场景导入。
- DefaultSceneLevelPipeline 将在数据通过DefaultSceneAssetPipeline之后在世界中生成Actor。
修改现有默认管线
你可以修改默认交换管线的属性,以便更改以下内容:
- 默认值
- 可视性
- 只读状态
交换管线细节面板。
要更改默认交换管线的设置,请执行下面的步骤:
- 在内容侧滑菜单或内容浏览器中找到默认管线,然后双击打开一个管线。管线位于 Engine > Plugins > Interchange Framework Content > Pipelines 文件夹中。如果你看不到Engine文件夹,请点击 内容侧滑菜单 或 内容浏览器 右上角的 设置(Settings) ,并选中 显示引擎内容(Show Engine Content) 复选框。
- 根据需要编辑以下内容:
- 导入和重新导入过程中的可视性。
- 默认设置。
- 该属性在导入过程中是否为只读。
- 保存并关闭窗口。
创建自定义管线
你可以使用蓝图、C++或Python创建新的交换管线,进一步自定义导入过程。
使用蓝图创建自定义管线
要使用蓝图创建新的交换管线,请执行下面的步骤:
选择InterchangePipelineBase作为父类。
- 右键点击 内容侧滑菜单 或 内容浏览器 并选择 创建蓝图类(Create Blueprint Class) 。
- 在 选择父类(Pick Parent Class) 窗口中,展开 全部类(All Classes) 类别并选择 InterchangePipelineBase 作为其父类。
双击新蓝图打开 Blueprint Editor 。使用蓝图创建的自定义管线有以下函数,可以将其覆盖以添加自定义行为。
交换蓝图覆盖函数。
覆盖函数 | 说明 |
---|---|
Scripted Can Execute on Any Thread | 向交换管理器传达此管线可以在异步模式中执行的信息。 |
Scripted Execute Export Pipeline | 在导出过程中执行(功能当前不起作用。 |
Scripted Execute Pipeline | 在文件转换之后执行。创建生成资产所需的工厂。 |
Scripted Execute Post Factory Pipeline | 在工厂创建资产之后但调用PostEditChange函数之前执行。 |
Scripted Execute Post Import Pipeline | 在资产完全导入之后并调用PostEditChange函数之后执行。 |
Scripted Set Reimport Source Index | 执行并向管线表明要重新导入哪个源索引。在重新导入可能有多个源的资产时使用此函数。例如,将一个源文件用于几何体并将另一个用于蒙皮信息的骨骼网格体。 |
使用C++创建自定义管线
要使用C++创建新的交换管线,请创建包含以下内容的头文件:
#pragma once
#include "CoreMinimal.h"
#include "InterchangePipelineBase.h"
#include "InterchangeSourceData.h"
#include "Nodes/InterchangeBaseNodeContainer.h"
#include "InterchangeMyPipeline.generated.h"
UCLASS(BlueprintType)
class INTERCHANGEPIPELINES_API UInterchangeMyPipeline : public UInterchangePipelineBase
{
GENERATED_BODY()
protected:
virtual void ExecutePipeline(UInterchangeBaseNodeContainer* BaseNodeContainer, const TArray<UInterchangeSourceData*>& SourceDatas) override;
virtual bool CanExecuteOnAnyThread(EInterchangePipelineTask PipelineTask) override
{
return true;
}
};
接下来,创建包含以下内容的源文件:
#include "InterchangeMyPipeline.h"
void UInterchangeMyPipeline::ExecutePipeline(UInterchangeBaseNodeContainer* NodeContainer, const TArray<UInterchangeSourceData*>& InSourceDatas)
{
Super::ExecutePipeline(NodeContainer, InSourceDatas);
// 将你需要的逻辑放在已转换的节点或工厂节点上
}
如需详细了解如何在虚幻引擎中使用C++,请参阅使用C++编程。
使用Python创建自定义管线
要使用Python脚本创建新的交换管线,请创建新的Python脚本,并使用项目设置将其添加到启动脚本。如需详细了解如何在虚幻引擎中使用Python脚本,请参阅使用Python对虚幻编辑器编写脚本。
在下面的示例脚本中,Python脚本用于创建基本资产导入管线。
import unreal
@unreal.uclass()
class PythonPipelineTest(unreal.InterchangePythonPipelineBase):
import_static_meshes = unreal.uproperty(bool,meta=dict(Category="StaticMesh"))
import_skeletal_meshes = unreal.uproperty(bool,meta=dict(Category="SkeletalMesh"))
def cast(self, object_to_cast, object_class):
try:
return object_class.cast(object_to_cast)
except:
return None
def recursive_set_node_properties(self, base_node_container, node_unique_id):
node = base_node_container.get_node(node_unique_id)
# 设置静态网格体工厂节点启用状态
static_mesh_node = self.cast(node, unreal.InterchangeStaticMeshFactoryNode)
if static_mesh_node:
static_mesh_node.set_enabled(self.import_static_meshes)
# 设置骨骼网格体工厂节点启用状态
skeletal_mesh_node = self.cast(node, unreal.InterchangeSkeletalMeshFactoryNode)
if skeletal_mesh_node:
skeletal_mesh_node.set_enabled(self.import_static_meshes)
## 对子项迭代
childrens = base_node_container.get_node_children_uids(node.get_unique_id())
for child_uid in childrens:
self.recursive_set_node_properties(base_node_container, child_uid)
@unreal.ufunction(override=True)
def scripted_execute_pipeline(self, base_node_container, SourceDatas):
root_nodes = base_node_container.get_roots()
for node_unique_id in root_nodes:
self.recursive_set_node_properties(base_node_container, node_unique_id)
return True