Assets in Unreal Engine are created through UFactory objects. There are a lot of factories in the engine responsible for creating various different assets.
- Many Blueprint assets such as Actors are created through UBlueprintFactory or its subclasses (which itself is a UFactory subclass)
- Many Gameplay Ability related assets are created through UGameplayAbilitiesBlueprintFactory. This class is very similar to UBlueprintFactory in its function and it’s a bit unclear why they didn’t just use that.
- Everything else is created through other UFactory subclasses
Note: the engine also contains objects called UActorFactory. These are unrelated to creating assets. Instead, they are used for spawning actors into levels, see for example Custom Place Actors toolbar categories
Creating an asset using a factory
The most straightforward way to make a new asset is using the factory’s CDO:
//Let's say we want to make a behavior tree asset
UFactory* MyFactory = GetDefault<UBehaviorTreeFactory>();
//Get a ref to the currently active content browser
IContentBrowserSingleton& ContentBrowser = IContentBrowserSingleton::Get();
//Get the current path from the content browser
FContentBrowserItemPath CurPath = ContentBrowser.GetCurrentPath();
//Generate a unique name for the asset
auto& AssetTools = IAssetTools::Get();
FString PackageNameToUse;
FString DefaultAssetName;
AssetTools.CreateUniqueAssetName(CurPath.GetInternalPathString() / Factory->GetDefaultNewAssetName(), FString(), PackageNameToUse, DefaultAssetName);
//Create the asset. Note the asset class needs to match the factory
ContentBrowser.CreateNewAsset(DefaultAssetName, CurPath.GetInternalPathString(), UBehaviorTree::StaticClass(), Factory);
Blueprint and Gameplay Ability factories
If you want to use one of the UBlueprintFactory
or UGameplayAbilitiesBlueprintFactory
classes, you need to use the factory class slightly differently:
//We need a new object instead of the CDO
auto* BPFactory = NewObject<UBlueprintFactory>(GetTransientPackage());
//The class we want to create must be set as the ParentClass on the factory
BPFactory->ParentClass = AActor::StaticClass();
//Note that instead of passing the asset class, we instead use GetSupportedClass
//(With blueprints, the supported class is typically UBlueprint, but not always)
ContentBrowser.CreateNewAsset(DefaultAssetName, CurPath.GetInternalPathString(), BPFactory->GetSupportedClass(), BPFactory);
The factory UGameplayAbilitiesBlueprintFactory
works exactly the same as above.
Other
Checking if the current path is valid for creating assets
Unreal has the concepts of a “virtual path” and an “internal path”. If the current path does not have an internal representation, assets cannot be created under it.
Some content directories do count as internal, but should not allow assets to be created in them. This includes the C++ classes folder.
We can determine the validity of a path as follows:
const FContentBrowserItemPath& Path = IContentBrowserSingleton::Get().GetCurrentPath();
if(!Path.HasInternalPath() || !Path.GetInternalPathString().StartsWith("/Game"))
{
//This path is either virtual, or is not within the game's Content folder
//and is invalid for creating assets into.
return;
}
Listing all factories
You can get a list of all engine factories via:
TArray<UFactory*> Factories = IAssetTools::Get().GetNewAssetFactories();