下面是自己在學(xué)習(xí)編輯器界面開(kāi)發(fā)學(xué)習(xí)內(nèi)容的總結(jié),有錯(cuò)誤的地方希望大家指出,謝謝~
學(xué)習(xí)的教程為:https://www.bilibili.com/video/BV1M84y1K7m4
創(chuàng)建空編輯器插件
新添加一個(gè)編輯器的插件,修改插件的設(shè)定,"Type": 從Runtime改為Editor,"LoadingPhase": "Default"改為PreDefault
此處參考文檔:https://blog.csdn.net/pp1191375192/article/details/103139304/
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "SuperManager",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "SuperManager",
"Type": "Editor",
"LoadingPhase": "PreDefault"
}
]
}
新建類(lèi)繼承AssetActionUtility并添加至插件目錄

添加后報(bào)錯(cuò),少引入模塊

在cs文件中添加指定的模塊"Blutility",繼續(xù)添加私有模塊
PrivateIncludePaths.AddRange(
new string[] {
System.IO.Path.GetFullPath(Target.RelativeEnginePath)+ "/Source/Editor/Blutility/Private"
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"Blutility",
// ... add other public dependencies that you statically link with here ...
}
測(cè)試代碼
#pragma once
#include "CoreMinimal.h"
#include "Blutility/Classes/AssetActionUtility.h"
#include "QuickAssetAction.generated.h"
/**
*
*/
UCLASS()
class SUPERMANAGER_API UQuickAssetAction : public UAssetActionUtility
{
GENERATED_BODY()
public:
UFUNCTION(CallInEditor)
void TestFun();
};
#include "AssetActions/QuickAssetAction.h"
void UQuickAssetAction::TestFun()
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1,8.0f,FColor::Cyan,TEXT("worlking"));
}
}
在編輯器中新建藍(lán)圖 并在窗口中右擊顯示測(cè)試,點(diǎn)擊后打印到屏幕上

復(fù)制資源文件功能
首先引入兩個(gè)
#include "EditorAssetLibrary.h"
#include "EditorUtilityLibrary.h"
添加"EditorScriptingUtilities"模塊到cs
添加"EditorScriptingUtilities"到插件目錄
EditorAssetLibrary 是一個(gè) Unreal Engine 4 中的靜態(tài)類(lèi),提供了許多用于在編輯器中管理和操作資產(chǎn)的功能。它包含許多靜態(tài)函數(shù),可以在 C++ 代碼中使用。
以下是一些 EditorAssetLibrary 可用的功能:
獲取資產(chǎn)的標(biāo)簽(GetAssetRegistryTags)
檢查資產(chǎn)是否處于編輯器內(nèi)(IsAssetLoadedInEditor)
獲取資產(chǎn)的路徑(GetPathNameForLoadedAsset)
獲取資產(chǎn)的類(lèi)型(GetAssetType)
保存資產(chǎn)(SaveAsset)
創(chuàng)建新的資產(chǎn)(CreateAsset)
檢查資產(chǎn)是否存在(DoesAssetExist)
加載資產(chǎn)(LoadAsset)
這些函數(shù)可以幫助您在編輯器中進(jìn)行資產(chǎn)管理和操作,例如創(chuàng)建新的資產(chǎn)、保存資產(chǎn)、加載資產(chǎn)等。這些函數(shù)還可以幫助您在運(yùn)行時(shí)訪(fǎng)問(wèn)編輯器中的資產(chǎn),例如獲取資產(chǎn)的路徑、類(lèi)型和標(biāo)簽等。
需要注意的是,EditorAssetLibrary 是一個(gè)專(zhuān)門(mén)用于編輯器的類(lèi),它不適用于在游戲運(yùn)行時(shí)使用。如果您需要在游戲運(yùn)行時(shí)加載、創(chuàng)建或保存資產(chǎn),則需要使用其他類(lèi)和函數(shù),例如 AssetRegistry、AssetTools、FAssetData 等。
EditorUtilityLibrary 是 Unreal Engine 4 中的一個(gè)靜態(tài)類(lèi),提供了一些有用的函數(shù),可以在編輯器中使用。這些函數(shù)可以幫助您處理編輯器中的對(duì)象、場(chǎng)景和資產(chǎn),以及與編輯器交互的其他功能。
本示例中獲取選中的資源函數(shù) UEditorUtilityLibrary::GetSelectedAssetData();
以下是一些 EditorUtilityLibrary 可用的功能:
捕捉視圖到指定的Actor或位置(GetActorBounds、GetActorBoundsLocal、GetBoundsForSelection等)
啟用或禁用編輯器視口中的游戲模式(SetGameView)
將選定的對(duì)象重定位到編輯器視口的中心(FocusViewportOnSelectedObjects)
執(zhí)行命令(ExecuteEditorCommand)
清空編輯器控制臺(tái)(ClearEditorConsole)
檢查資產(chǎn)是否處于編輯器內(nèi)(IsAssetLoadedInEditor)
打開(kāi)資產(chǎn)在資產(chǎn)編輯器中的編輯器(OpenEditorForAsset)
獲取或設(shè)置編輯器選項(xiàng)(GetEditorUserSettings、SetEditorUserSettings)
EditorUtilityLibrary 可以幫助您簡(jiǎn)化在編輯器中執(zhí)行的任務(wù),例如在編輯器中捕捉對(duì)象的邊界框、執(zhí)行編輯器命令、清空編輯器控制臺(tái)等。它還可以幫助您管理編輯器選項(xiàng)和資產(chǎn)。
需要注意的是,EditorUtilityLibrary 是一個(gè)專(zhuān)門(mén)用于編輯器的類(lèi),它不適用于在游戲運(yùn)行時(shí)使用。如果您需要在游戲運(yùn)行時(shí)執(zhí)行這些功能,則需要使用其他類(lèi)和函數(shù)。
UFUNCTION(CallInEditor)
void DuplicateAssets(int32 NumOfDuplicates);
void UQuickAssetAction::DuplicateAssets(int32 NumOfDuplicates)
{
if (NumOfDuplicates<=0)
{
Print(TEXT("請(qǐng)指定資源的數(shù)量"),FColor::Red);
return;
}
//獲取當(dāng)前選中的資源data
TArray<FAssetData> SelectedAssetData = UEditorUtilityLibrary::GetSelectedAssetData();
uint32 Counter = 0;
//遍歷選中的文件
for(const FAssetData& SelectedData:SelectedAssetData)
{
for (int32 i =0;i<NumOfDuplicates;i++)
{
//獲取資源路徑
const FString SourceAssetPath = SelectedData.GetSoftObjectPath().ToString();
//const FString SourceAsserPath = SelectedData.ObjectPath.ToString();
//IDE提示上面的函數(shù) 下個(gè)版本棄用
//獲取資源名稱(chēng) 并在新命名的文件后加上數(shù)量
const FString NewDuplicatedAssetName=SelectedData.AssetName.ToString() + TEXT("_") +FString::FromInt(i+1);
//將文件夾前綴名字 和 新文件路徑名稱(chēng)拼到一起
const FString NewPathName = FPaths::Combine(SelectedData.PackagePath.ToString(),NewDuplicatedAssetName);
//復(fù)制資源 保存資源
if (UEditorAssetLibrary::DuplicateAsset(SourceAssetPath,NewPathName))
{
UEditorAssetLibrary::SaveAsset(NewPathName,false);
++Counter;
}
}
}
if (Counter>0)
{
Print(TEXT("復(fù)制成功"+FString::FromInt(Counter)+" 文件"),FColor::Green);
}
}
編譯后右擊資源文件 選擇復(fù)制


提示確認(rèn)框 和 通知UI
當(dāng)用戶(hù)輸入一個(gè)錯(cuò)誤的復(fù)制數(shù)量時(shí),彈出一個(gè)提示框
在DebugHeader.h中引入下面頭文件
#include "Misc/MessageDialog.h"
EAppReturnType::Type ShowMsgDialog(EAppMsgType::Type MsgType,const FString& Message,bool BShowMsgWaring = true)
{
//是否顯示警告彈框文字
if (BShowMsgWaring)
{
//彈框標(biāo)題
FText MsgTitle = FText::FromString(TEXT("警告"));
return FMessageDialog::Open(MsgType,FText::FromString(Message),&MsgTitle);
}
else
{
return FMessageDialog::Open(MsgType,FText::FromString(Message));
}
}
輸入<=0時(shí)
void UQuickAssetAction::DuplicateAssets(int32 NumOfDuplicates)
{
if (NumOfDuplicates<=0)
{
ShowMsgDialog(EAppMsgType::Ok,TEXT("請(qǐng)指定有效資源數(shù)量"),false);
return;
}
彈出提示框

當(dāng)復(fù)制成功時(shí),彈出UI提示用戶(hù),復(fù)制成功
在DebugHeader.h中引入下面頭文件
#include "Widgets/Notifications/SNotificationList.h"
#include "Framework/Notifications/NotificationManager.h"
void ShowNotifyInfo(const FString &Message)
{
//創(chuàng)建info
FNotificationInfo NotifyInfo(FText::FromString(Message));
//大號(hào)字體
NotifyInfo.bUseLargeFont =true;
//消失時(shí)間
NotifyInfo.FadeOutDuration =7.0f;
//通過(guò)Manager 彈出
FSlateNotificationManager::Get().AddNotification(NotifyInfo);
}
if (Counter>0)
{
ShowNotifyInfo(TEXT("拷貝成功文件數(shù)量: "+FString::FromInt(Counter)));
}
彈出Slate UI

MessageDialog 是 Unreal Engine 中的一個(gè)類(lèi),用于在游戲或編輯器中顯示消息對(duì)話(huà)框。消息對(duì)話(huà)框通常用于向用戶(hù)顯示信息、警告或錯(cuò)誤消息,并讓用戶(hù)選擇接受或拒絕。
MessageDialog 提供了創(chuàng)建和顯示消息對(duì)話(huà)框的方法,以及處理用戶(hù)響應(yīng)的方法。您可以使用 MessageDialog 在游戲或編輯器中顯示自定義消息對(duì)話(huà)框,以向用戶(hù)顯示重要信息或警告。
以下是一些 MessageDialog 可用的功能:
創(chuàng)建消息對(duì)話(huà)框(Open)
設(shè)置消息對(duì)話(huà)框的標(biāo)題、正文和按鈕
顯示消息對(duì)話(huà)框,并等待用戶(hù)響應(yīng)(ShowModal)
處理用戶(hù)響應(yīng),例如確定、取消或其他自定義按鈕(OnButtonClicked)
例如,您可以使用 MessageDialog 在編輯器中顯示警告消息,并詢(xún)問(wèn)用戶(hù)是否要繼續(xù)進(jìn)行某個(gè)操作。在游戲中,您可以使用 MessageDialog 在游戲中顯示任務(wù)完成消息或錯(cuò)誤消息,并要求用戶(hù)重新嘗試或退出游戲。
總之,MessageDialog 是 Unreal Engine 中非常有用的一個(gè)類(lèi),可用于向用戶(hù)顯示消息對(duì)話(huà)框并處理用戶(hù)響應(yīng)
FSlateNotificationManager 是 Unreal Engine 4 中的一個(gè)類(lèi),用于在 Slate UI 框架中管理通知(notifications)。通知是用于向用戶(hù)提供關(guān)于操作或狀態(tài)的信息的消息。通知可以出現(xiàn)在 UI 中的任何地方,例如在屏幕的左上角或右下角。
FSlateNotificationManager 管理通知的創(chuàng)建、顯示和消失。它可以處理各種通知類(lèi)型,例如成功消息、警告消息、錯(cuò)誤消息、進(jìn)度消息等。
以下是一些 FSlateNotificationManager 可用的功能:
創(chuàng)建通知(AddNotification)
設(shè)置通知的文本、圖標(biāo)和持續(xù)時(shí)間(SetNotificationText、SetNotificationIcon、SetExpireDuration)
顯示通知(ShowNotification)
隱藏通知(HideNotification)
關(guān)閉通知(RemoveNotification)
FSlateNotificationManager 可以幫助您在 UI 中顯示通知,以提供操作或狀態(tài)的信息。例如,您可以在 UI 中顯示一個(gè)通知,以告訴用戶(hù)文件已經(jīng)成功保存,或者通知用戶(hù)正在進(jìn)行某個(gè)耗時(shí)操作的進(jìn)度。
需要注意的是,FSlateNotificationManager 是 Slate UI 框架的一部分,而不是 Unreal Engine 的其他部分。它僅適用于 Slate UI,不能在其他 UI 框架中使用。
批量按資源類(lèi)型 添加前綴
新建一個(gè)Tmap中存儲(chǔ)要替換 類(lèi) 對(duì)應(yīng) 名稱(chēng)
private:
TMap<UClass*,FString> PrefixMap =
{
{
UBlueprint::StaticClass(),TEXT("BP_")
}
};
新建編輯器函數(shù)
UFUNCTION(CallInEditor,meta=(DisplayName ="統(tǒng)一修改前綴"))
void AddPrefixes();
函數(shù)內(nèi)實(shí)現(xiàn):根據(jù)資源類(lèi)型 找到對(duì)應(yīng)的前綴 替換資源名稱(chēng)
void UQuickAssetAction::AddPrefixes()
{
TArray<UObject*>SelectedObject =UEditorUtilityLibrary::GetSelectedAssets();
uint32 Counter =0;
for (UObject* Object:SelectedObject)
{
//如果無(wú)效 跳出當(dāng)前循環(huán)
if (!Object) continue;
//尋找前綴
FString* PrefixFound = PrefixMap.Find(Object->GetClass());
//指針無(wú)效或者找到的值是空時(shí) 提示用戶(hù)
if (!PrefixFound || PrefixFound->IsEmpty())
{
Print(TEXT("無(wú)法找到前綴"+ Object->GetClass()->GetName()),FColor::Red);
continue;
}
FString OldName = Object->GetName();
//檢查當(dāng)前文件是不是已經(jīng)加過(guò)前綴
if (OldName.StartsWith(*PrefixFound))
{
Print(OldName+TEXT("此文件已包含前綴"),FColor::Red);
continue;
}
//添加前綴
const FString NewNameWithPrefix = *PrefixFound +OldName;
UEditorUtilityLibrary::RenameAsset(Object,NewNameWithPrefix);
++Counter;
}
ShowNotifyInfo("重命名成功文件數(shù)量: "+FString::FromInt(Counter));
}

刪除無(wú)引用資源文件
批量刪除,如果資源有引用存在 則提示用戶(hù)
void UQuickAssetAction::RemoveUnusedAssets()
{
TArray<FAssetData> SelectedObject = UEditorUtilityLibrary::GetSelectedAssetData();
TArray<FAssetData> UnusedAssetsDatas;
for (auto Object : SelectedObject)
{
//檢索資源的引用數(shù)量
TArray<FString> AssetReferencersNums = UEditorAssetLibrary::FindPackageReferencersForAsset(
Object.GetSoftObjectPath().ToString(), false);
//如果引用數(shù)量為0 則添加到待刪除數(shù)組中
if (AssetReferencersNums.Num() == 0)
{
UnusedAssetsDatas.Add(Object);
}
}
//如果待刪除數(shù)量為0
if (UnusedAssetsDatas.Num()==0)
{
ShowMsgDialog(EAppMsgType::Ok,TEXT("所選資源有引用,無(wú)法刪除"),false);
return;
}
//檢查待刪除的數(shù)量
const int32 DeleteNums = ObjectTools::DeleteAssets(UnusedAssetsDatas);
//如果為0 則沒(méi)有待刪除的 直接return
if (DeleteNums==0)return;
//刪除后提示用戶(hù)
ShowNotifyInfo(TEXT("成功刪除資源數(shù)量: ")+FString::FromInt(DeleteNums));
}
修復(fù)資源文件重定向
參考文檔:https://www.codenong.com/cs107010490/
當(dāng)一個(gè)Assets文件移動(dòng)了新的路徑后,如果沒(méi)有重定向文件夾,再次移動(dòng)時(shí)會(huì)有路徑錯(cuò)誤的問(wèn)題。
文件夾重定向之后修復(fù)。
將路徑下的FAssetData轉(zhuǎn)成UObjectRedirector

UObjectRedirector 是虛幻引擎中的一個(gè)類(lèi),用于處理對(duì)象重定向。當(dāng)您刪除一個(gè)對(duì)象時(shí),如果有其他對(duì)象引用了該對(duì)象,這些引用就會(huì)變?yōu)闊o(wú)效。如果您嘗試訪(fǎng)問(wèn)這些無(wú)效的引用,程序就會(huì)崩潰。為了解決這個(gè)問(wèn)題,虛幻引擎提供了 UObjectRedirector 類(lèi),用于在刪除對(duì)象時(shí)自動(dòng)將引用該對(duì)象的其他對(duì)象重定向到新的對(duì)象上。
當(dāng)您刪除一個(gè)對(duì)象時(shí),虛幻引擎會(huì)自動(dòng)創(chuàng)建一個(gè) UObjectRedirector 對(duì)象,并將其添加到 Redirector 目錄下。UObjectRedirector 對(duì)象存儲(chǔ)了指向被刪除對(duì)象的引用,以及指向新對(duì)象的引用。當(dāng)您嘗試訪(fǎng)問(wèn)引用被刪除的對(duì)象時(shí),虛幻引擎會(huì)自動(dòng)查找對(duì)應(yīng)的 UObjectRedirector 對(duì)象,并將引用重定向到新對(duì)象上。
AssetRegistry 是 Unreal Engine 中的一個(gè)系統(tǒng)級(jí)別的工具,用于提供所有項(xiàng)目中的資產(chǎn)(Assets)和資產(chǎn)相關(guān)的元數(shù)據(jù)(MetaData)信息,包括資產(chǎn)的類(lèi)型、名稱(chēng)、路徑、標(biāo)簽等。通過(guò) AssetRegistry,您可以獲得項(xiàng)目中所有可用資產(chǎn)的信息,而無(wú)需在運(yùn)行時(shí)加載這些資產(chǎn)。
AssetRegistry 具有以下一些主要功能:
資產(chǎn)搜索:可以按照各種標(biāo)準(zhǔn)搜索資產(chǎn),如類(lèi)型、標(biāo)簽、路徑、狀態(tài)等,可以對(duì)搜索結(jié)果進(jìn)行排序和過(guò)濾。
資產(chǎn)監(jiān)聽(tīng):可以訂閱資產(chǎn)的創(chuàng)建、刪除、移動(dòng)、更改等事件,以便您的代碼可以在資產(chǎn)發(fā)生變化時(shí)及時(shí)響應(yīng)。
資產(chǎn)緩存:可以緩存資產(chǎn)和元數(shù)據(jù),以便快速訪(fǎng)問(wèn)它們,減少運(yùn)行時(shí)的加載時(shí)間和內(nèi)存占用。
資產(chǎn)依賴(lài)關(guān)系:可以獲取資產(chǎn)之間的依賴(lài)關(guān)系,以便您可以構(gòu)建更復(fù)雜的資產(chǎn)和資源系統(tǒng)。
資產(chǎn)過(guò)濾:可以通過(guò)過(guò)濾器和標(biāo)準(zhǔn)篩選出特定的資產(chǎn),以便進(jìn)行更精細(xì)的操作。
在 UE4 中,AssetRegistry 是通過(guò)異步任務(wù)執(zhí)行的,因此,您需要注冊(cè)回調(diào)函數(shù)來(lái)接收搜索結(jié)果、監(jiān)聽(tīng)事件等。AssetRegistry 還可以在游戲運(yùn)行時(shí)使用,以便您的代碼可以訪(fǎng)問(wèn)項(xiàng)目中的資產(chǎn)并執(zhí)行操作。
void UQuickAssetAction::FixUpRedirectors()
{
TArray<UObjectRedirector*>RedirectorsToFixArray;
//拿到AssetRegistryModule:
FAssetRegistryModule& AssetRegistryModule =
FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
//Filter 用作AssetRegistry進(jìn)行查詢(xún)時(shí)的過(guò)濾器,可以配置多個(gè)屬性
FARFilter Filter;
Filter.bRecursivePaths =true;
Filter.PackagePaths.Emplace("/Game");
TArray<FAssetData>OutRedirectors;
//篩選資產(chǎn)數(shù)據(jù)
AssetRegistryModule.Get().GetAssets(Filter,OutRedirectors);
//遍歷數(shù)據(jù) FAssetData 轉(zhuǎn)換為 UObjectRedirector
for(const FAssetData& RedirectorData:OutRedirectors)
{
if (UObjectRedirector* RedirectorToFix = Cast<UObjectRedirector>(RedirectorData.GetAsset()))
{
RedirectorsToFixArray.Add(RedirectorToFix);
}
}
//拿到FAssetToolsModule:
FAssetToolsModule &AssetToolsModule =
FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
//重定向
AssetToolsModule.Get().FixupReferencers(RedirectorsToFixArray);
}
拓展Content Browser 自定義按鈕

ContentBrowserModule是UE4中的一個(gè)模塊,用于管理和顯示項(xiàng)目中的內(nèi)容,包括靜態(tài)資產(chǎn)、藍(lán)圖、關(guān)卡和插件等。常用的一些函數(shù)包括:
FContentBrowserModule::Get(): 獲取ContentBrowserModule單例對(duì)象。
FContentBrowserModule::GetAllAssetViewContextMenuExtenders(): 獲取所有資產(chǎn)視圖的右鍵菜單擴(kuò)展器。
FContentBrowserModule::GetAssetContextMenuExtender(): 獲取資產(chǎn)視圖的右鍵菜單擴(kuò)展器。
FContentBrowserModule::GetAssetContextMenuActions(): 獲取資產(chǎn)視圖的右鍵菜單動(dòng)作。
FContentBrowserModule::CreateNewAsset(): 創(chuàng)建新的資產(chǎn)。
FContentBrowserModule::SyncBrowserToAssets(): 將資源同步到內(nèi)容瀏覽器。
FContentBrowserModule::GetSelectedAssets(): 獲取當(dāng)前選擇的資產(chǎn)。
FContentBrowserModule::Get().Get()->RegisterNotificationCallback(): 注冊(cè)內(nèi)容瀏覽器通知回調(diào)函數(shù)。
FContentBrowserModule::Get().Get()->UnregisterNotificationCallback(): 取消注冊(cè)內(nèi)容瀏覽器通知回調(diào)函數(shù)。
這些函數(shù)可以幫助開(kāi)發(fā)人員更方便地管理和操作項(xiàng)目中的內(nèi)容。
本節(jié)要在Content Browser中添加我們自定義的事件按鈕。在編輯器開(kāi)始加載的時(shí)候就要實(shí)現(xiàn)事件的初始化和函數(shù)綁定,于是前往模塊的StartupModule()下新建初始化函數(shù)
模塊加載時(shí)初始化
void FSuperManagerModule::StartupModule()
{
InitCBMenuExtention();
}
初始化的函數(shù)
在UE5中,GetAllPathViewContextMenuExtenders()是一個(gè)靜態(tài)函數(shù),用于獲取注冊(cè)在編輯器中的所有Path View上下文菜單擴(kuò)展器。Path View是UE5編輯器中的一個(gè)資源管理器,用于瀏覽和管理項(xiàng)目中的資源。此函數(shù)返回一個(gè)數(shù)組,其中包含所有注冊(cè)的Path View上下文菜單擴(kuò)展器的指針??梢允褂眠@些指針來(lái)訪(fǎng)問(wèn)擴(kuò)展器的功能,并將它們添加到Path View上下文菜單中。
void FSuperManagerModule::InitCBMenuExtention()
{
//拿到FContentBrowserModule:
FContentBrowserModule &ContentBrowserModule =
FModuleManager::LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
//返回&時(shí) 保留& 而不是重新復(fù)制一份
//拿到所有PathView 委托的 數(shù)組
TArray<FContentBrowserMenuExtender_SelectedPaths> & ContentBrowserModuleMenuExtenders =
ContentBrowserModule.GetAllPathViewContextMenuExtenders();
//創(chuàng)建自己的委托
FContentBrowserMenuExtender_SelectedPaths CustomCBMenuDelegate;
//綁定委托事件
CustomCBMenuDelegate.BindRaw(this,&FSuperManagerModule::CustomCBMenuExtender);
//并添加到數(shù)組中
ContentBrowserModuleMenuExtenders.Add(CustomCBMenuDelegate);
//另外一種寫(xiě)法 add時(shí)添加
/*ContentBrowserModuleMenuExtenders.Add
(FContentBrowserMenuExtender_SelectedPaths::CreateRaw(this,&FSuperManagerModule::CustomCBMenuExtender));*/
}
添加綁定委托 Hook可以打開(kāi)編輯器設(shè)定里的 顯示菜單中的Hook信息


TSharedRef<FExtender> FSuperManagerModule::CustomCBMenuExtender(const TArray<FString>& SelectedPaths)
{
//創(chuàng)建一個(gè)TSharedRef<FExtender>
TSharedRef<FExtender> MenuExtender (new FExtender());
if (SelectedPaths.Num()>0)
{
//找到目標(biāo)的Hook鉤子 , 設(shè)置添加的位置, 設(shè)置快捷鍵, 添加綁定的事件委托)
MenuExtender->AddMenuExtension( TEXT("Delete"),
EExtensionHook::After,TSharedPtr< FUICommandList >(),
FMenuExtensionDelegate::CreateRaw(this,&FSuperManagerModule::AddCBMenuEntry ));
}
return MenuExtender;
}
完成后繼續(xù)使用委托設(shè)置菜單按鈕的信息
//設(shè)置菜單按鈕的一些信息
void FSuperManagerModule::AddCBMenuEntry(FMenuBuilder& MenuBuilder)
{
MenuBuilder.AddMenuEntry
(
//按鈕名稱(chēng)
FText::FromString(TEXT("刪除未被引用的資源")),
//提示文本
FText::FromString(TEXT("批量安全刪除未使用的Asset")),
//按鈕圖標(biāo)
FSlateIcon(),
//綁定要執(zhí)行的事件
FExecuteAction::CreateRaw(this,&FSuperManagerModule::OnDeleteUnsuedAssetButtonClicked)
);
}
最后是按鈕真正要處理的事件綁定函數(shù)
void FSuperManagerModule::OnDeleteUnsuedAssetButtonClicked()
{
}
成功添加了一個(gè)我們自定義的按鈕

注冊(cè)創(chuàng)建一個(gè)自定義編輯器界面
首先注冊(cè)編輯器面板 在模塊初始化時(shí)調(diào)用
//注冊(cè)窗口
void RegisterAdvanceDeletionTab();
//窗口綁定的委托
TSharedRef<SDockTab> OnSpawnAdvanceDeletionTab(const FSpawnTabArgs& SpawnTabArgs);
void FSuperManagerModule::RegisterAdvanceDeletionTab()
{
//FGlobalTabmanager注冊(cè)一個(gè)面板 綁定委托 設(shè)置窗口名稱(chēng)
FTabSpawnerEntry TabSpawnerEntry = FGlobalTabmanager::Get()->RegisterNomadTabSpawner(FName("AdvancedDelete"),
FOnSpawnTab::CreateRaw(this, &FSuperManagerModule::OnSpawnAdvanceDeletionTab));
TabSpawnerEntry.SetDisplayName(FText::FromString(TEXT("Advanced Delete")));
}
TSharedRef<SDockTab> FSuperManagerModule::OnSpawnAdvanceDeletionTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab).TabRole(NomadTab);
}
點(diǎn)擊時(shí)彈出

接著嘗試?yán)L制窗口內(nèi)的元素
新建一個(gè)C++空類(lèi) 放置插件目錄 新建SlateWidgets 內(nèi)
#pragma once
#include "Widgets/SCompoundWidget.h"
class SAdvancedDeletionTab:public SCompoundWidget
{
SLATE_BEGIN_ARGS(SAdvancedDeletionTab){}
//可以傳遞參數(shù)
SLATE_ARGUMENT(FString,TestString)
SLATE_END_ARGS()
public:
void Construct(const FArguments& InArgs);
};
#include "SlateWidgets/AdvancedDeleteWidget.h"
void SAdvancedDeletionTab::Construct(const FArguments& InArgs)
{
bCanSupportFocus = true;
ChildSlot
[
//傳遞參數(shù)需要帶下劃線(xiàn) _TestString
SNew(STextBlock).Text(FText::FromString(InArgs._TestString))
];
}
修改 在打開(kāi)SNew(SDockTab)的時(shí)候嘗試傳遞參數(shù)
TSharedRef<SDockTab> FSuperManagerModule::OnSpawnAdvanceDeletionTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab).TabRole(NomadTab)[
SNew(SAdvancedDeletionTab)
.TestString(TEXT("456"))
];
}
這是彈框顯示文本

設(shè)置自定義界面的標(biāo)題
void SAdvancedDeletionTab::Construct(const FArguments& InArgs)
{
bCanSupportFocus = true;
//設(shè)置字體大小 字體類(lèi)型 等
FSlateFontInfo FontInfo;
//未設(shè)置字體會(huì)顯示 ????
FontInfo = FCoreStyle::Get().GetFontStyle(TEXT("NormalFont"));
FontInfo.Size = 30;
ChildSlot
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(STextBlock)
.Text(FText::FromString("Advance Deletion"))
.Font(FontInfo)
.Justification(ETextJustify::Center) //居中
.ColorAndOpacity(FColor::White) // 顏色
]
];
}

SListView顯示資產(chǎn)信息
為了拿到右鍵文件夾的資產(chǎn)信息,修改代碼 傳遞一個(gè) FAssetData類(lèi)型的指針數(shù)組
//可以傳遞參數(shù)
SLATE_ARGUMENT(TArray<TSharedPtr<FAssetData>>,AssetDataToStore)
因此在彈框時(shí) ,獲取資產(chǎn)并傳遞
//彈框時(shí)的委托事件
TSharedRef<SDockTab> FSuperManagerModule::OnSpawnAdvanceDeletionTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab).TabRole(NomadTab)[
SNew(SAdvancedDeletionTab)
.AssetDataToStore(GetAllAssetDataUnderSelectedFolder())
];
}
//獲取當(dāng)前選擇的文件夾下的資產(chǎn)
TArray<TSharedPtr<FAssetData>> FSuperManagerModule::GetAllAssetDataUnderSelectedFolder()
{
TArray<TSharedPtr<FAssetData>> AvaiableAssetDatas;
TArray<FString> AssetsPathNames= UEditorAssetLibrary::ListAssets(FolderPathsSelected[0]);
for (auto PathNames: AssetsPathNames)
{
if (!UEditorAssetLibrary::DoesAssetExist(PathNames))continue;
const FAssetData Data = UEditorAssetLibrary::FindAssetData(PathNames);
AvaiableAssetDatas.Add(MakeShared<FAssetData>(Data));
}
return AvaiableAssetDatas;
}
修改彈框的樣式,新增一個(gè)SScrollBox的滾動(dòng)框
void SAdvancedDeletionTab::Construct(const FArguments& InArgs)
{
bCanSupportFocus = true;
StoreAssetData = InArgs._AssetDataToStore;
//設(shè)置字體大小 字體類(lèi)型 等
FSlateFontInfo FontInfo;
//未設(shè)置字體會(huì)顯示 ????
FontInfo = FCoreStyle::Get().GetFontStyle(TEXT("NormalFont"));
FontInfo.Size = 30;
ChildSlot
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(STextBlock)
.Text(FText::FromString("Advance Deletion"))
.Font(FontInfo)
.Justification(ETextJustify::Center) //居中
.ColorAndOpacity(FColor::White) // 顏色
]
//第二個(gè)插槽
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
]
//第三個(gè)插槽
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SScrollBox)
+ SScrollBox::Slot()
[
SNew(SListView<TSharedPtr<FAssetData>>)
.ItemHeight(24.0f)
//使用InArgs傳遞過(guò)來(lái)的資產(chǎn)信息
.ListItemsSource(&StoreAssetData)
.ScrollbarVisibility(EVisibility::Collapsed)
//生成一行item的委托
.OnGenerateRow(this, &SAdvancedDeletionTab::OnGenerateItemRow)
]
]
//第四個(gè)插槽
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
]
];
}
綁定生成itemrow的委托
TSharedRef<ITableRow> SAdvancedDeletionTab::OnGenerateItemRow(TSharedPtr<FAssetData> Item,
const TSharedRef<STableViewBase>& OwnerTable)
{
return SNew(STableRow<TSharedPtr<FAssetData>>, OwnerTable)
[
SNew(STextBlock)
.Text(FText::FromString(Item->AssetName.ToString()))
];
}
此時(shí)右擊Content目錄已經(jīng)可以獲取資產(chǎn)的名稱(chēng)

發(fā)現(xiàn)雖然列表顯示了,但是沒(méi)有滾動(dòng)條
將AutoHeight() 修改為.VAlign(VAlign_Fill)后滾動(dòng)條顯示正常
//使用AutoHeight會(huì)顯示不出滾動(dòng)條
//第三個(gè)插槽
+ SVerticalBox::Slot()
//使用AutoHeight會(huì)顯示不出滾動(dòng)條
//.AutoHeight()
.VAlign(VAlign_Fill)
SCheckBox復(fù)選框
為了顯示資源的信息,OnGenerateItemRow的時(shí)候 修改橫向顯示一些信息
TSharedRef<ITableRow> SAdvancedDeletionTab::OnGenerateItemRow(TSharedPtr<FAssetData> Item,
const TSharedRef<STableViewBase>& OwnerTable)
{
return SNew(STableRow<TSharedPtr<FAssetData>>, OwnerTable)[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
[
//生成一個(gè)CheckBox
//傳入Item參數(shù)
ConstructCheckBox(Item)
]
+ SHorizontalBox::Slot()
[
SNew(STextBlock)
.Text(FText::FromString(Item->GetClass()->GetName()))
]
+ SHorizontalBox::Slot()
[
SNew(STextBlock)
.Text(FText::FromString(Item->AssetName.ToString()))
]
+ SHorizontalBox::Slot()
[SNew(SButton)
]
];
構(gòu)造一個(gè)CheckBox選中框
//生成一個(gè)CheckBox
TSharedRef<SCheckBox> ConstructCheckBox(TSharedPtr<FAssetData> Item);
TSharedRef<SCheckBox> SAdvancedDeletionTab::ConstructCheckBox(TSharedPtr<FAssetData> Item)
{
//生成一個(gè)checkbox
TSharedRef<SCheckBox> CheckBox = SNew(SCheckBox)
.Type(ESlateCheckBoxType::CheckBox)
//選中切換時(shí)的事件
.OnCheckStateChanged(this,&SAdvancedDeletionTab::OnCheckBoxStateChanged,Item)
.Visibility(EVisibility::Visible);
return CheckBox;
}
在綁定切換選中的事件
//checkbox選中的事件
void OnCheckBoxStateChanged(ECheckBoxState NewState,TSharedPtr<FAssetData> ItemAssetData);
void SAdvancedDeletionTab::OnCheckBoxStateChanged(ECheckBoxState NewState, TSharedPtr<FAssetData> ItemAssetData)
{
DebugHeader::Print(ItemAssetData->AssetName.ToString(),FColor::Green);
}
此時(shí)切換checkbox時(shí) 打印出資源的名稱(chēng)

刪除按鈕 SButton
新增一個(gè)右側(cè)的按鈕,方便快速的刪除資源
[
//生成一個(gè)Button
ConstructButton(Item)
]
TSharedRef<SButton> SAdvancedDeletionTab::ConstructButton(const TSharedPtr<FAssetData> &ClickItem)
{
TSharedRef<SButton> ConstructButton =SNew(SButton)
.Text(FText::FromString(TEXT("刪除")))
//綁定刪除的事件
.OnClicked(this,&SAdvancedDeletionTab::OnDeleteButtonClick,ClickItem);
return ConstructButton;
}
為了后續(xù)的刪除資源,將刪除資源的函數(shù)寫(xiě)在FSuperManagerModule中,方便以后的調(diào)用
//刪除單個(gè)資源
bool DelectSingeAsset(const FAssetData& Data);
bool FSuperManagerModule::DelectSingeAsset(const FAssetData& Data)
{
TArray<FAssetData> AssetsDatas;
AssetsDatas.Add(Data);
//返回bool >0時(shí)則刪除是成功的
if (ObjectTools::DeleteAssets(AssetsDatas) > 0)
{
return true;
}
return false;
}
在用戶(hù)點(diǎn)擊按鈕時(shí),調(diào)用綁定的函數(shù)
FReply SAdvancedDeletionTab::OnDeleteButtonClick(TSharedPtr<FAssetData> ClickItem)
{
//獲取FSuperManagerModule模塊
FSuperManagerModule SuperManagerModule = FModuleManager::LoadModuleChecked<FSuperManagerModule>(
TEXT("SuperManager"));
//判斷用戶(hù)是否點(diǎn)了取消刪除
//取對(duì)象
const bool DelectBool = SuperManagerModule.DelectSingeAsset(*ClickItem.Get());
//刷新列表
if (DelectBool)
{
//如果資源列表中包含目標(biāo)的item
if (StoreAssetData.Contains(ClickItem))
{
StoreAssetData.Remove(ClickItem);
AssetList->RebuildList();
}
}
return FReply::Handled();
}
底部 全部刪除 全部選擇 全部取消 按鈕
將第四個(gè)SVerticalBox::Slot()的Snew出來(lái)一個(gè)面板 新增構(gòu)造函數(shù) ConstructHorizontalBox()
//第四個(gè)插槽 三個(gè)按鈕
+ SVerticalBox::Slot()
.FillHeight(0.2)
[
//底部按鈕
ConstructHorizontalBox()
]
];
構(gòu)造面板的函數(shù)
TSharedRef<SHorizontalBox> SAdvancedDeletionTab::ConstructHorizontalBox()
{
TSharedRef<SHorizontalBox> Menubutton = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.VAlign(VAlign_Fill)
.Padding(20, 20, 20, 20)
[
SNew(SButton)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.OnClicked(this,&SAdvancedDeletionTab::OnAllDeleteButtonClick)
.Text(FText::FromString(TEXT("刪除全部")))
]
+ SHorizontalBox::Slot()
.VAlign(VAlign_Fill)
.Padding(20, 20, 20, 20)
[
SNew(SButton)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.OnClicked(this,&SAdvancedDeletionTab::OnAllSelectButtonClick)
.Text(FText::FromString(TEXT("選擇全部")))
]
+ SHorizontalBox::Slot()
.VAlign(VAlign_Fill)
.Padding(20, 20, 20, 20)
[
SNew(SButton)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.OnClicked(this,&SAdvancedDeletionTab::OnAllUnSelectButtonClick)
.Text(FText::FromString(TEXT("取消全部")))
];
return Menubutton;
}
三個(gè)按鈕的綁定事件
//底部三個(gè)按鈕的事件
FReply OnAllDeleteButtonClick();
FReply OnAllSelectButtonClick();
FReply OnAllUnSelectButtonClick();
三個(gè)按鈕的綁定事件
為了將CheckBox狀態(tài)和FAssetData綁定到一起,這里新增一個(gè)結(jié)構(gòu)體,用來(lái)存貯CheckBox 和 FAssetData的指針
struct FCheckBoxStruct
{
TSharedPtr<SCheckBox> CheckBox ;
TSharedPtr<FAssetData> FAssetData ;
};
//當(dāng)前選中的CheckBox的FAssetData
TArray<TSharedPtr<FAssetData>> FAssetDataCheckArray;
//CheckBox選中數(shù)據(jù)對(duì)應(yīng)FAssetData
TArray <FCheckBoxStruct> CheckBoxStructArray;
全部刪除
FReply SAdvancedDeletionTab::OnAllDeleteButtonClick()
{
//獲取FSuperManagerModule模塊
FSuperManagerModule SuperManagerModule = FModuleManager::LoadModuleChecked<FSuperManagerModule>(
TEXT("SuperManager"));
//待刪除的資源數(shù)組
TArray<TSharedPtr<FAssetData>> DeleteFAssetDataArray;
//遍歷目前選中的checkbox 將FAssetData加入待刪除的資源數(shù)組
for (auto CheckBoxStruct : CheckBoxStructArray)
{
if (CheckBoxStruct.CheckBox->IsChecked())
{
DeleteFAssetDataArray.Add(CheckBoxStruct.FAssetData);
}
}
//FAssetDataCheckArray中是全部選中的資源
bool DelectBool = SuperManagerModule.DelectMultipleAsset(DeleteFAssetDataArray);
if (DelectBool)
{
AssetList->RebuildList();
for (auto FAssetDataArray : DeleteFAssetDataArray)
{
//如果顯示的資源列表中包含待刪除的數(shù)據(jù) 就移除 為了后面的刷新列表
if (StoreAssetData.Contains(FAssetDataArray))StoreAssetData.Remove(FAssetDataArray);
}
//清空CheckBoxStructArray數(shù)組
CheckBoxStructArray.Empty();
}
return FReply::Handled();
}
全部選中
FReply SAdvancedDeletionTab::OnAllSelectButtonClick()
{
//遍歷所有結(jié)構(gòu)體 將CheckBox設(shè)為選中
for (const auto & CheckBoxStruct : CheckBoxStructArray)
{
CheckBoxStruct.CheckBox->SetIsChecked(ECheckBoxState::Checked);
}
return FReply::Handled();
}
全部取消選中
FReply SAdvancedDeletionTab::OnAllUnSelectButtonClick()
{
//遍歷所有結(jié)構(gòu)體 將CheckBox設(shè)為未選中
for (const auto & CheckBoxStruct : CheckBoxStructArray)
{
CheckBoxStruct.CheckBox->SetIsChecked(ECheckBoxState::Unchecked);
}
return FReply::Handled();
}
Combox下拉框
構(gòu)建一個(gè)Combox方便篩選資源類(lèi)型
//生成一個(gè)Combox
TSharedRef< SComboBox< TSharedPtr<FString> > >ConstructComboBox();
//Combox下拉框文本
TArray<TSharedPtr<FString>>ComboBoxTextArray ;
//接受顯示
TSharedPtr<STextBlock>ComboBoxText;
TSharedRef<SWidget> OnGenerateComboContent(TSharedPtr<FString> SourceItem);
void OnComboChanged(TSharedPtr<FString> SelectedOption, ESelectInfo::Type SelectInfo);
構(gòu)建一個(gè)combox
//第二個(gè)插槽
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
ConstructComboBox()
]
]
生成combox
TSharedRef<SComboBox<TSharedPtr<FString>>> SAdvancedDeletionTab::ConstructComboBox()
{
TSharedRef<SComboBox<TSharedPtr<FString>>> ConstructComboBox =
SNew(SComboBox<TSharedPtr<FString>>)
//下拉框的數(shù)量
.OptionsSource(&ComboBoxTextArray)
//生成下拉框的樣式
.OnGenerateWidget(this,&SAdvancedDeletionTab::OnGenerateComboContent)
//選擇時(shí)的綁定函數(shù)
.OnSelectionChanged(this,&SAdvancedDeletionTab::OnComboChanged)
[
//接受顯示的STextBlock 固定寫(xiě)法 并不是OnSelectionChanged下的
SAssignNew(ComboBoxText,STextBlock)
.Text(FText::FromString("Asset Type"))
];
return ConstructComboBox;
}
生成Combo內(nèi)容
TSharedRef<SWidget> SAdvancedDeletionTab::OnGenerateComboContent(TSharedPtr<FString> SourceItem)
{
TSharedRef<SWidget> Widget= SNew(STextBlock).Text(FText::FromString(*SourceItem.Get()));
return Widget;
}
點(diǎn)擊狀態(tài)變更綁定的函數(shù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-482625.html
void SAdvancedDeletionTab::OnComboChanged(TSharedPtr<FString> Item, ESelectInfo::Type SelectInfo)
{
DebugHeader::Print(*Item.Get(),FColor::Green);
ComboBoxText->SetText(FText::FromString(*Item.Get()));
}
使用宏在字段數(shù)組中加入下拉字段文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-482625.html
#define ListAll TEXT("全部的類(lèi)型")
//使用宏簡(jiǎn)化后續(xù)文本
ComboBoxTextArray.Add(MakeShared<FString>(ListAll));

到了這里,關(guān)于UE5引擎編輯器插件開(kāi)發(fā)歸檔的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!