Actor Factory do not work with BP children

Specific use case is the WaterBody plugin. Created a blueprint from WaterBodyLake. WBL has an actor factory that does a bunch of work including setting up the materials. The BP version does not call any of that.

The root cause appears to be that FLevelEditorViewportClient::TryPlacingAssetObject is early outing from the

ActorFactory search because of if ( ObjectClass->IsChildOf( AActor::StaticClass() ) ).

Is there a preferred method of ensuring that blueprint versions of actor factory supported C++ classes are actually getting used?

Steps to Reproduce
Enable the Water plugin.

Make a BP child of the WaterBodyLake actor

Place BP child in world.

Notice that the materials are not set.

Hello [mention removed]​,

I have been able to reproduce this issue in UE 5.5 and in a build from the UE5 Main branch (CL 42589677). After investigating, it appears placing BP actors that depend on an Actor Factory isn’t currently supported by the engine.

Even if you bypass the early-out you mentioned, FindActorFactoryForActorClass expects an exact class match with the Actor Factory default actor class (not a derived blueprint class).

If you need to place a BP derived from a WaterBody actor and have it properly initialized by the WaterBodyActorFactory, engine source code modification is required. I’m going to share a short (hacky) workaround that can help:

1. Modify TryPlacingAssetObject (LevelEditorViewport.cpp):

`…

bool bPlaced = false;

// Workaround for Water Body derived Blueprint: use its GeneratedClass for placement and obtain the proper ActorFactory
UActorFactory* BPActorFactory = nullptr;
if (UBlueprint* BP = Cast(ObjToUse))
{
if (BP->GeneratedClass->GetName().Contains(TEXT(“WaterBody”)))
{
ObjectClass = BP->GeneratedClass;
BPActorFactory = GEditor->FindActorFactoryForActorClass(ObjectClass->GetSuperClass());
}
}

if ( ObjectClass->IsChildOf( AActor::StaticClass() ) )
{
//Attempting to drop a UClass object
UActorFactory* ActorFactory = Cast(PlacementOptions.FactoryToUse.GetObject());
if ( ActorFactory == NULL )
{
ActorFactory = GEditor->FindActorFactoryForActorClass( ObjectClass );
}

// Workaround for Water Body derived Blueprint
if (BPActorFactory) {
ActorFactory = BPActorFactory;
}


}`2. Override the following methods in the UWaterBodyActorFactory to allow for BP assets:

`virtual bool CanPlaceElementsFromAssetData(const FAssetData& InAssetData) override
{
if (!InAssetData.IsValid())
{
return false;
}

// HACK: Allow specific Blueprint asset by name (e.g., “BP_WaterBodyLake”)
if (InAssetData.AssetName.ToString().Contains(TEXT(“WaterBody”)))
{
return true;
}

// Fallback to base logic
return Super::CanPlaceElementsFromAssetData(InAssetData);
}

virtual AActor* GetDefaultActor(const FAssetData& AssetData) override
{
// Handle Blueprint assets specifically
if (UBlueprint* BP = Cast(AssetData.GetAsset()))
{
return BP->GeneratedClass->GetDefaultObject();
}

// Fallback to base implementation
return Super::GetDefaultActor(AssetData);
}`With these changes, you should be able to drag your BP_WaterLakeBody actor from the content browser into the level with the proper materials. This also works for BPs derived from other types of WaterBody actors (eg. Lake, Ocean).

[Image Removed]

Please let me know if this helps.

Best,

Francisco