Cannot Compile Custom Factory With ClassPicker

Hi guys,

I tried to implement my own asset factory which basically worked fine. But now I want to get a class picker like in the UDataAssetFactory. I just copied the code and changed the specific things which needed changing. Afterwards I added the ClassViewer-Module to my project dependencies and all includes (hopefully but doubtful) correct

Unfortunately the project will not build. I post the whole output log at the end.
I think there is something wrong with my module dependencies or includes. But I cannot figure out what. If somebody can give me a hint how to setup the dependencies and includes for the editor correctly I might be thankful.

Thanks and best regards,
Julian

My project dependencies:

		PublicDependencyModuleNames.AddRange(
            new string[] {
                "Core",
                "CoreUObject",
                "Engine",
                "InputCore",
                "UnrealEd",
                "ClassViewer"
            });

My factory header file:

#pragma once

#include "Object.h"
#include "UnrealEd.h"
#include "BaseAttribute.h"
#include "BaseAttributeFactory.generated.h"

UCLASS()
class UBaseAttributeFactory : public UFactory
{
	GENERATED_UCLASS_BODY()

	UPROPERTY(EditAnywhere, Category = DataAsset)
	TSubclassOf<UBaseAttribute> AttributeClass;

	// UFactory interface
	virtual bool ConfigureProperties() override;
	virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
	// End of UFactory interface
};

My factory cpp-file:

#include "WeltenwandererSaga.h"

#include "BaseAttribute.h"

#include "../ClassViewer/Public/ClassViewerFilter.h"
#include "../ClassViewer/Public/ClassViewerModule.h"
#include "SClassPickerDialog.h"

#include "BaseAttributeFactory.h"

/////////////////////////////////////////////////////
// UBaseAttributeFactory

class FAttributeParentFilter : public IClassViewerFilter
{
public:
	/** All children of these classes will be included unless filtered out by another setting. */
	TSet< const UClass* > AllowedChildrenOfClasses;

	/** Disallowed class flags. */
	uint32 DisallowedClassFlags;

	virtual bool IsClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const UClass* InClass, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override
	{
		return !InClass->HasAnyClassFlags(DisallowedClassFlags)
			&& InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InClass) != EFilterReturn::Failed;
	}

	virtual bool IsUnloadedClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const TSharedRef< const IUnloadedBlueprintData > InUnloadedClassData, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override
	{
		return !InUnloadedClassData->HasAnyClassFlags(DisallowedClassFlags)
			&& InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InUnloadedClassData) != EFilterReturn::Failed;
	}
};

UBaseAttributeFactory::UBaseAttributeFactory(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	bCreateNew = true;
	bEditAfterNew = true;
	SupportedClass = UBaseAttribute::StaticClass();
}

bool UBaseAttributeFactory::ConfigureProperties()
{
	// nullptr the DataAssetClass so we can check for selection
	AttributeClass = NULL;

	// Load the classviewer module to display a class picker
	FClassViewerModule& ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");

	// Fill in options
	FClassViewerInitializationOptions Options;
	Options.Mode = EClassViewerMode::ClassPicker;

	TSharedPtr<FAttributeParentFilter> Filter = MakeShareable(new FAttributeParentFilter);
	Options.ClassFilter = Filter;

	Filter->DisallowedClassFlags = CLASS_Abstract | CLASS_Deprecated | CLASS_NewerVersionExists;
	Filter->AllowedChildrenOfClasses.Add(UBaseAttribute::StaticClass());

	const FText TitleText = FText::FromString("Pick Attribute Class"); //LOCTEXT("CreateDataAssetOptions", "Pick Data Asset Class");
	UClass* ChosenClass = nullptr;
	const bool bPressedOk = SClassPickerDialog::PickClass(TitleText, Options, ChosenClass, UBaseAttribute::StaticClass());
	if (bPressedOk)
	{
		AttributeClass = ChosenClass;
	}

	return bPressedOk;
}

UObject* UBaseAttributeFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
	if (AttributeClass != NULL)
	{
		return CastChecked<UBaseAttribute>(StaticConstructObject(AttributeClass, InParent, Name, Flags | RF_Transactional));
	}
	else
	{
		// if we have no attribute class, use the passed-in class instead
		check(Class->IsChildOf(UBaseAttribute::StaticClass()));
		return CastChecked<UBaseAttribute>(StaticConstructObject(Class, InParent, Name, Flags | RF_Transactional));
	}
}

Finally the output error log:

