Plugin
I’ve created a plugin that allows you to configure custom Place Actors categories from Project Settings - If you are interested, please check out zomg’s editor addons - No C++ code required!
Manual setup
Create a custom Editor Module, and you can easily add new categories to the place actors toolbar.
//Get the placement mode module
IPlacementModeModule& PlacementModeModule = IPlacementModeModule::Get();
//Register a new category
//Handle must be unique as it's used to identify categories
FPlacementCategoryInfo Info = {
FText::AsCultureInvariant("My Category Name"),
FName("MyCategoryHandle"),
TEXT("PMMyCategoryTag"),
100
};
PlacementModeModule.RegisterPlacementCategory(Info);
Icons
Categories can be given icons if you use the overload which takes a FSlateIcon
as a parameter. Engine icons can be used for this if you don’t have Custom Editor Icons
Adding C++ actors into categories
//Using a previously created placement category info variable
//you can register new values into it like so
PlacementModeModule.RegisterPlaceableItem(Info.UniqueHandle, MakeShareable(
new FPlaceableItem(nullptr, AMyActor::StaticClass())
));
Adding Blueprint actors into categories
For Blueprint actors, you need to get its asset data, and an appropriate actor factory. The actor factory is most likely always UActorFactoryBlueprint
, but you can get the appropriate factory using GEngine->FindActorFactoryForActorClass
. (C++ actors do not need a factory.)
Below is an example of how to get a list of blueprint assets in a directory in your project, and filter all characters out, finally placing them into a category.
TArray<FAssetData> Assets;
FARFilter Filter;
Filter.ClassNames.Add(UBlueprint::StaticClass()->GetFName());
Filter.bRecursiveClasses = true;
Filter.PackagePaths = { "/Game/My/Blueprint/Characters" };
Filter.bRecursivePaths = true;
IAssetRegistry::Get()->GetAssets(Filter, Assets);
for(auto& Asset : Assets)
{
UBlueprint* BP = Cast<UBlueprint>(Asset.GetAsset());
if(!IsValid(BP))
{
//The BP can be invalid in some cases, such as when renaming assets
//it can give you the old incorrect asset which will not be valid
//and we should just skip it
continue;
}
UClass* AssetClass = BP->GetBlueprintClass();
if(AssetClass && BP->GeneratedClass->IsChildOf(ACharacter::StaticClass()))
{
PlacementModeModule.RegisterPlaceableItem(Info.UniqueHandle, MakeShareable(
new FPlaceableItem(
GEditor->FindActorFactoryForActorClass(Asset.GetClass()),
Asset
)
));
}
}