首先定义我们自己的资源类型:
UCLASS()
class TESTSLATE_API UMyObject : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
int A;
};
之后,我们需要最重要的一个类:UFactory, 该类决定指定类型的资源的创建, 是否支持通过菜单创建,是否支持通过导入文件创建。
我们需要派生一个属于我们自己的UFactory子类,可以通过编辑器的类向导添加:
#include "CoreMinimal.h"
#include "Factories/Factory.h"
#include "MyObjectFactory.generated.h"
/**
*
*/
UCLASS()
class MYTEST_API UMyObjectFactory : public UFactory
{
GENERATED_BODY()
public:
UMyObjectFactory();
virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn);
};
#include "MyObjectFactory.h"
#include "MyObject.h"
UMyObjectFactory::UMyObjectFactory()
{
bCreateNew = true;
bEditAfterNew = true;
SupportedClass = UMyObject::StaticClass();
}
UObject* UMyObjectFactory::FactoryCreateNew(UClass* InClass, UObject* InParent,
FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
UMyObject* MyObject = NewObject<UMyObject>(InParent, InName, Flags);
return MyObject;
}
在UMyObjectFactory构造函数中,我们需要指定以下内容:
SupportedClass | 指定生成的资源类型 与bCreateNew 一起使用 |
bCreateNew | 指定是否支持通过菜单进行资源创建。默认情况将屏蔽 bEditorImport。与SupportedClass一起使用, CanCreateNew() 默认返回该值。CanCreateNew返回值表示是否不通过文件导入创建。详细查看UFactory的ImportObject函数 |
bEditorImport | 指定是否支持导入文件来创建资源 |
Formats | 指定支持的导入文件格式,与bEditorImport一起使用,格式为“ext;Description”,ext是扩展名,比如txt,mp3,fbx,等 |
bEditAfterNew | 指定是否创建对象后打开关联的编辑器。//这个暂时没发现有什么用。 |
bText | 指定资源将从文本格式的文件导入的还是二进制文件导入的 |
FactoryCreateNew 是在指定bCreateNew = true时调用的函数,返回创建的资源对象。
FactoryCreateText 是在指定bEditorImport=true,bText=true时,当通过编辑器导入文件时,调用的函数,返回创建的资源对象。
FactoryCreateBinary 是在指定bEditorImport=true,bText=false时,当通过编辑器导入文件时,调用的函数,返回创建的资源对象。
之后就可以在编辑器创建我们的自定义资源了
如果需要支持重新导入功能,你还需要将你的UFactory子类再通过FReimportHandler进行派生。必须重写FReimportHandler的CanReimport,SetReimportPaths,Reimport
#include "CoreMinimal.h"
#include "MyTypeFactory.h"
#include "EditorReimportHandler.h"
#include "MyReimportTypeFactory.generated.h"
/**
*
*/
UCLASS()
class TESTSLATE_API UMyReimportTypeFactory : public UMyTypeFactory, public FReimportHandler
{
GENERATED_BODY()
public:
//返回是否可以重新导入
virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
//实际重新导入的函数,通常调用UFactory的ImportObject(会根据CanCreateNew()返回该值判断通过UFactory的哪个FactoryCreate[new, text, binary] 函数进行创建新对象),返回值决定是否导入成功。
virtual EReimportResult::Type Reimport(UObject* Obj) override;
};
#include "MyReimportTypeFactory.h"
#include "MyObject.h"
bool UMyReimportTypeFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames)
{
return true;
}
void UMyReimportTypeFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths)
{
}
EReimportResult::Type UMyReimportTypeFactory::Reimport(UObject* Obj)
{
bool bOutCanceled = false;
UObject * newObject = ImportObject(Obj->GetClass(), Obj->GetOuter(), Obj->GetFName(), Obj->GetFlags(), PreferredReimportPath, nullptr, bOutCanceled);
Cast<UMyObject>(newObject)->id = 100;
return EReimportResult::Succeeded;
}