icon
11장 : 고급 주제와 최신 기술

에디터 확장과 커스텀 툴


이전 절에서 우리는 언리얼 엔진의 플러그인 개발을 통해 엔진의 기능을 확장하는 방법을 살펴보았습니다. 플러그인 개발의 중요한 영역 중 하나는 바로 언리얼 에디터(Unreal Editor) 자체를 확장하고 커스텀 툴을 개발하는 것입니다. 에디터 확장은 개발 워크플로우를 크게 개선하고, 반복적인 작업을 자동화하며, 팀의 생산성을 비약적으로 향상시킬 수 있는 강력한 기능입니다.

이번 절에서는 언리얼 에디터의 확장성 개념을 이해하고, 커스텀 툴을 개발하기 위한 다양한 방법과 핵심 API들에 대해 자세히 알아보겠습니다.


에디터 확장성의 중요성

언리얼 에디터는 기본적으로 매우 강력한 기능을 제공하지만, 모든 프로젝트의 특정 요구사항을 충족하기는 어렵습니다.

  • 워크플로우 최적화: 프로젝트 특유의 반복적인 작업을 자동화하여 시간을 절약하고 오류를 줄입니다.
  • 생산성 향상: 개발자가 더 효율적으로 작업할 수 있는 맞춤형 환경을 제공합니다.
  • 특정 콘텐츠 관리: 게임의 특정 데이터나 에셋을 효율적으로 생성, 수정, 관리할 수 있는 전용 툴을 만듭니다.
  • 팀 협업 강화: 팀 내에서 공유 가능한 표준화된 툴을 제공하여 협업을 원활하게 합니다.
  • 엔진 기능 확장: 에디터 수준에서 새로운 기능을 추가하거나 기존 엔진 기능을 재정의합니다.

에디터 확장은 주로 C++ 플러그인을 통해 이루어지지만, 간단한 유틸리티는 블루프린트나 Python 스크립트로도 구현할 수 있습니다.


에디터 확장 유형

언리얼 에디터를 확장할 수 있는 방법은 다양합니다.

메뉴 및 툴바 확장

  • FExtensibilityManager, FMenuBuilder, FToolBarBuilder: 에디터의 메인 메뉴, 툴바, 컨텍스트 메뉴(우클릭 메뉴)에 새로운 항목이나 버튼을 추가하여 커스텀 기능을 실행합니다.
  • Commands: 커스텀 명령을 정의하고 키보드 단축키와 연결할 수 있습니다.

커스텀 에셋 에디터

  • IAssetTypeActions: 새로운 에셋 타입(예: 커스텀 데이터 에셋)을 만들거나, 기존 에셋 타입에 대한 커스텀 에디터(Asset Editor)를 구현하여 해당 에셋의 편집 경험을 완전히 제어합니다.
  • UFactory를 사용하여 새로운 에셋을 생성하는 팩토리를 정의할 수 있습니다.

커스텀 패널/탭 (Slate UI)

  • SDockTab, SCompoundWidget: 에디터 내부에 새로운 독립적인 창이나 패널을 생성하여 복잡한 커스텀 UI와 기능을 제공합니다. 언리얼 엔진의 UI 프레임워크인 Slate를 사용하여 인터페이스를 구축합니다.
  • FGlobalTabManager를 통해 탭을 에디터에 등록합니다.

디테일 패널 커스터마이징

  • IDetailCustomization: 액터나 컴포넌트의 디테일 패널(Details Panel)에 표시되는 속성(Property)을 커스터마이징합니다. 특정 속성을 숨기거나, 표시 순서를 변경하거나, 커스텀 위젯을 추가하여 편집 경험을 개선할 수 있습니다.
  • IPropertyTypeCustomization: 특정 구조체나 클래스 타입의 모든 인스턴스에 대한 디테일 패널 표시 방식을 전역적으로 변경합니다.

모드 및 뷰포트 오버레이

  • FEdMode: 뷰포트에서 상호작용하는 새로운 에디터 모드를 생성합니다 (예: 랜드스케이프 모드와 유사). 특정 유형의 에셋을 선택하고 편집하는 데 특화된 툴을 만들 수 있습니다.
  • FViewportClient: 뷰포트에 커스텀 시각화나 기즈모(Gizmo)를 그려서 디버깅 정보를 표시하거나 편집 도구를 제공합니다.

데이터 관리 및 자동화

  • UnrealEd 모듈: 에디터 전용 함수를 포함하며, 에셋 로딩/저장, 액터 생성/삭제, 레벨 변경 등 다양한 에디터 작업을 스크립트나 코드에서 수행할 수 있습니다.
  • Python 스크립팅: 언리얼 엔진 4.23부터 Python 스크립팅을 지원합니다. 복잡한 작업 자동화, 데이터 임포트/익스포트, 배치 처리 등에 유용합니다.
  • 블루프린트 유틸리티 위젯 (Blueprint Utility Widget): 간단한 에디터 툴을 블루프린트로 빠르게 만들 수 있습니다. 데이터 유효성 검사, 에셋 일괄 처리 등에 사용됩니다.

에디터 확장 개발을 위한 핵심 API/모듈

에디터 확장은 주로 EditorUnrealEd 모듈의 기능에 의존합니다.

  • UnrealEd: 에디터 핵심 기능 대부분이 포함된 모듈입니다. 에셋 로딩/저장, 트랜잭션, 월드 관리 등.
  • Slate / SlateCore: 언리얼 에디터 자체의 UI를 구성하는 데 사용되는 UI 프레임워크입니다. 커스텀 패널이나 위젯을 만들 때 필수적입니다.
  • PropertyEditor: 디테일 패널 커스터마이징(IDetailCustomization, IPropertyTypeCustomization)에 사용됩니다.
  • ToolMenus: 언리얼 엔진 5부터 메뉴 및 툴바 확장을 위해 도입된 새로운 시스템입니다. FToolMenuOwner, FToolMenuSection 등을 사용하여 보다 유연하게 메뉴를 구성할 수 있습니다.
  • EditorStyle: 에디터의 표준 스타일과 아이콘에 접근하여 일관된 UI를 만듭니다.

에디터 확장 개발 워크플로우 (C++ 기반)

새 에디터 플러그인 생성: 11장 1절에서 다룬 것처럼 New Plugin 대화 상자에서 Editor Standalone Window 템플릿을 선택하거나, 기존 플러그인에 에디터 모듈을 추가합니다.

  • 플러그인 .uplugin 파일에 Type: "Editor"로 설정된 모듈을 추가하고 LoadingPhase: "Default" 또는 PostEngineInit으로 설정합니다.

Build.cs 설정: 에디터 모듈의 Build.cs 파일에 PublicDependencyModuleNames.AddRangeUnrealEd, Slate, SlateCore, EditorStyle, PropertyEditor, ToolMenus 등 필요한 모듈을 추가합니다.

모듈 StartupModule() 구현

  • IMyEditorPluginModule::StartupModule() 함수에서 커스텀 UI 생성, 메뉴/툴바 등록, 디테일 패널 커스터마이징 등록 등의 초기화 작업을 수행합니다.
  • 메뉴/툴바 추가 예시 (UE5 ToolMenus)
MyEditorPluginModule.cpp의 StartupModule()
FGlobalToolMenuDelegate::Get().AddMainMenuExtension(
    FName("File"), // 확장할 메뉴 이름
    FExecuteAction::CreateRaw(this, &FMyEditorPluginModule::AddMyPluginMenuEntry)
);
MyEditorPluginModule.cpp
void FMyEditorPluginModule::AddMyPluginMenuEntry(FMenuBuilder& MenuBuilder)
{
    MenuBuilder.BeginSection("MyPluginSection", LOCTEXT("MyPluginSection", "My Plugin Tools"));
    MenuBuilder.AddMenuEntry(FMyPluginCommands::Get().MyAction, NAME_None, LOCTEXT("MyActionLabel", "Do My Action"));
    MenuBuilder.EndSection();
}

FMyPluginCommandsTCommands를 상속받아 커스텀 명령을 정의합니다.

  • 커스텀 탭 등록 예시 (Slate UI):
