ue-editor-tools

Use when extending the Unreal Editor with editor tool, editor utility widget, Blutility, detail customization, property customization, editor mode, asset editor, editor subsystem, editor extension, UToolMenus, or scripted asset operations. For Slate fundamentals, see ue-ui-umg-slate. For module buil

By quodsoler · 937 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-editor-tools

Source repository · Upstream listing

UE Editor Tools Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use". Editor extensions live in a module with "Type": "Editor" and depend on UnrealEd , Slate , SlateCore , PropertyEditor (detail panels), ToolMenus (menus and toolbars), EditorSubsystem ( UEditorSubsystem ), Blutility (editor utility widgets and scripted actions), AssetTools and AssetDefinition (Content Browser asset types). None of these may be referenced unconditionally from a Runtime module (engine runtime modules add them only under if (Target.bBuildEditor) plus if WITH EDITOR , e.g. AIModule.Build.cs:31 34 ). Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code. Request is about… Go to Creating the editor module, Build.cs, registration lifecycle [Editor Module Setup]( editor module setup) Custom property panel for a class or struct [Detail Customizations]( detail customizations) UMG panel run inside the editor, right click asset/actor actions [Editor Utility Widgets and Scripted Actions]( editor utility widgets and scripted actions) Main menu, toolbar, context menu entries, commands [Menus and Toolbars]( menus and toolbars) Editor lifetime singleton, GEditor GetEditorSubsystem<T () [Editor Subsystems]( editor subsystems) Undo/redo, marking objects dirty, reacting to editor events [Transactions and Editor Delegates]( transactions and editor delegates) Viewport mode with custom interaction or tools [Editor Modes]( editor modes) Content Browser type colour, category, factory, thumbnail [Asset Types Factories and Thumbnails]( asset types factories and thumbnails) Tabbed asset editor window [Asset Editor Toolkits]( asset editor toolkits) Validating assets on save or in CI [Data Validation]( data validation) Editor Module Setup .uproject (or .uplugin ) module entry — Default is enough for detail customizations and UToolMenus::RegisterStartupCallback menus ( CommonUIEditor registers its detail customizations at Default ); use PostEngineInit when StartupModule itself needs GEditor or other engine initialised state: Declare the module class, define both lifecycle functions, then place IMPLEMENT MODULE last: RegisterMenus and OpenMyPanel are defined under [Menus and Toolbars]( menus and toolbars). FRegisterCustomClassLayoutParams carries TOptional<int32 OptionalOrder ; set it when two modules customize the same class and the order matters, otherwise pass a default constructed struct. Directory layout, WITH EDITOR guards, factories, thumbnails, toolkits and the full mode boilerplate: [editor module setup.md](references/editor module setup.md). Detail Customizations IDetailCustomization replaces the whole details panel layout for a UClass . IPropertyTypeCustomization replaces the row for a USTRUCT or instanced object property. Both are registered from StartupModule as shown above. The single argument override does the layout work: EditCategory , GetProperty , AddProperty , AddCustomRow , HideProperty , GetObjectsBeingCustomized — full bodies in the reference below. The USTRUCT counterpart, FMyRangeCustomization : public IPropertyTypeCustomization , overrides CustomizeHeader(TSharedRef<IPropertyHandle PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) and CustomizeChildren(TSharedRef<IPropertyHandle PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils) . Key interfaces (all in Engine/Source/Editor/PropertyEditor/Public ): Type Header What you call IDetailLayoutBuilder DetailLayoutBuilder.h EditCategory , HideCategory , GetProperty , HideProperty , AddPropertyToCategory , GetObjectsBeingCustomized , GetSelectedObjects , ForceRefreshDetails , RegisterInstancedCustomPropertyTypeLayout IDetailCategoryBuilder DetailCategoryBuilder.h AddProperty , AddCustomRow , AddCustomBuilder , AddGroup , AddExternalObjects , SetSortOrder , InitiallyCollapsed ( IDetailChildrenBuilder in IDetailChildrenBuilder.h offers the same five adders, plus AddExternalStructure , inside CustomizeChildren ) FDetailWidgetRow DetailWidgetRow.h NameContent() , ValueContent() , WholeRowContent() , ExtensionContent() , FilterString , Visibility , IsEnabled IPropertyHandle PropertyHandle.h GetValue / SetValue overloads, GetNumChildren , GetChildHandle , SetOnPropertyValueChanged , SetOnChildPropertyValueChanged , CreatePropertyNameWidget , CreatePropertyValueWidget , EnumerateRawData , NotifyPreChange , NotifyPostChange IDetailPropertyRow IDetailPropertyRow.h DisplayName , ToolTip , EditCondition , IsEnabled , Visibility , GetDefaultWidgets , CustomWidget PropertyCustomizationHelpers PropertyCustomizationHelpers.h MakeAddButton , MakeRemoveButton , MakeClearButton , MakeBrowseButton , MakeUseSelectedButton , MakePropertyComboBox , SObjectPropertyEntryBox , SClassPropertyEntryBox GetValue / SetValue return FPropertyAccess::Result ( Success , Fail , MultipleValues ). NotifyPostChange takes EPropertyChangeType::Type , e.g. EPropertyChangeType::ValueSet . ECategoryPriority::Type sorts top down: Variable , Transform , Important , TypeSpecific , Default , Uncommon . Full row patterns, CustomizeHeader / CustomizeChildren bodies, SObjectPropertyEntryBox , per object value enumeration and fonts: [detail customization patterns.md](references/detail customization patterns.md). Editor Utility Widgets and Scripted Actions UEditorUtilityWidget ( EditorUtilityWidget.h , module Blutility ) is a UUserWidget that runs in the editor. Subclass in C++ to expose helper functions, then build the visuals in a Blueprint child. UEditorUtilityLibrary ( EditorUtilityLibrary.h , Blutility ) also provides GetSelectedAssetData() , GetSelectedAssetsOfClass(UClass ) , GetSelectionSet() (level actors) and SyncBrowserToFolders(const TArray<FString &) . Open a widget Blueprint from code through UEditorUtilitySubsystem ( EditorUtilitySubsystem.h ): UEditorUtilitySubsystem call Effect SpawnAndRegisterTab(UEditorUtilityWidgetBlueprint ) Registers the tab and opens it; returns the UEditorUtilityWidget SpawnAndRegisterTabAndGetID(UEditorUtilityWidgetBlueprint , FName& OutTabID) / SpawnAndRegisterTabWithId(UEditorUtilityWidgetBlueprint , FName InTabID) Same, writing back or supplying the tab id RegisterTabAndGetID(UEditorUtilityWidgetBlueprint , FName& OutTabID) Registers the spawner without opening the tab TryRun(UObject Asset) Runs a UEditorUtilityObject derived asset (invokes its Run ) Scripted actions: any UFUNCTION(CallInEditor) on a UAssetActionUtility subclass appears in the Content Browser context menu; UActorActionUtility does the same for level actors. Both derive from UEditorUtilityObject . Filter with the SupportedClasses array ( TArray<TSoftClassPtr<UObject , editable in Class Defaults); read it back with GetSupportedClasses() . The editor builds these menus without loading the utility asset, from asset registry tags wrapped by FAssetActionUtilityPrototype ( EditorUtilityAssetPrototype.h ). Keep the filter in SupportedClasses on the CDO rather than computing it at run time. Menus and Toolbars UToolMenus (module ToolMenus ) owns every editor menu and toolbar. Register from the startup callback so Slate and the menus you extend exist. Call Use UToolMenus::Get() / UToolMenus::TryGet() Singleton; TryGet does not force the module to load RegisterMenu(FName Name, FName Parent = NAME None, EMultiBoxType Type = EMultiBoxType::Menu, bool bWarnIfAlreadyRegistered = true) Declare a menu you own ExtendMenu(FName) Add to a menu someone else owns; queues an extension if it is not registered yet FindMenu(FName) Look up a registered menu; nullptr if absent UToolMenu::FindOrAddSection(FName) / AddSection(FName, Label, FToolMenuInsert) Get or create a section FToolMenuSection::AddMenuEntry(FName, Label, ToolTip, FSlateIcon, FToolUIActionChoice, EUserInterfaceActionType, FName TutorialHighlight, TOptional<FText InputBindingOverride) Menu item FToolMenuSection::AddSubMenu / AddSeparator / AddEntry Sub menus, separators, prebuilt entries FToolMenuEntry::InitToolBarButton / InitComboButton / InitWidget / InitMenuEntry Build entries to pass to AddEntry UToolMenus::RegisterStartupCallback(const FSimpleMulticastDelegate::FDelegate&) Defer registration until menus exist UToolMenus::UnRegisterStartupCallback(this) + UToolMenus::UnregisterOwner(this) Mandatory in ShutdownModule FToolMenuOwnerScoped tags everything created in its scope with the owner so UnregisterOwner removes it all. Useful menu names: LevelEditor.MainMenu.Window , LevelEditor.MainMenu.Tools , LevelEditor.LevelEditorToolBar.PlayToolBar , LevelEditor.LevelEditorToolBar.User , LevelEditor.ActorContextMenu , ContentBrowser.AssetContextMenu . Icons are FSlateIcon(FAppStyle::GetAppStyleSetName(), "StyleName") . Keyboard chords and reusable commands use TCommands with UI COMMAND ; see [editor module setup.md](references/editor module setup.md). Editor Subsystems UEditorSubsystem (module EditorSubsystem , header EditorSubsystem.h ) is auto instantiated once the owning module is loaded — there is no registration call. Reach it with GEditor GetEditorSubsystem<T () . UEditorSubsystem derives from UDynamicSubsystem ; Initialize(FSubsystemCollectionBase&) , Deinitialize() and ShouldCreateSubsystem(UObject Outer) const come from USubsystem , so always chain to Super:: . Engine editor subsystems worth calling before writing your own: Subsystem Module Use UEditorActorSubsystem UnrealEd GetAllLevelActors , GetSelectedLevelActors , SetSelectedLevelActors , SpawnActorFromClass , DestroyActor UEditorAssetSubsystem UnrealEd LoadAsset , RenameAsset , DuplicateAsset , DeleteAsset , SaveLoadedAsset , ListAssets UAssetEditorSubsystem UnrealEd OpenEditorForAsset , FindEditorForAsset , CloseAllEditorsForAsset , GetEditorModeInfoOrderedByPriority UEditorUtilitySubsystem Blutility SpawnAndRegisterTab , RegisterTabAndGetID , TryRun ULevelEditorSubsystem LevelEditor Level open/save/new operations The canonical subsystem type table (game instance, world, local player, engine, editor) lives in ue cpp foundations . Transactions and Editor Delegates Every editor mutation of a UObject must be wrapped in a transaction and preceded by Modify() , or undo restores stale data: FScopedTransaction ( ScopedTransaction.h , UnrealEd ) also offers Cancel() and IsOutstanding() . After a direct property write on an asset call MarkPackageDirty() and PostEditChange() . Delegate Signature FEditorDelegates::PostUndoRedo FSimpleMulticastDelegate FEditorDelegates::OnMapOpened (const FString& Filename, bool bAsTemplate) FEditorDelegates::PreBeginPIE / PostPIEStarted / EndPIE (const bool bIsSimulating) FEditorDelegates::OnAssetPostImport (UFactory , UObject ) FEditorDelegates::OnNewActorsPlaced (UObject , const TArray<AActor &) FEditorDelegates::OnPackageDeleted / OnAssetsPreDelete (UPack