UE4 有很多asset资源类型,如果定义自己的asset呢

创建一个空的插件

1. 在UE4引擎中创建一个空的Plugin结构

image

2. 定义一个自己类型的结构

在 Public 目录下创建一个自定义类型结构

#pragma once

#include "CoreMinimal.h"

#include "UObject/Object.h"
#include "UltimateSkillAsset.generated.h"

UCLASS(BlueprintType, Blueprintable)
class ULTIMATESKILL_API UUltimateSkillAsset : public UObject
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=NewAsset)
	int Value;
};

创建一个Editor Module

1. Editor Module 目录结构

image

2. 定义一个Module类

#include "AssetToolsModule.h"
#include "IAssetTools.h"
#include "IAssetTypeActions.h"
#include "AssetTools/UltimateSkillAssetActions.h"
#include "Modules/ModuleInterface.h"
#include "Templates/SharedPointer.h"
#include "Modules/ModuleManager.h"

#define LOCTEXT_NAMESPACE "FUltimateSkillEditorModule"

class FUltimateSkillEditorModule : public IModuleInterface
{
	virtual void StartupModule() override
	{
		RegisterAssetTools();
	}
	virtual void ShutdownModule() override
	{
		UnregisterAssetTools();
	}
	virtual bool SupportsDynamicReloading() override
	{
		return true;
	}

protected:
	void RegisterAssetTools()
	{
		IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
		RegisterAssetTypeAction(AssetTools, MakeShareable(new FUltimateSkillAssetActions()));
	}

	void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef<IAssetTypeActions> Action)
	{
		AssetTools.RegisterAssetTypeActions(Action);
		RegisteredAssetTypeActions.Add(Action);
	}

	void UnregisterAssetTools()
	{
		FAssetToolsModule* AssetToolsModule = FModuleManager::GetModulePtr<FAssetToolsModule>("AssetTools");
	
		if (AssetToolsModule != nullptr)
		{
			IAssetTools& AssetTools = AssetToolsModule->Get();
	
			for (auto Action : RegisteredAssetTypeActions)
			{
				AssetTools.UnregisterAssetTypeActions(Action);
			}
		}
	}

private:
	// /** The collection of registered asset type actions. */
	TArray<TSharedRef<IAssetTypeActions>> RegisteredAssetTypeActions;
};

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FUltimateSkillEditorModule, UltimateSkillEditor);

分析:

  1. 在文件头部需要定义 *#define LOCTEXT_NAMESPACE “FUltimateSkillEditorModule”*,与类名相同
  2. 在文件尾部定义Module名,在uplugin的文件中,需要指明加载该Module IMPLEMENT_MODULE(FUltimateSkillEditorModule, UltimateSkillEditor);
  3. 在uplugin加载该module, 改完uplugin后,需要关闭ide,重新生成vsproj 文件
    image

3. 定义一个 右键菜单类

定义一个 右键菜单类 FUltimateSkillAssetActions

FUltimateSkillAssetActions.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "AssetTypeActions_Base.h"

class ULTIMATESKILLEDITOR_API FUltimateSkillAssetActions : public FAssetTypeActions_Base
{
public:
	FUltimateSkillAssetActions();
	// void CreateBlueprint();

	public:
	//~ FAssetTypeActions_Base overrides
	virtual uint32 GetCategories() override;
	virtual FText GetName() const override;
	virtual  UClass* GetSupportedClass() const override;
	virtual FColor GetTypeColor() const override;

	virtual void GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder) override;
	virtual bool HasActions(const TArray<UObject*>& InObjects) const override;
};

FUltimateSkillAssetActions.

// Fill out your copyright notice in the Description page of Project Settings.


#include "UltimateSkillAssetActions.h"

#include "UltimateSkillAsset.h"
#include "Misc/MessageDialog.h"

#define LOCTEXT_NAMESPACE "AssetTypeActions"

FUltimateSkillAssetActions::FUltimateSkillAssetActions()
{
}

//资源的类型
uint32 FUltimateSkillAssetActions::GetCategories()
{
	return EAssetTypeCategories::Basic;
}

//资源的名字
FText FUltimateSkillAssetActions::GetName() const
{
	return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_UltimateSkillAsset", "Ultimate Skill Asset");
}

UClass* FUltimateSkillAssetActions::GetSupportedClass() const
{
	return UUltimateSkillAsset::StaticClass();
}
//资源颜色
FColor FUltimateSkillAssetActions::GetTypeColor() const
{
	return FColor::Blue;
}

void FUltimateSkillAssetActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder)
{
	FAssetTypeActions_Base::GetActions(InObjects, MenuBuilder);
	
	const auto NextAnimAssets = GetTypedWeakObjectPtrs<UUltimateSkillAsset>(InObjects);
	
	MenuBuilder.AddMenuEntry(
		LOCTEXT("NextAnimAsset_UltimateSkill", "Ultimate Skill"),
		LOCTEXT("NextAnimAsset_UltimateSkillTip", "Ultimate Skill Tip"),
		FSlateIcon(),
		FUIAction(
			FExecuteAction::CreateLambda([=]
			{
				//TODO
				// const FText DialogText = LOCTEXT("TODO", "待实现");
				// FMessageDialog::Open(EAppMsgType::Ok, DialogText);
			}),
			FCanExecuteAction::CreateLambda([=]
			{
				return true;
			})
		)
	);
}

bool FUltimateSkillAssetActions::HasActions(const TArray<UObject*>& InObjects) const
{
	return true;
}

#undef LOCTEXT_NAMESPACE
  1. 继承自FAssetTypeActions_Base
  2. 头部定义命名空间
    #define LOCTEXT_NAMESPACE "AssetTypeActions"
  3. 核心方法 GetActions
    1. InObjects: 为选中的资源对象,由于可能同时选择多个,所以返回的是数组
    2. 可将InObjects 转为 自定义的Asset
      const auto NextAnimAssets = GetTypedWeakObjectPtrs<UUltimateSkillAsset>(InObjects);
    3. MenuBuilder: 添加右键菜单显示的item及其点击的action

4. 定义一个 创建资源的类

UFactory: 所有在Content中创建的资源都集成UFactory, 在你点击Content空白处,确定资源时,会调用UFactory创建这个资源在内存中

UltimateSkillFactoryNew.h

#pragma once

#include "CoreMinimal.h"

#include "Factories/Factory.h"
#include "UltimateSkillFactoryNew.generated.h"

UCLASS()
class ULTIMATESKILLEDITOR_API UUltimateSkillFactoryNew : public UFactory
{
	GENERATED_UCLASS_BODY()

public:
	virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
	virtual bool ShouldShowInNewMenu() const override;
};

UltimateSkillFactoryNew.cpp

#include "UltimateSkillFactoryNew.h"
#include "UltimateSkillAsset.h"

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


UObject* UUltimateSkillFactoryNew::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName,
	EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
	return NewObject<UUltimateSkillAsset>(InParent, InClass, InName, Flags);
}

bool UUltimateSkillFactoryNew::ShouldShowInNewMenu() const
{
	return true;
}

5. 在EditorModule中注册Actions

IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
RegisterAssetTypeAction(AssetTools, MakeShareable(new FUltimateSkillAssetActions()));

Github Code

https://github.com/hulefei/ue4-plugins/tree/main/UltimateSkill