MyEditorPluginModule.cpp 의 StartupModule()
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(
    MyPluginTabName, // 고유한 탭 이름
    FOnSpawnTab::CreateRaw(this, &FMyEditorPluginModule::SpawnMyPluginTab)
)
.SetDisplayName(LOCTEXT("MyPluginTabTitle", "My Plugin Window"))
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "PlacementBrowser.TabIcon"));

SpawnMyPluginTab 함수는 SNew(SMyCustomWidget) 등으로 커스텀 Slate 위젯을 반환합니다.

모듈 ShutdownModule() 구현: StartupModule()에서 등록한 모든 확장 기능을 해제하고 리소스를 정리합니다.

C++ 코드 컴파일 및 에디터 재시작: 솔루션 파일을 다시 생성하고 빌드한 후 에디터를 재시작하여 변경 사항을 확인합니다.


블루프린트 유틸리티 위젯 (Blutility)

간단한 에디터 툴이나 배치 작업을 빠르게 구현해야 할 경우, 블루프린트 유틸리티 위젯(Blutility)이 매우 유용합니다.

  • 생성 방법: Content Browser에서 Add New -> Blueprint Class -> All Classes에서 Editor Utility Widget 또는 Editor Utility Blueprint를 검색하여 생성합니다.
  • 기능 구현: 일반 UMG 위젯처럼 UI를 구성하고, 이벤트 그래프에서 에디터 전용 노드(Editor Utilities 카테고리)를 사용하여 에셋 접근, 액터 조작, 파일 입출력 등 다양한 작업을 수행합니다.
  • 실행: Content Browser에서 생성된 유틸리티 위젯을 마우스 오른쪽 버튼으로 클릭하고 Run Editor Utility Widget을 선택하여 실행합니다. 또는 에디터의 Window -> Editor Utility Widgets 메뉴에 등록하여 사용할 수 있습니다.
  • 장점: 코딩 없이 빠르게 툴을 만들 수 있고, 프로토타이핑에 매우 적합합니다.
  • 단점: C++ 플러그인만큼 강력하거나 유연하지는 않으며, 복잡한 UI나 성능이 중요한 로직에는 한계가 있습니다.

Python 스크립팅

Python은 언리얼 에디터의 작업을 자동화하고 스크립팅하는 데 매우 강력한 도구입니다.

  • 활성화: Edit -> Plugins에서 Python Editor Script Plugin을 활성화합니다.
  • 스크립트 작성 및 실행
    • 에디터의 Output Log 창에서 Cmd 드롭다운 메뉴를 Python으로 변경하고 바로 Python 코드를 입력할 수 있습니다.
    • .py 파일을 작성하여 Content BrowserPython 폴더에 넣거나, File -> Execute Python Script를 통해 실행할 수 있습니다.
  • 가능한 작업
    • 에셋 임포트/익스포트 및 배치 처리.
    • 레벨의 액터 속성 일괄 변경.
    • 씬 데이터 분석 및 보고서 생성.
    • 커스텀 UI(PySide/PyQt 연동).
  • 장점: 비프로그래머(아티스트, 디자이너)도 쉽게 배울 수 있고, 외부 라이브러리(NumPy, SciPy 등)와 연동하여 강력한 데이터 처리 기능을 구현할 수 있습니다.
  • 단점: 런타임 게임 코드에는 직접적으로 사용될 수 없으며, 에디터 내에서만 작동합니다.

언리얼 에디터 확장과 커스텀 툴 개발은 개발자의 생산성을 혁신적으로 향상시킬 수 있는 고급 기술입니다. 메뉴 및 툴바 확장, 커스텀 에셋 에디터, Slate UI 기반의 커스텀 패널, 디테일 패널 커스터마이징 등 다양한 방법을 통해 프로젝트의 고유한 워크플로우에 최적화된 환경을 구축할 수 있습니다. C++ 플러그인, 블루프린트 유틸리티 위젯, Python 스크립팅 중 적절한 방법을 선택하여 강력한 커스텀 툴을 개발하고, 게임 개발의 효율성을 극대화하시길 바랍니다.