I have an actor in C++ that creates a number of components in it’s constructor, like so:
UCLASS(HideCategories = ("Replication", "Actor Tick", "Actor", "Input"))
class PERSISTENCE_API AMyClass : public AActor
{
GENERATED_BODY()
public:
AMyClass ();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MyClass")
UBoxComponent* TriggerVolume = nullptr;
...
};
AMyClass::AMyClass()
{
PrimaryActorTick.bCanEverTick = false;
...
TriggerVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerVolume"));
TriggerVolume->SetBoxExtent(FVector(50.f, 50.f, 10.f));
TriggerVolume->SetCollisionObjectType(ECC_WorldStatic);
TriggerVolume->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
TriggerVolume->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
TriggerVolume->SetCollisionResponseToChannel(ECC_PlayerCharacter, ECollisionResponse::ECR_Ignore);
TriggerVolume->SetCollisionResponseToChannel(ECC_Camera, ECollisionResponse::ECR_Ignore);
TriggerVolume->SetCanEverAffectNavigation(false);
TriggerVolume->SetupAttachment(DefaultSceneRoot);
}
I then have a number of blueprints based on this actor, which mostly just tweak settings, meshes etc. on the existing components, to create the specific instances of this class.
When packaging with nativize assets, the game asserts when running the package. The assert hit is here:
UObjectGlobals.cpp line 3714
UE_LOG(LogClass, Fatal, TEXT("Default subobject %s %s already exists for %s."), *OverrideClass->GetName(), *SubobjectFName.ToString(), *Outer->GetFullName());
.
[2017.03.15-18.04.56:622][547]LogHAL:Error: appError called: Assertion failed: Assertion failed: [File:F:\work\projects\unreal\415\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp] [Line: 3714] Default subobject BoxComponent TriggerVolume already exists for BP_MyBlueprintClass_C /Game/Objects/BP_MyBlueprintClass.Default__BP_MyBlueprintClass_C.
Looking at the code generated by the nativizer for this blueprint, I can indeed see that there are duplicate components being created with the same name, as both my C++ game code, and the nativized blueprint generated code, are trying to create the component. The constructor generated by the nativizer contains this snippet:
ABP_MyBlueprintClass_C__pf1991454251::ABP_MyBlueprintClass_C__pf1991454251(const FObjectInitializer& ObjectInitializer) : Super()
{
if(HasAnyFlags(RF_ClassDefaultObject) && (ABP_MyBlueprintClass_C__pf1991454251::StaticClass() == GetClass()))
{
ABP_MyBlueprintClass_C__pf1991454251::__CustomDynamicClassInitialization(CastChecked<UDynamicClass>(GetClass()));
}
auto __Local__8 = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerVolume"));
auto& __Local__9 = (*(AccessPrivateProperty<FVector >((__Local__8), UBoxComponent::__PPO__BoxExtent() )));
__Local__9 = FVector(20.000000, 50.000000, 10.000000);
i.e. both constructors are creating the TriggerVolume component.
There are a number of other components in the class that are declared and constructed in exactly the same way, which the nativizer correctly deduces and accesses in its generated constructor like so:
auto __Local__15 = CastChecked<UBoxComponent>(GetDefaultSubobjectByName(TEXT("CollisionVolume")));
I can’t see any difference between the components that work and the component that doesn’t, so I can’t see anything to change on the game side to try remedy the issue.
Note that the only package I’ve checked for this is a PS4 development build (everything seems fine in a shipping build, where the assert is defined out, though I guess in this case perhaps there just are duplicates of this component but everything manages to work okay regardless).
Thanks for reading this far!