Particle system component event catching in C++

I’ve made an actor class to represent a particle generator that I can spawn programmatically in the world. I use it to spawn blood particles when a bullet hits an enemy.

I created a simple blueprint that’s linked to the class and basically does nothing. The class has a UParticleSystemComponent member and the class sets it to the right particle emitter type. When I shoot an enemy, the particles are spawned successfully and everything looks good.

The problem is that I want to catch some events, in C++, that are outputted by the UParticleSystemComponent and do some logic. Mostly, I want to destroy the particle generator actor when the particles are done. I think I’ve done everything correctly in the code to wire this up, but the events are just never called. It actually seems like the UParticleSystemComponent member of my class isn’t the one being used to play the particle emitter. I don’t understand how that could be.

Can anyone tell me what’s wrong with my implementation? Also, what’s the best way to tell, in c++, when a particle generator is done and all its particles are dead? Does OnSystemFinished do it?

.h

#pragma once

#include "GameFramework/Actor.h"
#include "MyBloodParticle.generated.h"

UCLASS(config=Game)
class MYPROJECT_API AMyBloodParticle : public AActor
{
	GENERATED_BODY()
	
    UPROPERTY(VisibleDefaultsOnly, Category=Default)
	class UParticleSystemComponent* ParticleEmitter;

public:	
	// Sets default values for this actor's properties
	AMyBloodParticle();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

    UFUNCTION()
    void OnDeath(FName EventName, float EmitterTime, int32 ParticleTime, FVector Location, FVector Velocity, FVector Direction);

    UFUNCTION()
    void OnFinished(UParticleSystemComponent* PSystem);
};

.cpp

#include "MyProject.h"
#include "MyBloodParticle.h"

// Sets default values
AMyBloodParticle::AMyBloodParticle()
{
    ParticleEmitter = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleEmitter"));

    ConstructorHelpers::FObjectFinder<UParticleSystem> ReferenceVariable (TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Blood.P_Blood'"));
    if(ReferenceVariable.Succeeded())
    {
        ParticleEmitter->SetTemplate(ReferenceVariable.Object);
    }

    ParticleEmitter->OnParticleDeath.AddDynamic(this, &AMyBloodParticle::OnDeath);
    ParticleEmitter->OnSystemFinished.AddDynamic(this, &AMyBloodParticle::OnFinished);

    RootComponent = ParticleEmitter;

	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void AMyBloodParticle::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void AMyBloodParticle::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
}

void AMyBloodParticle::OnDeath(FName EventName, float EmitterTime, int32 ParticleTime, FVector Location, FVector Velocity, FVector Direction)
{
}

void AMyBloodParticle::OnFinished(UParticleSystemComponent* PSystem)
{
    Destroy();
}

It seems that my events were indeed called. I thought they weren’t called because I put breakpoints in them and they weren’t being hit. So, it works, but for some reason, I can’t debug code in events…

// Do it
FScriptDelegate Delegate;
Delegate.BindUFunction(this, FName(“OnFinished”));
ParticleEmitter->OnSystemFinished.AddUnique(Delegate);