跳至主要內容

ED09.EdGraph|序

Mr.Si大约 3 分钟u++

导言

头像
Dada!资产编辑器的框架是有了,但好像少点东西,默认的那个图表去哪里了?
头像

因为咱们用的是FWorkflowCentricApplication不是内建蓝图编辑器子类( FBlueprintEditor)

头像
好吧,那咱们怎么把这玩意加回来?
头像
莫慌,待老夫慢慢道来。

UEdGraph 系统结构

UEdGraph

头像

图表的容器,包含了所有节点UEdGraphNode

UEdGraphNode

头像

图表中的每个节点(Node)都是 UEdGraphNode 或其子类。

UEdGraphPin

头像

每个 Node 上的引脚

UEdGraphSchema

头像

可以理解成一个管家 ,负责管理图的规则(哪些可以连、不能连,右键菜单、拖拽连线)

头像

为什么没有一个专门的连线对象

头像

每一根线其实是两个 UEdGraphPin 互相关联

PinA->LinkedTo.Add(PinB);
PinB->LinkedTo.Add(PinA);

实践

1.派生三剑客

UCLASS()
class XXX_EDITOR_API USuperComboGraphEdGraph : public UEdGraph
{
	GENERATED_BODY()
};

2.派生UEdGraphNode

UCLASS()
class XXX_EDITOR_API USuperComboGraphEdGraphNode : public UEdGraphNode
{
	GENERATED_BODY()
};

3.派生UEdGraphSchema

UCLASS()
class XXX_EDITOR_API USuperComboGraphEdSchema : public UEdGraphSchema
{
	GENERATED_BODY()
};

4. 要显示图表的类中缓存图表指针

UCLASS()
class UXXX : public UObject
{
	GENERATED_BODY()
public:
#if WITH_EDITORONLY_DATA
	// 图表资源保存点
	UPROPERTY()
	TObjectPtr<UEdGraph> EditorGraph;
#endif	
};
头像

看的我一脸懵逼!为什么要写一个UEdGraph指针

头像

为了让你的图表作为资产的一部分被序列化保存下来,否则编辑器里画的所有连线和节点会在关闭编辑器后全部丢失。

5. 类内写上CreateGraph函数

void UXXX::CreateGraph()
{
	if (EditorGraph == nullptr)
	{
		EditorGraph = USoundCue::GetSoundCueAudioEditor()->CreateNewSoundCueGraph(this);
		EditorGraph->bAllowDeletion = false;
		
		const UEdGraphSchema* Schema = EditorGraph->GetSchema();
		Schema->CreateDefaultNodesForGraph(*EditorGraph);
	}
}
头像

这一步也可以放在AssetEditor类中。

头像

但我看很多官方模板类似SoundCue都是直接写在类内的

头像

两种写法各有千秋,不过写在类内记得加#if WITH_EDITOR ,我个人习惯上还是放在AssetEditor类中,毕竟Editor模块更解耦。

6.创建 GraphEditor 控件(UI)

.h
/** 你要显示图表的指针 */
TObjectPtr<USuperComboGraph> SuperComboGraphObj;

/**图表指针*/
TSharedPtr<SGraphEditor> GraphEditorWidget;

7.挂载 SDockTabLayout

头像

无论是类内还是类外写初始化函数,都需要在AssetEditor类中挂载到Layout中才会显示。

具体注册方法我们上一篇已经讲了,这里只做简单描述

//1.注册ID
static const FName CombGraphTabId;

//2.生成对应的标签页
TSharedRef<SDockTab> SpawnTab_SuperComboGraph(const FSpawnTabArgs& Args) const;

TSharedRef<SDockTab> FSuperComboGraphAssetsEditor::SpawnTab_SuperComboGraph(const FSpawnTabArgs& Args) const
{
	check( Args.GetTabId() == CombGraphTabId );

	return SNew(SDockTab)
		.Label(LOCTEXT("SuperComboGraphTitle", "Super Combo Graph"))
		[
			GraphEditorWidget.ToSharedRef()
		];
}

//3.通过ID组除生成的标签页
void FSuperComboGraphAssetsEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& Manager)
{
	/*注册工作区的菜单分类*/
	WorkspaceMenuCategory = Manager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_SuperComboGraph", "Super ComboGraph "));
	const auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();

	/*注册自定义的标签页(Tab)*/
	FAssetEditorToolkit:: RegisterTabSpawners(Manager);
	
	/*Graph / 画布*/
	Manager->RegisterTabSpawner( CombGraphTabId, FOnSpawnTab::CreateSP(this, &FSuperComboGraphAssetsEditor::SpawnTab_SuperComboGraph) )
			.SetDisplayName( LOCTEXT("CombGraphTab", "CombGraphTab") )
			.SetGroup(WorkspaceMenuCategoryRef)
			.SetIcon(FSlateIcon(FSuperCombGraphEditorStyle::GetStyleSetName(), "SiGaoHe.Main"));
}

//4.添加到标签页
InitAssetEditor(Mode,InitToolkitHost,TEXT("SuperComboGraphEditor"),CreateEditorLayout(),true,true,ObjectToEdit,false);