From our programmer that got the furthest on this - assuming the below definitions:
`UCLASS(Abstract, EditInlineNew, BlueprintType, DefaultToInstanced)
class USettingsObjectBase
{
}
UCLASS()
class USettingsObjectTypeOne : public USettingsObjectBase
{
}
UCLASS()
class USettingsObjectTypeTwo : public USettingsObjectBase
{
}
USTRUCT()
struct FSettingsWrapper
{
UPROPERTY(EditAnywhere, NoClear, Instanced, Meta = (ShowOnlyInnerProperties))
TObjectPtr Settings;
FSettingsWrapper(UObject& Outer)
{
Settings = Outer.CreateDefaultSubobject(USettingsObjectTypeOne::StaticClass()->GetFName());
}
}
UCLASS()
class AProblemActorBase
{
UPROPERTY()
FSettingsWrapper Wrapper;
AProblemActorBase(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, Wrapper(*this)
{
}
}`Steps to put a BP asset into a bad state:
- Create a BP asset that inherits from AProblemActorBase
- In the class defaults pane, switch the Settings property to an instance of USettingsObjectTypeTwo
- In the class defaults pane, switch the Settings property back to an instance of USettingsObjectTypeOne
- Save the BP asset
After running these steps, dumping the BP asset’s export entries using the PkgInfo commandlet shows that the Settings subobject’s name is incremented (ie “SettingsObjectTypeOne_0”).
At cook time, when the BP asset is loaded and its generated class’s CDO is populated, it will have two Settings subobjects, one from the FSettingsWrapper constructor and one created for the export entry by the UObject linker.
The initial subobject from the constructor is unreferenced post-serialization and eventually becomes GC’ed, however we did see that initial subobject is still registered as a cooker EDL dependency. Working backwards, we traced it to FPackageHarvester::ProcessImport() calling UE::SavePackageUtilities::GetCDOSubobjects() before the first garbage collection pass during the commandlet’s run. We believe that this is the root cause of the issue but were unsure of a safe way to fix it, so we went with a workaround to avoid the situation entirely.