CreateDefaultSubobject with UObject

As far as I understand rather important not only initialize objects but also attach it to some parent component, to avoid the object being immediately deleted. But Ubject derived classes don’t have any special functions for that. Seems to save reference as UPROPERTY should be enougth, or not? I got None, nullptr of this property when trying to get this reference in BP, is it bug or I just missing something?

UCLASS()
class PROCEDURALTREE_API ATreeRoot : public AActor
{
	GENERATED_BODY()

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Genesis")
	UTreeGenesis* Genesis; // UTreeGenesis inherited from UObject

public:
	ATreeRoot();
}

ATreeRoot::ATreeRoot()
{
	PrimaryActorTick.bCanEverTick = true;
	Genesis = CreateDefaultSubobject<UTreeGenesis>(TEXT("GenesisInstance"));
}

Yes, a UPROPERTY keeps an object reference alive (unless it’s a TWeakPtr<>)

1 Like

Nevertheless, if I make a blueprint of the inheritor, the inheritor will overwrite this property in its constructor with nullptr. So I decided to write const getter with c++ mutable specifier instead.

class PROCEDURALTREE_API ATreeRoot : public AActor
{
	GENERATED_BODY()

protected:
	UPROPERTY(VisibleDefaultsOnly)
	mutable UTreeGenesis* Genesis;

public:
	ATreeRoot();
	UFUNCTION(BlueprintPure, Category = "Genesis")
	UTreeGenesis* GetGenesis() const;
}

UTreeGenesis* ATreeRoot::GetGenesis() const {
	if (!Genesis) Genesis = NewObject<UTreeGenesis>();
	return Genesis;
}

The Blueprint doesn’t have to overwrite the field. It may do that, if you have an existing blueprint and add a new property, but a new blueprint created after you already have the object in the base, should not overwrite that, as far as I know.

1 Like

I should not, you right. I recompiled c++ source several times, with differnet specifiers, so it might me cashed somewhere and didn’t updated even if I make some changes in cpp. Anyway getter seems to be good alternative.