Problems spawning sounds attatched to a component.

You can use UPROPERTY, but make it Transient so it can’t be loaded as nullptr when the engine serializes it from some BP class with broken references.

You likely don’t need default values from Blueprints to be kept on the nested component, as Blueprints can’t even access those from the components panel. So the workaround here is to not allow the engine to replace that UPROPERTY at all by adding the Transient tag to it: UPROPERTY(Transient). Again, the actual fix is to not use nested components.


The real issue here, though, is just having nested components.

Notice the Default on the parent component. That’s the ClassDefaultObject instance of the Blueprint archetype for the component being instanced. This problem usually arises from nested components, where CreateDefaultSubobject is called from inside another component.

Avoid nested components like the plague

First of all, avoid nested components. When using the parent component directly in Blueprint classes, the SimpleConstructionScript (SCS) systems are unaware of the nested component. A lot of important functionality related to serialization, parenting and networking is missed on the nested component when instancing it from its Blueprint template (archetype).

On serialization and cooking, the nested component is treated as a generic sub-object, and its properties are copied straight from its archetype in FObjectInitializer::InitProperties, without awareness of component hierarchy, registration order and whatnot. That happens just after the parent component’s constructor. Non-transient UPROPERTY pointers on the nested component, like AttachParent, get overridden, copied straight from the archetype, resulting on the instanced nested component pointing to the other archetype components, instead of its sibling instances.

If one insists on having nested components

There’s a workaround for the AttachParent issue specifically. Set the nested component’s AttachParent after the parent component’s constructor, before AttachToParent() is called by the nested component’s OnRegister().

PostInitProperties() is called right after properties are copied on the parent component’s sub-objects, but before any component registration, when they get actually attached to the parent from SetupAttachment().

void UNPCAttractorComponent::PostInitProperties()
{
  Super::PostInitProperties();
  OverlapComponent->SetupAttachment(this);
}

I saw some solutions to this with OnRegister(). Trying to fix this issue in the parent’s OnRegister() works only sometimes. OnRegister() order is not guaranteed, because it’s called by the owner Actor after all components have been instantiated, and the nested component could get registered before the parent.

An actual long-term solution

These are just some of the issues one might have to fix with nested components. Those will keep cropping up and the actual fix is to not have them at all. Components should be created directly by Actors and be stored on UPROPERTY fields. There’s SCS logic regarding those properties too.

Here’s a great small text on doing that while keeping most of the nested component related code within the parent component.