Download

Creating component in an UObject referenced by another object causes unexpected behaviour

Situation goes like this:

I have an actor component called UBuffComponent. It holds pointers to UBuff objects derived from UObject. UBuff on construction creates it’s own component UStatsComponent. I expect to be able to add BuffComponent to an actor and then add Buffs to it, each containing it’s own stats component. What actually happens is that those UStatComponents for some reason get registered with whatever actor holds UBuffComponent and remain even when Buff itself is erased (and after ading and removing few buffs everything crashes). Can anyone tell me what an I doing wrong here?

My code goes like this:

UBuffComponent.h



UCLASS(Blueprintable, editinlinenew, BlueprintType, ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class TWINSTICK_API UBuffComponent : public UActorComponent
{
	GENERATED_BODY()

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

	// Called when the game starts
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;

protected:

	/**
	* Buff container
	*/
	UPROPERTY(EditAnywhere, Instanced, BlueprintReadWrite, Category = "Container")
	TArray<class UBuff*> Buffs;


UBuffComponent.cpp



// Sets default values for this component's properties
UBuffComponent::UBuffComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	bWantsBeginPlay = true;
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}


// Called when the game starts
void UBuffComponent::BeginPlay()
{
	Super::BeginPlay();

	for (UBuff* buff : Buffs)
	{
		buff->SetBuffComponent(this);
		buff->Activate();
	}

	// ...
	
}

// Called every frame
void UBuffComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
	Super::TickComponent( DeltaTime, TickType, ThisTickFunction );

	for (UBuff* buff : Buffs)
	{
		buff->Update(DeltaTime);
	}
	// ...
}

Buff.h


UCLASS(Blueprintable, editinlinenew, BlueprintType, ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class TWINSTICK_API UBuff : public UObject
{
	GENERATED_BODY()

public:

	/**
	* Default constructor
	*/
	UBuff(const FObjectInitializer& ObjectInitializer);

	/**
	* Setter for the component that holds the buff
	*/
	UFUNCTION(BlueprintCallable, Category = "BuffFunctions")
	void SetBuffComponent(class UBuffComponent* aBuffComponent);

protected:
	/**
	* Buff component buff is attached to
	*/
	UPROPERTY(EditAnywhere, Instanced, BlueprintReadWrite, Category = "Container")
	class UBuffComponent* BuffComponent;
	
	/**
	* Stats to apply to affecting object
	*/
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
	class UStatsComponent* Stats;




UBuff::UBuff(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	BuffComponent = nullptr;
	AttatchPointName = NAME_None;
	Timeout = 0;

	Stats = CreateDefaultSubobject <class UStatsComponent>("Stats");
}

void UBuff::SetBuffComponent(UBuffComponent * aBuffComponent)
{
	BuffComponent = aBuffComponent;
}


Problem solved. I forgot to add a call to Super() in BuffComponent Constructor