Developers Club geek daily blog

2 years, 6 months ago
Creation of the type of an asset in Unreal Engine 4 and customization of a property bar

My name is Dmitry. I am engaged in creation of computer games on Unreal Engine as a hobby. Today I would like to tell as in Unreal Engine to create the type of an asset and how to add an additional element on a property bar of an asset. So we will begin.

Let's begin with creation of an asset. First it is necessary to create a class for the asset.

UCLASS()
class UICUSTOM_API UMyObject : public UObject
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, Category = "My Object Properties")
		FString Name;

};

After that it is necessary that ours asst it was displayed in content the browser for this purpose we create the descendant for the class UFactory:

UCLASS()
class UICUSTOM_API UMyObjectFactory : public UFactory
{
	GENERATED_UCLASS_BODY()

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

Here for us the most important method is FactoryCreateNew which creates a copy of our class.

UObject* UMyObjectFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
	UMyObject* NewObjectAsset = NewObject<UMyObject>(InParent,Class, Name, Flags | RF_Transactional);
	
	return NewObjectAsset;
}

So ours asst it is already possible to create in content the browser but it is impossible to select not the name, not color of an icon, not category eventually. For all this it is necessary to create one more class, the descendant of FAssetTypeActions_Base.

class UICUSTOM_API FMyObjectAssetAction : public FAssetTypeActions_Base
{
public:
	virtual FText GetName() const override;
	virtual FColor GetTypeColor() const override;
	virtual UClass* GetSupportedClass() const override;
	virtual bool HasActions(const TArray<UObject*>&InObjects) const override { return false; }
	virtual uint32 GetCategories() override;
	static void RegistrateCustomPartAssetType();
};

In the principle everything is clear according to the name of methods except the RegistrateCustomPartAssetType method (). This method is necessary for registration of this class. So from where it to cause? This method has to be called once when loading the editor therefore the most suitable place for his challenge is the designer of GameMode. Here actually and it:

AUICustomGameMode::AUICustomGameMode()
{
#if WITH_EDITORONLY_DATA
	FMyClassDetails::RegestrateCostumization();
	FMyObjectAssetAction::RegistrateCustomPartAssetType();
#endif //WITH_EDITORONLY_DATA
}

After that it is possible to compile the project and to enjoy result:

Creation of the type of an asset in Unreal Engine 4 and customization of a property bar

You likely ask. And what sense in it, I can create in the same way blyuprint which will inherit MyObject, it will turn out most but without hemorrhoids too. Here it is necessary to specify what blyuprint is a class the successor of MyObject but not him.

For example if to place the reference to MyObject in any other asset that created thus asst you will be able to select, and blyuprint for which this asst is basic is not present.

Creation of the type of an asset in Unreal Engine 4 and customization of a property bar

As you see asst is, and there is no blyuprint.

Now we will pass to adding of elements to a property bar of an asset. For this purpose we will create an experimental class:

UCLASS()
class UICUSTOM_API ATestAct : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ATestAct();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		UMyObject* MyObject;
	
};

To customize its property bar it is necessary to create a class the successor of IDetailCustomization:

class FMyClassDetails : public IDetailCustomization
{
public:
	static FReply MClick(IDetailLayoutBuilder* DetailBuilder);

	/** Makes a new instance of this detail layout class for a specific detail view requesting it */
	static TSharedRef<IDetailCustomization> MakeInstance();

	static void RegestrateCostumization();

	/** IDetailCustomization interface */
	virtual void CustomizeDetails(IDetailLayoutBuilder&DetailBuilder) override;

	static void ShowNotification(FText Text, SNotificationItem::ECompletionState State = SNotificationItem::CS_None);

	static ATestAct* GetObject(IDetailLayoutBuilder* DetailBuilder);
};

So I explain: A method which will work when we will press MClick the added button (as an example I selected the button, but it can be any element of the interface).

CustomizeDetails a method in which there is adding of a new element on a panel of parts:

void FMyClassDetails::CustomizeDetails(IDetailLayoutBuilder&DetailBuilder)
{
	// Create a category so this is displayed early in the properties
	ATestAct* TestAct = GetObject(&DetailBuilder;);
	IDetailCategoryBuilder&MyCategory = DetailBuilder.EditCategory("Button", FText::GetEmpty(), ECategoryPriority::Important);
	
	//You can get properties using the detailbuilder
	//MyProperty= DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(MyClass, MyClassPropertyName));

	FText TestHUDText = FText::FromString("Your Text");
	MyCategory.AddCustomRow(TestHUDText)
		.ValueContent() //NameContent()
		[
			SNew(SButton)
			.Text(FText::FromString("ShowMessage"))
			.OnClicked(FOnClicked::CreateStatic(&FMyClassDetails;::MClick, &DetailBuilder;))
		];
	
}

RegestrateCostumization Method necessary for registration of this customization. (You likely noticed his challenge from the designer of GameMode) there is a wish to note that TestAct needs to be entered without A prefix:

void FMyClassDetails::RegestrateCostumization()
{
	FPropertyEditorModule&PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");

	//Custom detail views
	PropertyModule.RegisterCustomClassLayout("TestAct", FOnGetDetailCustomizationInstance::CreateStatic(&FMyClassDetails;::MakeInstance));
}

ShowNotification Simply displays the message. GetObject Allows to receive the link to the customized object (ATestAct in this case).

So, here what we have as a result:

Creation of the type of an asset in Unreal Engine 4 and customization of a property bar

Thanks for attention, I hope, this lesson will allow you to create even more best and interesting games. The project with source codes can be downloaded here.

This article is a translation of the original post at habrahabr.ru/post/274159/
If you have any questions regarding the material covered in the article above, please, contact the original author of the post.
If you have any complaints about this article or you want this article to be deleted, please, drop an email here: sysmagazine.com@gmail.com.

We believe that the knowledge, which is available at the most popular Russian IT blog habrahabr.ru, should be accessed by everyone, even though it is poorly translated.
Shared knowledge makes the world better.
Best wishes.

comments powered by Disqus