1>------ Build started: Project: WeltenwandererSaga, Configuration: DebugGame_Editor x64 ------
2>------ Skipped Build: Project: UE4, Configuration: BuiltWithUnrealBuildTool Win32 ------
2>Project not selected to build for this solution configuration 
1>  Performing 2 actions (4 in parallel)
1>  BaseAttributeFactory.cpp
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(17): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(17): error C2143: syntax error : missing ',' before '&'
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(26): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(26): error C2143: syntax error : missing ',' before '&'
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\UnrealEd\Public\Kismet2\SClassPickerDialog.h(31): error C2065: 'FClassPickerDefaults' : undeclared identifier
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\UnrealEd\Public\Kismet2\SClassPickerDialog.h(31): error C2923: 'TSharedPtr' : 'FClassPickerDefaults' is not a valid template type argument for parameter 'ObjectType'
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\UnrealEd\Public\Kismet2\SClassPickerDialog.h(68): error C2065: 'FClassPickerDefaults' : undeclared identifier
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\UnrealEd\Public\Kismet2\SClassPickerDialog.h(68): error C2923: 'TSharedPtr' : 'FClassPickerDefaults' is not a valid template type argument for parameter 'ObjectType'
1>D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\UnrealEd\Public\Kismet2\SClassPickerDialog.h(68): error C3203: 'TSharedPtr' : unspecialized class template can't be used as a template argument for template parameter 'InElementType', expected a real type
1>D:\Unreal Engine\Weltenwanderer-Saga Project\Source\WeltenwandererSaga\AttributeSystem\BaseAttributeFactory.cpp(27): warning C4263: 'bool FAttributeParentFilter::IsClassAllowed(const FClassViewerInitializationOptions &,const UClass *,TSharedRef<FClassViewerFilterFuncs,0>)' : member function does not override any base class virtual member function
1>D:\Unreal Engine\Weltenwanderer-Saga Project\Source\WeltenwandererSaga\AttributeSystem\BaseAttributeFactory.cpp(38): warning C4264: 'bool IClassViewerFilter::IsClassAllowed(const int)' : no override available for virtual member function from base 'IClassViewerFilter'; function is hidden
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(17) : see declaration of 'IClassViewerFilter::IsClassAllowed'
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(6) : see declaration of 'IClassViewerFilter'
1>D:\Unreal Engine\Weltenwanderer-Saga Project\Source\WeltenwandererSaga\AttributeSystem\BaseAttributeFactory.cpp(33): warning C4263: 'bool FAttributeParentFilter::IsUnloadedClassAllowed(const FClassViewerInitializationOptions &,const TSharedRef<const IUnloadedBlueprintData,0>,TSharedRef<FClassViewerFilterFuncs,0>)' : member function does not override any base class virtual member function
1>D:\Unreal Engine\Weltenwanderer-Saga Project\Source\WeltenwandererSaga\AttributeSystem\BaseAttributeFactory.cpp(38): warning C4264: 'bool IClassViewerFilter::IsUnloadedClassAllowed(const int)' : no override available for virtual member function from base 'IClassViewerFilter'; function is hidden
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(26) : see declaration of 'IClassViewerFilter::IsUnloadedClassAllowed'
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(6) : see declaration of 'IClassViewerFilter'
1>D:\Unreal Engine\Weltenwanderer-Saga Project\Source\WeltenwandererSaga\AttributeSystem\BaseAttributeFactory.cpp(60): error C2259: 'FAttributeParentFilter' : cannot instantiate abstract class
1>          due to following members:
1>          'bool IClassViewerFilter::IsClassAllowed(const int)' : is abstract
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(17) : see declaration of 'IClassViewerFilter::IsClassAllowed'
1>          'bool IClassViewerFilter::IsUnloadedClassAllowed(const int)' : is abstract
1>          D:\Unreal Engine\Unreal Engine\4.7\Engine\Source\Editor\BspMode\../ClassViewer/Public/ClassViewerFilter.h(26) : see declaration of 'IClassViewerFilter::IsUnloadedClassAllowed'
1>  -------- End Detailed Actions Stats -----------------------------------------------------------
1>ERROR : UBT error : Failed to produce item: D:\Unreal Engine\Weltenwanderer-Saga Project\Binaries\Win64\UE4Editor-WeltenwandererSaga-Win64-DebugGame.pdb
1>  Cumulative action seconds (4 processors): 0,00 building projects, 16,13 compiling, 0,00 creating app bundles, 0,00 generating debug info, 0,00 linking, 0,00 other
1>  UBT execution time: 23,81 seconds
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ""D:\Unreal Engine\Unreal Engine\4.7\Engine\Build\BatchFiles\Build.bat" WeltenwandererSagaEditor Win64 DebugGame "D:\Unreal Engine\Weltenwanderer-Saga Project\WeltenwandererSaga.uproject" -rocket" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========

Hi,

after some time I found the correct dependencies (v4.7):

#include "../Public/ClassViewerModule.h"
#include "../Public/ClassViewerFilter.h"
#include "../../Classes/Preferences/UnrealEdOptions.h"
#include "../Kismet2/SClassPickerDialog.h"

In addition, you need in your header file:

#include "UnrealEd.h"

And finally, you need the correct package dependencies of “UnrealEd” and “ClassViewer”.

Best regards,
Julian

Well, there is one additional information I want to share with whoever is interested (just copied it from my source code comment):

// When importing assets from the file-system, the function AssetTools::ImportAsset will be
// called. This function handles the asset creation process.
// AssetTools::ImportAsset will call
//	UObject// Result = UFactory::StaticImportObject( /.../ );
// UFactory::StaticImportObject will call
//	if(CanCreateNew)		FactoryCreateNew
//	else if(bTextImport)	FactoryCreateText
//	else					FactoryCreateBinary
//
// This means, a factory can either create a new asset by the content browser or create a
// new asset by a text file or a binary file.