Skip to content

Instantly share code, notes, and snippets.

@SkylakeOfficial
Created January 16, 2024 11:54
Show Gist options
  • Select an option

  • Save SkylakeOfficial/eb65519e1803eaa1bd57eb60b5878edc to your computer and use it in GitHub Desktop.

Select an option

Save SkylakeOfficial/eb65519e1803eaa1bd57eb60b5878edc to your computer and use it in GitHub Desktop.
UE Editor module utility example
// Skylake 2023 all rights reserved
#pragma once
#include "CoreMinimal.h"
#include "MoviePipelinePrimaryConfig.h"
#include "Brushes/SlateBoxBrush.h"
#include "Engine/DeveloperSettings.h"
#include "AFPEditorSettings.generated.h"
/**
*
*/
struct FSlateBrush;
UCLASS(Config = "Game", defaultconfig, meta = (DisplayName = "AFPEditorSettings"))
class ARKNIGHTSFPEDITOR_API UAFPEditorSettings : public UDeveloperSettings
{
GENERATED_BODY()
public:
UPROPERTY(Config, EditAnywhere, Category = "编辑器放置侧边栏")
TArray<TSubclassOf<AActor>> ActorsPlacement;
UPROPERTY(Config, EditAnywhere, Category = "工具链", meta = (FilePathFilter = "exe", AbsolutePath))
FFilePath BlenderLocation;
UPROPERTY(config, EditAnywhere, Category = "施工地图", meta=(AllowedClasses="/Script/Engine.World"))
TArray<FSoftObjectPath> MapsUnderConstruction;
UPROPERTY(config, EditAnywhere, Category = "数值编辑", meta=(AllowedClasses = "/Script/Engine.DataTable"))
TArray<TSoftObjectPtr<UDataTable>> TablesToOpen;
UPROPERTY(config, EditAnywhere, Category = "数值编辑", meta=(AllowedClasses = "/Script/Engine.DataTable",FilePathFilter = "*.xlsx|*.xlsm", RelativePath))
TArray<FFilePath> ExcelsToOpen;
UPROPERTY(config, EditAnywhere, Category = "关卡缩略图")
TSoftObjectPtr<UMoviePipelinePrimaryConfig> MapThumbRenderConfig;
};
// Skylake 2023 all rights reserved
#include "ArknightsFPEditor.h"
#include "IPlacementModeModule.h"
#include "Styling/SlateStyle.h"
#include "Styling/SlateStyleRegistry.h"
#include "Slate/SlateGameResources.h"
#include "EditorStyleSet.h"
#include <string>
#include <windows.h>
#include "Editor/EditorEngine.h"
#include "Styling/SlateStyleMacros.h"
#include "Subsystems/UnrealEditorSubsystem.h"
#include "MoviePipelineEditorBlueprintLibrary.h"
#include "MoviePipelineQueueEngineSubsystem.h"
#include "MoviePipelinePIEExecutor.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "MoviePipelineOutputSetting.h"
#include "AssetImportTask.h"
#include "AssetToolsModule.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Widgets/Notifications/SNotificationList.h"
IMPLEMENT_GAME_MODULE(FArknightsFPEditorModule, ArknightsFPEditor);
DEFINE_LOG_CATEGORY(LogAFPEditor);
#define LOCTEXT_NAMESPACE "ArknightsFPEditor"
#define RootToContentDir StyleSet-> RootToContentDir
void FArknightsFPEditorModule::StartupModule()
{
SetupPlacementActors();
UAFPEditorSettings* EdSettings = GetMutableDefault<UAFPEditorSettings>();
EdSettings->OnSettingChanged().AddRaw(this, &FArknightsFPEditorModule::RefreshPlacementActors);
FInternationalization::Get().SetCurrentCulture(TEXT("zh-Hans-CN"));
SetupExtendIcons();
RegisterGameEditorMenus();
}
void FArknightsFPEditorModule::ShutdownModule()
{
CleanupPlacementActors();
FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSet);
StyleSet.Reset();
}
void FArknightsFPEditorModule::RefreshPlacementActors(UObject* Settings, FPropertyChangedEvent& event)
{
if (IPlacementModeModule::IsAvailable())
{
if (IPlacementModeModule::Get().GetRegisteredPlacementCategory("AFPActors"))
{
IPlacementModeModule::Get().UnregisterPlacementCategory("AFPActors");
const UAFPEditorSettings* EdSettings = GetDefault<UAFPEditorSettings>();
const FPlacementCategoryInfo Info(INVTEXT("AFP Actors"), FSlateIcon(FAppStyle::GetAppStyleSetName(), "PlacementBrowser.Icons.Basic"), "AFPActors",TEXT("AFPActors"), 1);
IPlacementModeModule::Get().RegisterPlacementCategory(Info);
if (!EdSettings->ActorsPlacement.IsEmpty())
{
for (int32 i = 0; i != EdSettings->ActorsPlacement.Num(); i++)
{
IPlacementModeModule::Get().RegisterPlaceableItem(Info.UniqueHandle, MakeShared<FPlaceableItem>(nullptr, FAssetData(EdSettings->ActorsPlacement[i])));
}
}
}
}
}
void FArknightsFPEditorModule::SetupPlacementActors()
{
const FPlacementCategoryInfo Info(INVTEXT("AFP Actors"), FSlateIcon(FAppStyle::GetAppStyleSetName(), "PlacementBrowser.Icons.Basic"), "AFPActors",TEXT("AFPActors"),
1);
const UAFPEditorSettings* EdSettings = GetDefault<UAFPEditorSettings>();
IPlacementModeModule& PlacementModeModule = IPlacementModeModule::Get();
PlacementModeModule.RegisterPlacementCategory(Info);
if (!EdSettings->ActorsPlacement.IsEmpty())
{
for (int32 i = 0; i != EdSettings->ActorsPlacement.Num(); i++)
{
PlacementModeModule.RegisterPlaceableItem(Info.UniqueHandle, MakeShared<FPlaceableItem>(nullptr, FAssetData(EdSettings->ActorsPlacement[i])));
}
}
}
void FArknightsFPEditorModule::CleanupPlacementActors()
{
if (IPlacementModeModule::IsAvailable())
{
IPlacementModeModule::Get().UnregisterPlacementCategory("AFPActors");
}
}
static bool CanLaunchBlender() { return FPaths::FileExists(*GetDefault<UAFPEditorSettings>()->BlenderLocation.FilePath); }
static void LaunchBlender_Clicked()
{
const FString BlenderExecutable = GetDefault<UAFPEditorSettings>()->BlenderLocation.FilePath;
const FString ExtraParam = " --app-template AFP";
if (FPaths::FileExists(BlenderExecutable))
{
//FWindowsPlatformProcess::CreateProc(*BlenderExecutable, nullptr, true, false, false, nullptr, 0, nullptr, nullptr);
std::string str_path = TCHAR_TO_UTF8(*BlenderExecutable);
std::string str_param = TCHAR_TO_UTF8(*ExtraParam);
std::wstring wstr_path;
std::wstring wstr_param;
wstr_path.assign(str_path.begin(), str_path.end());
wstr_param.assign(str_param.begin(), str_param.end());
ShellExecute(nullptr, L"open", wstr_path.c_str(), wstr_param.c_str(), nullptr, 0);
}
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(TEXT("Blender,启动!")));
NewNotification.ExpireDuration = 3.0;
NewNotification.bUseLargeFont = true;
NewNotification.Image = FSlateIcon("AFPExtendStyle", "AFP.BlenderLarge").GetIcon();
FSlateNotificationManager::Get().AddNotification(NewNotification);
}
static bool HasNoPlayWorld()
{
return GEditor->PlayWorld == nullptr;
}
static bool HaveMapsUnderConstruction()
{
return HasNoPlayWorld() && !GetDefault<UAFPEditorSettings>()->MapsUnderConstruction.IsEmpty();
}
static void OpenMap_Clicked(const FString MapPath)
{
if (ensure(MapPath.Len()))
{
GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OpenEditorForAsset(MapPath);
}
}
static TSharedRef<SWidget> GetMapsDropdown()
{
FMenuBuilder MenuBuilder(true, nullptr);
for (const FSoftObjectPath& Path : GetDefault<UAFPEditorSettings>()->MapsUnderConstruction)
{
if (!Path.IsValid())
{
continue;
}
const FText DisplayName = FText::FromString(Path.GetAssetName());
MenuBuilder.AddMenuEntry(
DisplayName,
LOCTEXT("OpenMapDesc", "打开施工中的地图"),
FSlateIcon(),
FUIAction(
FExecuteAction::CreateStatic(&OpenMap_Clicked, Path.ToString()),
FCanExecuteAction::CreateStatic(&HasNoPlayWorld),
FIsActionChecked(),
FIsActionButtonVisible::CreateStatic(&HasNoPlayWorld)
)
);
}
return MenuBuilder.MakeWidget();
}
static void EditNumerics_Clicked()
{
const UAFPEditorSettings* Settings = GetDefault<UAFPEditorSettings>();
TArray<TSoftObjectPtr<UDataTable>> Datatables = Settings->TablesToOpen;
TArray<UObject*> LoadedTables;
for (auto Table : Datatables)
{
UObject* Loaded = Table.LoadSynchronous();
if (Loaded)
{
LoadedTables.Add(Loaded);
}
}
UAssetEditorSubsystem* AssetEditor = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
AssetEditor->OpenEditorForAssets(LoadedTables);
TArray<FFilePath> Excels = Settings->ExcelsToOpen;
for (FFilePath Excel : Excels)
{
FString StrPath = Excel.FilePath;
if (FPaths::FileExists(*StrPath))
{
StrPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*StrPath);
std::string str_path = TCHAR_TO_UTF8(*StrPath);
std::wstring wstr_path;
wstr_path.assign(str_path.begin(), str_path.end());
ShellExecute(nullptr, nullptr, wstr_path.c_str(), nullptr, nullptr, SW_SHOW);
}
}
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(TEXT("Excel,启动!")));
NewNotification.bUseLargeFont = true;
NewNotification.Image = FSlateIcon("AFPExtendStyle", "AFP.ExcelLarge").GetIcon();
NewNotification.ExpireDuration = 3.0;
FSlateNotificationManager::Get().AddNotification(NewNotification);
}
static void SwapLanguage_Clicked()
{
FString Culture = FInternationalization::Get().GetCurrentCulture()->GetName();
FString Lang = TEXT("中文");
if (Culture == TEXT("zh-Hans-CN"))
{
FInternationalization::Get().SetCurrentCulture(TEXT("en-US"));
Lang = TEXT("英文");
}
else
{
FInternationalization::Get().SetCurrentCulture(TEXT("zh-Hans-CN"));
}
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(FString::Printf(TEXT("切换界面语言到%s"), *Lang)));
NewNotification.ExpireDuration = 3.0;
NewNotification.Image = FSlateIcon("AFPExtendStyle", "AFP.Languages").GetIcon();
FSlateNotificationManager::Get().AddNotification(NewNotification);
}
void FArknightsFPEditorModule::CaptureMapThumb_Clicked()
{
UMoviePipelinePrimaryConfig* RenderConfig = GetDefault<UAFPEditorSettings>()->MapThumbRenderConfig.LoadSynchronous();
if (!RenderConfig)
{
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(TEXT("渲染失败。\n请填入默认MRQ渲染设置。")));
NewNotification.ExpireDuration = 3.0;
FSlateNotificationManager::Get().AddNotification(NewNotification);
return;
}
//Get sequence
UWorld* ActiveWorld = GEditor->GetEditorSubsystem<UUnrealEditorSubsystem>()->GetEditorWorld();
ThisMapName = ActiveWorld->GetMapName();
ThisMapPath = ActiveWorld->GetPathName();
ThisMapPath = FPaths::GetPath(ThisMapPath);
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FAssetData> SequenceAssets;
AssetRegistryModule.Get().GetAssetsByClass(ULevelSequence::StaticClass()->GetClassPathName(), SequenceAssets);
ULevelSequence* Sequence = nullptr;
for (FAssetData Data : SequenceAssets)
{
FString Path = FPaths::GetPath(Data.GetObjectPathString());
if (FPaths::IsSamePath(Path, ThisMapPath))
{
Sequence = Cast<ULevelSequence>(Data.GetAsset());
break;
}
}
if (!Sequence)
{
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(TEXT("当前世界路径内不存在Sequence,请创建以渲染")));
NewNotification.ExpireDuration = 3.0;
FSlateNotificationManager::Get().AddNotification(NewNotification);
return;
}
UMoviePipelineQueueEngineSubsystem* MoviePipelineQueueEngineSubsystem = GEngine->GetEngineSubsystem<UMoviePipelineQueueEngineSubsystem>();
UMoviePipelineQueue* ActiveQueue = MoviePipelineQueueEngineSubsystem->GetQueue();
ActiveQueue->DeleteAllJobs();
auto ThisJob = ActiveQueue->AllocateNewJob(UMoviePipelineExecutorJob::StaticClass());
ThisJob->Sequence = Sequence;
ThisJob->Map = ActiveWorld;
ThisJob->Author = "Skylake";
RenderConfig->FindSetting<UMoviePipelineOutputSetting>()->bFlushDiskWritesPerShot = true;
ThisJob->SetConfiguration(RenderConfig);
if (!Exec)
{
Exec = NewObject<UMoviePipelinePIEExecutor>();
Exec->AddToRoot();
Exec->OnIndividualShotWorkFinished().AddRaw(this, &FArknightsFPEditorModule::OnThumbRenderComplete);
}
MoviePipelineQueueEngineSubsystem->RenderQueueWithExecutorInstance(Exec);
}
void FArknightsFPEditorModule::RegisterGameEditorMenus()
{
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar.PlayToolBar");
FToolMenuSection& Section = Menu->AddSection("AFPExtensions", TAttribute<FText>(), FToolMenuInsert("Play", EToolMenuInsertType::After));
FToolMenuEntry LaunchBlender = FToolMenuEntry::InitToolBarButton(
"LaunchBlender",
FUIAction(
FExecuteAction::CreateStatic(&LaunchBlender_Clicked),
FCanExecuteAction::CreateStatic(CanLaunchBlender),
FIsActionChecked(),
FIsActionButtonVisible::CreateStatic(CanLaunchBlender)),
LOCTEXT("LaunchBlenderButton", "启动Blender"),
LOCTEXT("LaunchBlenderDesc", "启动预设置的Blender实例"),
FSlateIcon("AFPExtendStyle", "AFP.Blender")
);
LaunchBlender.StyleNameOverride = "CalloutToolbar";
Section.AddEntry(LaunchBlender);
FToolMenuEntry MapShortcut = FToolMenuEntry::InitComboButton(
"OpenMap",
FUIAction(
FExecuteAction(),
FCanExecuteAction::CreateStatic(&HasNoPlayWorld),
FIsActionChecked(),
FIsActionButtonVisible::CreateStatic(&HaveMapsUnderConstruction)),
FOnGetContent::CreateStatic(&GetMapsDropdown),
LOCTEXT("OpenmapButton", "施工地图"),
LOCTEXT("OpenMapDesc", "打开施工中的地图"),
FSlateIcon("AFPExtendStyle", "AFP.Maps")
);
MapShortcut.StyleNameOverride = "CalloutToolbar";
Section.AddEntry(MapShortcut);
FToolMenuEntry EditNumerics = FToolMenuEntry::InitToolBarButton(
"EditNumerics",
FUIAction(
FExecuteAction::CreateStatic(&EditNumerics_Clicked),
FCanExecuteAction::CreateLambda([=] { return true; }),
FIsActionChecked(),
FIsActionButtonVisible::CreateLambda([=] { return true; })),
LOCTEXT("EditNumericsButton", "编辑游戏数值"),
LOCTEXT("EditNumericsDesc", "打开收藏品数值的编辑工具"),
FSlateIcon("AFPExtendStyle", "AFP.Numerics")
);
EditNumerics.StyleNameOverride = "CalloutToolbar";
Section.AddEntry(EditNumerics);
FToolMenuEntry SwapLanguage = FToolMenuEntry::InitToolBarButton(
"SwapLanguage",
FUIAction(
FExecuteAction::CreateStatic(&SwapLanguage_Clicked),
FCanExecuteAction::CreateLambda([=] { return true; }),
FIsActionChecked(),
FIsActionButtonVisible::CreateLambda([=] { return true; })),
LOCTEXT("SwapLanguageButton", "中/英"),
LOCTEXT("SwapLanguageDesc", "切换中英文"),
FSlateIcon("AFPExtendStyle", "AFP.Languages")
);
SwapLanguage.StyleNameOverride = "CalloutToolbar";
Section.AddEntry(SwapLanguage);
FToolMenuEntry CaptureMapThumb = FToolMenuEntry::InitToolBarButton(
"CaptureMapThumb",
FUIAction(
FExecuteAction::CreateRaw(this, &FArknightsFPEditorModule::CaptureMapThumb_Clicked),
FCanExecuteAction::CreateStatic(&HasNoPlayWorld),
FIsActionChecked(),
FIsActionButtonVisible::CreateLambda([=] { return true; })),
LOCTEXT("CaptureMapThumbButton", "更新地图缩略图"),
LOCTEXT("CaptureMapThumbDesc", "更新地图缩略图"),
FSlateIcon("AFPExtendStyle", "AFP.Camera")
);
CaptureMapThumb.StyleNameOverride = "CalloutToolbar";
Section.AddEntry(CaptureMapThumb);
}
void FArknightsFPEditorModule::SetupExtendIcons()
{
FString ExtendAssetPath = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::ProjectContentDir() + TEXT("EditorUtils/Icons/")));
StyleSet = MakeShareable(new FSlateStyleSet("AFPExtendStyle"));
StyleSet->SetContentRoot(FPaths::ProjectContentDir() / TEXT("EditorUtils/Icons/"));
StyleSet->Set("AppIcon", new IMAGE_BRUSH("EditorIcon", FVector2D(48.0)));
StyleSet->Set("AFP.Blender", new IMAGE_BRUSH("Blender", FVector2D(64.0f)));
StyleSet->Set("AFP.BlenderLarge", new IMAGE_BRUSH("Blender", FVector2D(240.0f)));
StyleSet->Set("AFP.Maps", new IMAGE_BRUSH("Maps", FVector2D(64.0f)));
StyleSet->Set("AFP.Numerics", new IMAGE_BRUSH("Numerics", FVector2D(64.0f)));
StyleSet->Set("AFP.Languages", new IMAGE_BRUSH("Languages", FVector2D(64.0f)));
StyleSet->Set("AFP.Excel", new IMAGE_BRUSH("Excel", FVector2D(64.0f)));
StyleSet->Set("AFP.ExcelLarge", new IMAGE_BRUSH("Excel", FVector2D(240.0f)));
StyleSet->Set("AFP.Camera", new IMAGE_BRUSH("Camera", FVector2D(64.0f)));
StyleSet->Set("AFP.CameraLarge", new IMAGE_BRUSH("Camera", FVector2D(240.0f)));
StyleSet->Set("ClassThumbnail.AFPEnemySpawnerActor", new IMAGE_BRUSH("Spawner", FVector2D(64.0f)));
StyleSet->Set("ClassThumbnail.AFPEnemySpawnerEditor", new IMAGE_BRUSH("Spawner", FVector2D(64.0f)));
// Setup black Tooltip.
StyleSet->Set("ToolTip.BrightBackground", new BOX_BRUSH("Tooltip", FMargin(0.25f)));
StyleSet->Set("Documentation.ToolTip.Background", new BOX_BRUSH("", FMargin(4 / 16.0f), FLinearColor()));
// Setting the text style doesn't work. I don't know why.
FTextBlockStyle DocContentStyle = FTextBlockStyle(); //FAppStyle::GetWidgetStyle<FTextBlockStyle>("Documentation.Content");
DocContentStyle.SetColorAndOpacity(FSlateColor(FLinearColor::White));
DocContentStyle.SetFont(DEFAULT_FONT("Regular", 12));
DocContentStyle.SetColorAndOpacity(FSlateColor(FLinearColor::White));
StyleSet->Set("Documentation.Content", DocContentStyle);
StyleSet->Set("Documentation.NumberedContent", DocContentStyle);
StyleSet->Set("Documentation.BoldContent", DocContentStyle.SetTypefaceFontName(TEXT("Bold")));
StyleSet->Set("Documentation.SDocumentationTooltip", DocContentStyle.SetTypefaceFontName(TEXT("Bold")));
StyleSet->Set("Documentation.SDocumentationTooltipSubdued", DocContentStyle);
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet);
}
void FArknightsFPEditorModule::OnThumbRenderComplete(FMoviePipelineOutputData Results)
{
if (!Results.bSuccess)
{
return;
}
if (Results.ShotData.IsEmpty())
{
return;
}
TMap<FMoviePipelinePassIdentifier, FMoviePipelineRenderPassOutputData> Data = Results.ShotData[0].RenderPassData;
TArray<FMoviePipelinePassIdentifier> Keys;
Data.GetKeys(Keys);
FString SourceFilePath = Data[Keys[0]].FilePaths[0];
FString TexturePath = ThisMapPath / "MapThumb_" + ThisMapName + ".MapThumb_" + ThisMapName;
UTexture2D* TextureAsset = LoadObject<UTexture2D>(nullptr, *TexturePath, nullptr, LOAD_None, nullptr);
if (TextureAsset)
{
if (FReimportManager::Instance()->Reimport(TextureAsset, true, false, SourceFilePath))
{
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(FString::Printf(TEXT("地图缩略图已从 %s 重新导入到 %s "), *SourceFilePath, *ThisMapPath)));
NewNotification.ExpireDuration = 3.0;
NewNotification.Image = FSlateIcon("AFPExtendStyle", "AFP.CameraLarge").GetIcon();
FSlateNotificationManager::Get().AddNotification(NewNotification);
}
}
else
{
//如果没有文件存在,导入
UAssetImportTask* ThumbnailImportTask = NewObject<UAssetImportTask>();
ThumbnailImportTask->bAsync = false;
ThumbnailImportTask->bSave = true;
ThumbnailImportTask->bReplaceExisting = true;
ThumbnailImportTask->bReplaceExistingSettings = false;
ThumbnailImportTask->Filename = SourceFilePath;
ThumbnailImportTask->DestinationPath = ThisMapPath;
ThumbnailImportTask->DestinationName = "MapThumb_" + ThisMapName;
FAssetToolsModule* AssetTools = FModuleManager::LoadModulePtr<FAssetToolsModule>("AssetTools");
AssetTools->Get().ImportAssetTasks({ThumbnailImportTask});
if (ThumbnailImportTask->GetObjects().Num() > 0)
{
FNotificationInfo NewNotification = FNotificationInfo(FText::FromString(FString::Printf(TEXT("地图缩略图已从 %s 导入到 %s "), *SourceFilePath, *ThisMapPath)));
NewNotification.ExpireDuration = 3.0;
NewNotification.Image = FSlateIcon("AFPExtendStyle", "AFP.CameraLarge").GetIcon();
FSlateNotificationManager::Get().AddNotification(NewNotification);
}
}
}
#undef RootToContentDir
#undef LOCTEXT_NAMESPACE
// Skylake 2023 all rights reserved
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "Modules/ModuleInterface.h"
#include "AFPEditorSettings.h"
#include "MoviePipelinePIEExecutor.h"
#include "UnrealEd.h"
#include "Containers/Ticker.h"
DECLARE_LOG_CATEGORY_EXTERN(LogAFPEditor, Log, All);
class FArknightsFPEditorModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
void RefreshPlacementActors(UObject* Settings, struct FPropertyChangedEvent& event);
static void SetupPlacementActors();
static void CleanupPlacementActors();
void RegisterGameEditorMenus();
static void SetupExtendIcons();
public:
void OnThumbRenderComplete(FMoviePipelineOutputData Results);
void CaptureMapThumb_Clicked();
private:
static inline TSharedPtr<FSlateStyleSet> StyleSet = nullptr;
UMoviePipelinePIEExecutor* Exec = nullptr;
FString ThisMapPath;
FString ThisMapName;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment