[5.1] Can't destroy actor with call from child component,

We were having this warning thrown at us:
“Destroying object which doesn’t have a valid world pointer unreal”
When trying to destroy a character when it had 0 HP

We are controlling this value from a “stats” component (which will have relevant logic to other stats as well and will be used on other actors.

This is an extract of the code:

void UStatsComponent::TakeDamage(float Damage)
{
    this->CurrentHealth -= Damage;
    if(this->CurrentHealth <= 0)
        this->m_Parent->Death();
}

m_Parent is an internal variable of the type of the parent, this can be an interface or whatever you like, we were testing networking capabilities of our stats component (a bit more nuanced than a simple float hp stat) on a clean project and we came across this issue
the “death” parent function looks like

void AHotdogSoldier::Death_Implementation()
{
    // UE logs and stuff to print to screen
    this->Destroy();
}

Doing it this way we encountered the warning and the character wasn’t destroyed at all, it even went into negative hp if we kept hitting it…

Solution:
I remembered that on our main project we were using delegates:

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnZeroHP)

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class OPERATIONHOTDOG_API UStatsComponent : public UActorComponent
{
...
public:
...
	UPROPERTY(BlueprintAssignable, BlueprintCallable)
	FOnZeroHP OnZeroHP;
};

the take damage function from above would be:

void UStatsComponent::TakeDamage(float Damage)
{
    this->CurrentHealth -= Damage;
    if(this->CurrentHealth <= 0)
        this->OnZeroHP.Broadcast();
}

And on the Hotdog Soldier class:

void AHotdogSoldier::BeginPlay()
{
	Super::BeginPlay();
	this->HotDogStats->OnZeroHP.AddDynamic(this, &AHotdogSoldier::ServerDeath);
}

Now, here’s the question:
Even though we were able to get a solution, I would like to know what’s different between broadcasting the event and calling the death function directly from the component, I’m not really familiar with the delegate system part from the guts of the engine, nor why i can’t call a “Destroy” function from a child component.

EDIT: typo in some code, sorry

Hi imblackmagic1,

The first way you do it, the component calls it’s parents destroy which calls destroy components which destroys the component you’re calling it from…

1 Like

That makes sense, thanks for the answer, although I’m still a bit confused.

And how’s that different from using the broadcast? isn’t the broadcast doing the same thing as well?

like I said, I don’t know the ins and outs of the delegate system in the engine

I’m guessing that a multicast delegate system is issuing the destroy outside of the scope of both the actor and its components - plus it uses weak pointers so is able to skip objects already destroyed…

1 Like

thanks! I was thinking along the same lines

1 Like

Does it really work ? shouldn’t it be void AHotdogSoldier::Death_Implementation() ?
well, if it’s an Event with a default implementation.

sorry, it’s a typo, i typed the code from memory here

Ok :wink: