How to implement a Factory?

Hello everyone,

I’ve been trying to implement my own Factory based on what the suggested in this thread
According to that, I would be able to create my own asset in the content browser and populate it with my own data (I hope I’m assuming correctly)

Anyways, I’ve been trying to implement the methods required in order to work properly, I tried overriding the method ShouldShowInNewMenu() making it return true, then it compiled correctly, opened the editor and as soon as I click Create new asset in the content browser, go to the Miscellaneous category it crashes horribly with a screen error in VS saying “UE4Editor-CoreUObject.pdb not loaded” somehow that tells me I’m going in the right path but I have no idea what’s going on.

I really don’t know how to implement the factory, any help or advice is greatly appreciated, thanks.

.

I made a little progress, instead of overriding the “ShouldShowInNewMenu” method, I overrode the “CanCreateNew” method making it return true, now when I click on Create new asset->Miscellaneous, the name of my new Factory appears, but when I click on it nothing happens, it doesn’t create a new asset, what am I missing? it should call the “FactoryCreateNew” method but it’s not getting called.

Depending of the nature of the asset you’re trying to add, UDataAsset might be simpler for you to use. Assets deriving from UDataAsset are automatically gathered and added to a list so you only have to choose New Asset > Data Asset > Your Asset Type instead of creating a full blown factory. Factories are mostly useful if you want to really customize instantiation of your asset type.

But for what it’s worth, we also have some trivial factories set up (basically only because our other programmer wasn’t aware of UDataAsset) and it doesn’t seem require overriding anything beyond FactoryCreateNew:



UMyGameObjectFactory::UMyGameObjectFactory(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	SupportedClass = UMyGameObject::StaticClass();

	bCreateNew = true;
	bEditorImport = true;
	bEditAfterNew = true;
}

UObject* UMyGameObjectFactory::FactoryCreateNew( UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn )
{
	return ConstructObject<UMyGameObject>( UMyGameObject::StaticClass(), InParent, InName, Flags );
}


Thank you for your answer, I didn’t know about UDataAsset I’m gonna look up for info about it.
About the snippet of code you put, have you tested it? Does it work the way I was saying, I mean, does it let you create an Asset in the Content Browser with that class or how are you using it exactly? Because my implementation looks almost exactly like that and somehow the FactoryCreateNew method never gets called.

Still I’m gonna try the UDataAsset thing, maybe it fits to my needs. Basically I need an Asset in the content browser that lets the designers edit an array of a struct with a lot of properties.

I forgot about a bunch more boilerplate – you also have to create a corresponding FAssetAction:


class FAssetTypeActions_MyGameObject : public FAssetTypeActions_Base
{
public:
	// IAssetTypeActions Implementation
	virtual FText GetName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_MyGameObject", "My Game Object"); }
	virtual FColor GetTypeColor() const override { return FColor( 175, 0, 128 ); }
	virtual UClass* GetSupportedClass() const override { return UMyGameObject::StaticClass(); }
	virtual uint32 GetCategories() override { return EAssetTypeCategories::Gameplay; }
};


And register it in your editor module:



void FMyGameEditorModule::StartupModule()
{
	// Register asset types
	IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
	{
		TSharedRef<IAssetTypeActions> Action = MakeShareable( new FAssetTypeActions_MyGameObject );
		AssetTools.RegisterAssetTypeActions( Action );
	}
}

I think that’s all. The asset action tells the asset browser where and how your asset type is displayed in the new asset menu, then the engine combs through UFactory classes to find one that supports the same class.

Basically, this boilerplate is why I opt for data assets when I can. :slight_smile:

1 Like

Yeah now I understand why you pointed me to UDataAsset. I created a class and extended it to UDataAsset and now I can create a DataAsset in the Content Browser using my class and fill all the data I needed, so it was so simple that way.
And yes, it looks like Factories are meant for more complicated stuff, I’ll probably give it a try later, for now I’ll stick with UDataAsset, that did the trick!
Thank you very much .