Download

C++ Components NULL when accessed via Blueprint (sometimes)

Hello,

I have a number of components in C++ that are used to encapsulate some logic.

About 50% of the time, these work fine, the other 50% they are NULL when blueprint tries to access them. This feels like a race condition to me, but it could also be that I am doing something incorrectly.


UPROPERTY(VisibleDefaultsOnly , BlueprintReadOnly, Category = AWK)
UConditionComponent* ConditionComponent;

UPROPERTY(VisibleDefaultsOnly , BlueprintReadOnly, Category = AWK)
UExperienceComponent* ExperienceComponent;



ConditionComponent = CreateDefaultSubobject<UConditionComponent>(TEXT("ConditionComponent"));
ExperienceComponent = CreateDefaultSubobject<UExperienceComponent>(TEXT("ExperienceComponent"));



UCLASS(ClassGroup = (Custom), Blueprintable, meta = (BlueprintSpawnableComponent, AllowPrivateAccess = "true"))
class TESTCREATENEWPROJECT_API UConditionComponent : public UActorComponent
{
GENERATED_BODY()

public:
// Sets default values for this component's properties
UConditionComponent();

The components show up ok in the Component List of the actor owner and can be dragged into the BP editor and accessed in design time OK.

Any ideas?

Thanks

I’ve seen many discussions about this issue, unfortunately no definitive answer. For some reason the components seem to get reset and stored as nullptrs in the Blueprint default object from time to time. It thought this is more likely to happen if the component properties are marked as editable, but if yours have always been just VisibleDefaultsOnly, then that’s not it either :confused:

In any case this can usually be fixed by renaming the property or recreating the Blueprint, but I don’t know if it is possible to avoid this from happening completely (other than maybe not exposing the components to BP at all) or what exactly triggers it. I usually use VisibleAnywhere (or no) access for components now and haven’t had this issue since, but that doesn’t seem like it should make a difference compared to VisibleDefaultsOnly.

This is one of several reasons why I now believe that the usual pattern of “implement class in C++, edit properties for it in child Blueprints” is maybe not such a good idea after all.

Components have the RF_ArchetypeObject flag and it’s only safe to access them after AActor::PostInitializeComponent was executed, a little before BeginPlay() is called.

Thanks - I’m coming to the same conclusion. The background is that I had changed the properties, started having these issues, recreated the direct child blueprint, thought it all fixed, but then it started happening again. Given the randomness of it, I had thought it a race condition.

What would be a better approach? Putting my component logic into the actors themselves (ie pulling it out of the components)?

Thanks - I was triggering access via human input once the actors were in the world, so sadly I don’t think it’s that :frowning: Would component replication play a role here? (Long shot)