自定义导入器技术指南

有关为自定义资源类型编写导入器的程序员指南。

Windows
MacOS
Linux

本页面是从虚幻引擎3的文档转换而来,目前正在审阅中。信息可能已过时。

在编辑器中,UFactory类用于创建新资源,最常见的是基于外部文件。

UFactory的姊妹类是UExporter,它用于为拷贝/复制操作导出资源以及将资源导出到文件。请参阅编写自定义导出器 了解如何编写导出器的信息。

添加新的UFactory类

您可能想要在游戏编辑器项目中创建自己的UFactory类。请查阅在Editor/UnrealEd/Classes/Factories中找到的类,了解与虚幻引擎4一起提供的UFactory派生类型示例。

需要注意的UFactory成员

需要用户输入的factory通常通过向其UPROPERTY()声明中添加类别来公开其成员。这些UProperty用于填充导入/创建对话框上的属性窗口。

下面是UFactory成员的列表,通常由其构造函数中的UFactory派生类型设置。

支持的类

说明该factory创建的对象类型。空表示该factory支持多种类型并且必须实现ResolveSupportedClass来消除歧义,更多信息见下文。

描述

描述该factory支持的类型。在编辑器UI中向用户呈现。

bText

如果为_true,说明该factory通过FactoryCreateText导入文本。如果为_false,说明该factory通过FactoryCreateBinary导入二进制数据。

bCreateNew

如果为_true_,该factory通过实现FactoryCreateNew,而不是通过FactoryCreateText或FactoryCreateBinary导入数据,来创建对象。

bEditorImport

如果为_true_,说明UI应将该factory视为用于导入数据的factory,换言之,该factory基于外部数据创建资源类型。

自动优先级

可选项;一个用于对支持同一个类型的多个factory进行优先排序的整数。

支持单一类型的factory

UFactory派生的大多数类型导入或创建单一类型的对象,这由factory通过在factory类的StaticConstructor()覆盖中设置SupportedClass成员指定。下面是一个用于创建新的UDecalMaterial对象的简单factory的实现示例。

UCurveFactory::UCurveFactory(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    // 属性初始化
    bCreateNew = true;
    bEditAfterNew = true;
    SupportedClass = UCurveBase::StaticClass();
    Description = TEXT("Curve");

    CurveClass = UCurveFloat::StaticClass();
}

UObject* UCurveFactory::FactoryCreateNew(UClass* Class,
                                            UObject* InParent,
                                            FName Name,
                                            EObjectFlags Flags,
                                            UObject* Context,
                                            FFeedbackContext* Warn)
{
    UCurveBase* NewCurve = NULL;
    if(CurveClass != NULL)
    {
        NewCurve = CastChecked<UCurveBase>(StaticConstructObject(CurveClass,InParent,Name,Flags));      
    }

    return NewCurve;
}

支持多种类型的factory

通过将空声明为SupportedClass,然后实现ResolveSupportedClass()来在导入之前解析该类,来实现支持多种返回类型的factory。

例如,为factory考虑以下代码,它以虚构的.ABC文本文件格式读取,并使用它来根据用户的选择创建类型A或类型B的对象:

UCLASS(hidecategories=Object)
class UYourFactory : public UFactory
{
    GENERATED_UCLASS_BODY()

    // 标记指示输入文件是应作为
    // 类型A还是类型B进行处理。它将由
    // 用户在导入对话框中设置,在
    // ResolveSupportedClass()中查看它,以确定要创建的
    // 对象的类型。
    UPROPERTY(Category=ABCOptions)
    bool bTreatAsTypeA;

(#ifcpp)

if CPP

    // UFactory实现
    UClass* ResolveSupportedClass();
    UObject* FactoryCreateText(UClass* Class, /* more args */, FFeedbackContext* Warn);

    /** 创建类型A的对象 */
    UObject* UYourFactory::CreateTypeA(UClass* Class, /* more args */, FFeedbackContext* Warn)

    /** 创建类型B的对象 */
    UObject* UYourFactory::CreateTypeB(UClass* Class, /* more args */, FFeedbackContext* Warn)
#endif // CPP
}

UYourFactory::UYourFactory(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    // 属性初始化

    // 说明"导入" UI应考虑该factory。
    bEditorImport = true;

    // 声明不支持的类,表明在选择"确定"关闭
    // 导入对话框时,导入路径应该调用
    // ResolveSupportedClass()。
    SupportedClass = NULL;

    // 记录该factory对.ABC文件有兴趣。
    new(Formats) FString( TEXT("abc;Ye Olde ABC Type") );

    bCreateNew = false;
    bText = true;          // 指示ABC是文本文件格式。
}

// 当SupportedClass为空时,导入对话框将调用它。
UClass* UYourFactory::ResolveSupportedClass()
{
    UClass* UserSpecifiedClass = bTreatAsTypeA ? UTypeA::StaticClass() : UTypeB::StaticClass();
    return UserSpecifiedClass;
}

UObject* UYourFactory::FactoryCreateText(UClass* Class, /* more args */, FFeedbackContext* Warn)
{
    UObject* NewObject;
    if ( bTreatAsTypeA )
    {
        NewObject = CreateTypeA( Class, /* more args */, Warn );
    }
    else
    {
        NewObject = CreateTypeB( Class, /* more args */, Warn );
    }
    return NewObject;
}

UObject* UYourFactory::CreateTypeA(UClass* Class, /* more args */, FFeedbackContext* Warn)
{ ...}
UObject* UYourFactory::CreateTypeB(UClass* Class, /* more args */, FFeedbackContext* Warn)
{ ...}
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback