언리얼 개발/이것저것 테스트
[UE_5] 모듈 제작 -5 (엔진 메뉴 Extension)
WhNi
2024. 4. 22. 21:50
엔진을 쓰다보면 Custom하는 경우가 생기기 마련이다.
이걸 플러그인으로 만들 수 있는데,
먼저 플러그인 처음으로 생성하면 IModuleInterface 를 상속받는 헤더가 있다.
여기에 추가적인 함수들을 추가해주고, 델리게이트로 연결해줘야 한다.
(#include "Modules/ModuleManager.h") 를 추가해줘야 한다.
private:
void InitMenuExtention();
TSharedRef<FExtender> CustomMenuExtender(const TArray<FString>& Path);
void AddMenuEntry(class FMenuBuilder& Menu);
void OnDeleteUnUsedAssetButtonClicked();
그 다음 cpp 파일에서 ContentBrowserModule.h 도 추가해 줘야한다. 아무래도 ContentBrowser 에서 적용되는 메뉴 Extension이기에, 여기에 하는게 당연하다.
void FSuperManagerModule::InitMenuExtention()
{
//모듈 매니저에서 모듈이 로드 되어있는지 체크하고
FContentBrowserModule& ContentBrowerModule =
FModuleManager::LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
//GetAllPathViewContextMenuExtenders() 찾아준다.
TArray<FContentBrowserMenuExtender_SelectedPaths>& ContentBrowerModuleMenuExtenders =
ContentBrowerModule.GetAllPathViewContextMenuExtenders();
//델리게이트 연결로 커스텀 메뉴를 추가해야 한다.
FContentBrowserMenuExtender_SelectedPaths CustomMenuDelegate;
CustomMenuDelegate.BindRaw(this, &FSuperManagerModule::CustomMenuExtender);
ContentBrowerModuleMenuExtenders.Add(CustomMenuDelegate);
}
// CustomMenuExtender는 리턴 타입이 TSharerdRef라는 스마트 포인터로 되어있다.
TSharedRef<FExtender> FSuperManagerModule::CustomMenuExtender(const TArray<FString>& Path)
{
// 포인터를 새로 할당하고
TSharedRef<FExtender> MenuExtender(new FExtender());
// Path의 배열이 0보다 크다면
if (Path.Num() > 0)
{
// "Delete"라는 메뉴에 위치에 또 델리게이트를 추가하는데
MenuExtender->AddMenuExtension(FName("Delete"),EExtensionHook::After,
TSharedPtr<FUICommandList>(),
FMenuExtensionDelegate::CreateRaw(this,&FSuperManagerModule::AddMenuEntry));
}
// 반환을 포인터로 해야 한다.
return MenuExtender;
}
// FMemuBuilder 라는 class을 매개변수로 갖는 FMenuExtensionDelegate.
void FSuperManagerModule::AddMenuEntry(FMenuBuilder& Menu)
{
이 메뉴에서 새로이 메뉴 Extenstion을 추가할 수 있다.
Menu.AddMenuEntry
(
FText::FromString(TEXT("Delete Unused Assets")),
FText::FromString(TEXT("Safely delete all unused assets")),
FSlateIcon(),
// 여기서는 그 메뉴에 들어가는 기능을 델리게이트 해야한다.
FExecuteAction::CreateRaw(this, &FSuperManagerModule::OnDeleteUnUsedAssetButtonClicked)
);
}
void FSuperManagerModule::OnDeleteUnUsedAssetButtonClicked()
{
//Print(TEXT("Working"), FColor::Red);
//파일의 갯수가 2개면 한 폴더에서만 가능해야하니까 return
if (FolderPath.Num() > 1)
{
ShowMsgDialog(EAppMsgType::Ok,TEXT("You can only do this to one folder"));
return;
}
//선택된 폴더 이름 표시
Print(TEXT("Selected folder: ") + FolderPath[0], FColor::Green);
// 선택된 에셋의 갯수
TArray<FString> AssetsPathCount =UEditorAssetLibrary::ListAssets(FolderPath[0]);
// 선택된 폴더 내에 에셋이 없다는 뜻
if (AssetsPathCount.Num() == 0)
{
ShowMsgDialog(EAppMsgType::Ok,TEXT("No Assets found under selected folder"));
return;
}
// 있다면 몇개 있는지 보여주는 다이얼로그. Yes No 라는 문구로, No라면 return
EAppReturnType::Type ConfirmResult =
ShowMsgDialog(EAppMsgType::YesNo, TEXT("A total of ")+ FString::FromInt(AssetsPathCount.Num()) + TEXT(" found, \nWould you like to procceed?"));
if (ConfirmResult == EAppReturnType::No) return;
// Yes 라면 사용하지 않는 에셋 수집하고 삭제
else
{
TArray<FAssetData> UnusedAssetDataArray;
// 경로에 대한 탐색을 할때, 에디터에 손상이 안가게 Root 폴더는 꼭 제외
for (const FString& AssetPathName : AssetsPathCount)
{
// make sure don't touch root folder
if (AssetPathName.Contains(TEXT("Developers")) || (AssetPathName.Contains(TEXT("Collections"))))
{
continue;
}
if (!UEditorAssetLibrary::DoesAssetExist(AssetPathName)) continue;
// 에셋에 대한 레퍼런스가 있는지 확인
TArray<FString> AssetReferece =
UEditorAssetLibrary::FindPackageReferencersForAsset(AssetPathName);
// 레퍼런스가 없는 에셋들이 있다면
if (AssetReferece.Num() == 0)
{
const FAssetData UnusedAssetData =
UEditorAssetLibrary::FindAssetData(AssetPathName);
// 사용하지 않는 에셋의 배열에 추가하기
UnusedAssetDataArray.Add(UnusedAssetData);
}
}
// 사용하지 않는 에셋의 배열이 1개 이상이면
if (UnusedAssetDataArray.Num() > 0)
{
// 에셋 지우고 다이얼로그 출력하기
ObjectTools::DeleteAssets(UnusedAssetDataArray);
ShowMsgDialog(EAppMsgType::Ok, TEXT(" Total Delete : ") + FString::FromInt(UnusedAssetDataArray.Num()));
}
else
{
ShowMsgDialog(EAppMsgType::Ok,TEXT("No Assets found under selected folder"));
}
}
}
이런식으로 적용하게 되면,
폴더 내에 있는 에셋들이 몇개인지 확인하고,
레퍼런스가 없는 에셋들을 찾아서
갯수를 보여주면서
삭제가 되는 에디터 기능을 메뉴에 추가 할 수 있다.