UPROPERTY member vars reset to NULL by ObjectInitializer

4.7.3 - still there

We are also experiencing this on 4.7.3.
What our arrangement boils down to is really simple (pseudocode-ish for brevity).

I asked cmartel for help in PM and later decided to move the conversation here.

Thank you for pointing that out, I didn’t know that. But we are not overriding the component.
Our issue is exactly like described here or here. We haven’t had our project upgraded from 4.3.1 in a loong time, and this issue started appearing only when we introduced StatComponent (on the same engine version).
Our Character-derived assets seem to have been corrupted with null references and most of them (or all) had an empty StatsComponent tab in the editor. Any code access to StatsComponent outside of constructor code resulted in an obvious crash. I tried to fix this by doing what chaosgrind describes (setting Component uproperty to EditAnywhere, BlueprintReadWrite, then resetting assets to their default, then modifying back to VisibleAnywhere, BlueprintReadOnly) to find out that I couldn’t reset the component variable from None - there were no alternative choices. Removing StatsComponent from the game entirely was of little help - Stats Component variable on instances was greyed out and set to ‘None’.
Eventually, after some heavy tinkering, updating the engine, tinkering and saving a bit more and finally giving up and re-creating assets, StatsComponent started to spawn correctly for a few launches. Then it broke again.
What I (and many others) found out was that the value for the new component pointer has been overwritten by the Blueprint class CDO. (testTriangleWander is a Bot blueprint)

I couldn’t reproduce the issue on a clean game with this class inheritance arrangement. My next guess is cyclic dependencies in blueprints, but I haven’t yet found any. Is casting to Bot inside Character blueprint considered a cyclic dependency?
Also, I should mention that I have occasional failures on saving a map (externally referenced error) or a blueprint (same here, externally referenced material instances mostly). But these are easy as pie to fix. Sometimes I have “LogUObjectGlobals:Warning: Failed to find object ‘Class None.’” logged to me once but I haven’t tracked it down yet.
I’m workin on this for about 3 days straight and the deeper I go, the more cryptic it seems to me. I have decided to take a break from this issue for a day before trying harder :slight_smile: I am now compiling the bleeding edge engine for rurther testing.

Text version of pseudocode for convenience:



//StatsComponent.h
class UStatsComponent : public UActorComponent
{
	GENERATED_BODY()
public:
	UStatsComponent(const class FObjectInitializer& ObjectInitializer);
	/** character stats, with items and power-ups applied. */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Stats)
	class URPGStats* Stats; //bare UObject child
}

//StatsComponent.cpp
UStatsComponent::UStatsComponent(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	Stats = NewObject<URPGStats>(this);
	check(Stats); //always valid
}

//MyCharacter.h
class AMyCharacter : public ACharacter
{
	GENERATED_BODY()
public:
	/** Character stats managing component */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Stats)
	class UStatsComponent* StatsComponent;
}

//MyCharacter.cpp
AMyCharacter::AMyCharacter(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	StatsComponent = ObjectInitializer.CreateDefaultSubobject<UStatsComponent>(this, TEXT("CharacterStats"));
	check(StatsComponent); //always valid here
}

//MyBot.h
class AMyBot : public AMyCharacter
{
	GENERATED_BODY()
public:
	AMyBot(const class FObjectInitializer& ObjectInitializer);
protected:
	void BeginPlay() override;
}

//MyBot.cpp
AMyBot::AMyBot(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	check(StatsComponent); //always valid
}

void AMyBot::BeginPlay()
{
	check(StatsComponent); //!CRASH
}


1 Like