PART 5 · 강의 2/3
커스텀 에셋 에디터
FAssetEditorToolkit으로 커스텀 에셋 전용 에디터 UI를 구축합니다
01
FAssetEditorToolkit 개요
에셋 에디터의 프레임워크 이해하기
블루프린트 에디터, 머티리얼 에디터 같은 전용 에디터는 모두 FAssetEditorToolkit을 기반으로 합니다. 탭 매니저로 레이아웃을 구성하고, 툴바와 메뉴를 커스터마이징합니다.
| 구성 요소 | 역할 |
|---|---|
FAssetEditorToolkit | 에셋 에디터의 기본 프레임워크 |
FTabManager | 탭 레이아웃 관리 (도킹, 분할) |
FToolBarBuilder | 에디터 전용 툴바 |
IDetailsView | 프로퍼티 편집 패널 |
02
에셋 에디터 구현
Dialogue Tree 전용 에디터 만들기
FDialogueTreeEditor.h
#pragma once
#include "Toolkits/AssetEditorToolkit.h"
class FDialogueTreeEditor
: public FAssetEditorToolkit
{
public:
void InitEditor(
const EToolkitMode::Type Mode,
const TSharedPtr<IToolkitHost>& Host,
UDialogueTree* InTree);
// FAssetEditorToolkit
virtual FName GetToolkitFName() const override
{ return "DialogueTreeEditor"; }
virtual FText GetBaseToolkitName() const override
{ return LOCTEXT("Name", "Dialogue Tree Editor"); }
virtual FString GetWorldCentricTabPrefix() const override
{ return "DialogueTree"; }
virtual FLinearColor GetWorldCentricTabColorScale()
const override
{ return FLinearColor(0.0f, 0.8f, 1.0f); }
// 탭 레이아웃 정의
virtual void RegisterTabSpawners(
const TSharedRef<FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(
const TSharedRef<FTabManager>& TabManager) override;
private:
TSharedRef<SDockTab> SpawnDetailsTab(
const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnNodeListTab(
const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnPreviewTab(
const FSpawnTabArgs& Args);
UDialogueTree* EditingTree = nullptr;
TSharedPtr<IDetailsView> DetailsView;
static const FName DetailsTabId;
static const FName NodeListTabId;
static const FName PreviewTabId;
};
FDialogueTreeEditor.cpp (핵심 부분)
const FName FDialogueTreeEditor::DetailsTabId("Details");
const FName FDialogueTreeEditor::NodeListTabId("NodeList");
const FName FDialogueTreeEditor::PreviewTabId("Preview");
void FDialogueTreeEditor::InitEditor(
const EToolkitMode::Type Mode,
const TSharedPtr<IToolkitHost>& Host,
UDialogueTree* InTree)
{
EditingTree = InTree;
// 기본 탭 레이아웃 정의
const TSharedRef<FTabManager::FLayout> Layout =
FTabManager::NewLayout("DialogueTreeEditorLayout_v1")
->AddArea(
FTabManager::NewPrimaryArea()
->SetOrientation(Orient_Horizontal)
->Split(
FTabManager::NewStack()
->SetSizeCoefficient(0.3f)
->AddTab(NodeListTabId, ETabState::OpenedTab))
->Split(
FTabManager::NewStack()
->SetSizeCoefficient(0.4f)
->AddTab(PreviewTabId, ETabState::OpenedTab))
->Split(
FTabManager::NewStack()
->SetSizeCoefficient(0.3f)
->AddTab(DetailsTabId, ETabState::OpenedTab))
);
// 에디터 초기화
InitAssetEditor(Mode, Host,
FName("DialogueTreeEditorApp"),
Layout,
true, // bCreateDefaultStandaloneMenu
true, // bCreateDefaultToolbar
InTree);
}
void FDialogueTreeEditor::RegisterTabSpawners(
const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::RegisterTabSpawners(InTabManager);
InTabManager->RegisterTabSpawner(
DetailsTabId,
FOnSpawnTab::CreateSP(
this, &FDialogueTreeEditor::SpawnDetailsTab))
.SetDisplayName(LOCTEXT("Details", "Details"))
.SetIcon(FSlateIcon(
FAppStyle::GetAppStyleSetName(),
"LevelEditor.Tabs.Details"));
InTabManager->RegisterTabSpawner(
NodeListTabId,
FOnSpawnTab::CreateSP(
this, &FDialogueTreeEditor::SpawnNodeListTab))
.SetDisplayName(LOCTEXT("Nodes", "Node List"));
InTabManager->RegisterTabSpawner(
PreviewTabId,
FOnSpawnTab::CreateSP(
this, &FDialogueTreeEditor::SpawnPreviewTab))
.SetDisplayName(LOCTEXT("Preview", "Preview"));
}
TSharedRef<SDockTab> FDialogueTreeEditor::SpawnDetailsTab(
const FSpawnTabArgs& Args)
{
// 디테일 뷰 생성
FPropertyEditorModule& PropModule =
FModuleManager::GetModuleChecked<FPropertyEditorModule>(
"PropertyEditor");
FDetailsViewArgs ViewArgs;
ViewArgs.bAllowSearch = true;
ViewArgs.bHideSelectionTip = true;
DetailsView = PropModule.CreateDetailView(ViewArgs);
DetailsView->SetObject(EditingTree);
return SNew(SDockTab)
.Label(LOCTEXT("Details", "Details"))
[
DetailsView.ToSharedRef()
];
}
03
AssetTypeActions에서 에디터 열기
더블클릭으로 커스텀 에디터 실행하기
C++ - OpenAssetEditor 구현
void FDialogueTreeTypeActions::OpenAssetEditor(
const TArray<UObject*>& InObjects,
TSharedPtr<IToolkitHost> EditWithinLevelEditor)
{
EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid()
? EToolkitMode::WorldCentric
: EToolkitMode::Standalone;
for (UObject* Obj : InObjects)
{
UDialogueTree* Tree =
Cast<UDialogueTree>(Obj);
if (Tree)
{
TSharedRef<FDialogueTreeEditor> Editor(
new FDialogueTreeEditor());
Editor->InitEditor(
Mode, EditWithinLevelEditor, Tree);
}
}
}
04
에디터 툴바 커스터마이징
에셋 에디터 전용 툴바 버튼 추가
C++ - 에디터 툴바
// InitEditor에서 툴바 확장 등록
void FDialogueTreeEditor::InitEditor(...)
{
// ... InitAssetEditor 호출 후 ...
// 에디터 전용 툴바 확장
TSharedPtr<FExtender> ToolbarExtender =
MakeShareable(new FExtender);
ToolbarExtender->AddToolBarExtension(
"Asset",
EExtensionHook::After,
GetToolkitCommands(),
FToolBarExtensionDelegate::CreateSP(
this,
&FDialogueTreeEditor::BuildToolbar));
AddToolbarExtender(ToolbarExtender);
RegenerateMenusAndToolbars();
}
void FDialogueTreeEditor::BuildToolbar(
FToolBarBuilder& Builder)
{
Builder.AddSeparator();
Builder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(
this,
&FDialogueTreeEditor::OnValidateTree)),
NAME_None,
LOCTEXT("Validate", "Validate"),
LOCTEXT("ValidateTip", "Validate dialogue tree"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),
"Icons.Check"));
Builder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(
this,
&FDialogueTreeEditor::OnExportJSON)),
NAME_None,
LOCTEXT("Export", "Export JSON"),
LOCTEXT("ExportTip", "Export as JSON file"),
FSlateIcon(FAppStyle::GetAppStyleSetName(),
"Icons.Save"));
}
레이아웃 저장/복원
FTabManager::NewLayout에 전달하는 레이아웃 이름에 버전 접미사(예: _v1)를 붙이면 레이아웃이 변경될 때 사용자의 저장된 레이아웃을 리셋할 수 있습니다. 버전을 올리면 새 기본 레이아웃이 적용됩니다.
SUMMARY
핵심 요약
- FAssetEditorToolkit은 커스텀 에셋 전용 에디터의 프레임워크이며, 탭 레이아웃, 툴바, 메뉴를 제공합니다
- FTabManager::NewLayout으로 탭의 분할 구조(Details, Node List, Preview 등)를 정의합니다
- IDetailsView로 UObject의 프로퍼티를 자동으로 편집 가능한 패널을 생성합니다
- FAssetTypeActions::OpenAssetEditor에서 커스텀 에디터를 생성하여 더블클릭으로 열 수 있게 합니다
- 에디터 전용 툴바 버튼으로 Validate, Export 같은 에셋별 작업을 제공합니다
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: FAssetEditorToolkit으로 에셋 에디터 생성
FAssetEditorToolkit을 상속받아 커스텀 에셋(UMyQuestData)을 더블클릭하면 열리는 전용 에디터를 만드세요. 기본 레이아웃에 프로퍼티 에디터(FPropertyEditorModule)와 프리뷰 패널을 배치하세요.
실습 2: 에셋 에디터 툴바와 메뉴
커스텀 에셋 에디터에 Save, Validate, Export 버튼이 포함된 툴바를 추가하세요. Save 시 에셋을 저장하고, Validate 시 데이터 무결성을 검사하며, Export 시 JSON으로 내보내는 기능을 구현하세요.
심화 과제: 노드 그래프 에셋 에디터
SGraphEditor를 활용하여 노드 기반 비주얼 에디터를 구현하세요. 대화 시스템이나 AI 행동 트리처럼 노드를 연결하여 흐름을 편집할 수 있는 에셋 에디터를 만드세요.