How can I create BP events from c++ without needing to bind them in BP?

I’m trying to make events that get triggered from c++ code, execute some c++ code, and then execute an event in blueprint. Should function just as AActor::BeginPlay() does, and I don’t want to have to “bind” things to the event in blueprint.
But, the blueprint event isn’t the same delegate as my UProperty, and isn’t getting called when my delegate is dispatched.

My code so far:

Weapon.h:

#pragma once

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

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBPDelegate);

UCLASS()
class TRAVELER_API AWeapon : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AWeapon();

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat)
		float Damage;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat)
		bool StopOnClank;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat)
		bool IsAttacking;


	UPROPERTY(EditAnywhere,BlueprintAssignable, Category = "Combat")
		FBPDelegate Start;
	UFUNCTION()
	virtual void Start_Implementation();
	UPROPERTY(EditAnywhere,BlueprintAssignable, Category = "Combat")
		FBPDelegate End;
	UFUNCTION()
	virtual void End_Implementation();
	UPROPERTY(EditAnywhere,BlueprintAssignable, Category = "Combat")
		FBPDelegate Clank;
	UFUNCTION()
	virtual void Clank_Implementation();
};

Weapon.cpp:

#include "Weapon.h"


AWeapon::AWeapon()
{
	PrimaryActorTick.bCanEverTick = true;
}

void AWeapon::BeginPlay()
{
	Super::BeginPlay();
	Start.AddDynamic(this, &AWeapon::Start_Implementation);
	End.AddDynamic(this, &AWeapon::End_Implementation);
	Clank.AddDynamic(this, &AWeapon::Clank_Implementation);


// for testing only
	End.Broadcast();
}

void AWeapon::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
}

void AWeapon::Start_Implementation()
{
	IsAttacking = true;
}

void AWeapon::End_Implementation()
{
	IsAttacking = false;
}

void AWeapon::Clank_Implementation()
{
	End.Broadcast();
}

Blueprint:

As you can see, the events do appear as “event dispatchers” in BP, and I can drag them in and select “Event”. But, unlike BeginPlay(), I need to bind these events before they can be called, and I can’t call them from C++.

Of course, after a couple of days of having the problem, I post the question, and then ten minutes later figure out the solution… -_-

I mismatched my UFUNCTIONs, and shouldn’t be using delegates here.

Taking a page from Actor.h, void BeginPlay() is a c++ function, which can be called from blueprint. Then, a function declaration, void ReceiveBeginPlay(), is made, and is given a display name in BP of “Begin Play”. None of this involves delegates. So now, when BP calls the event, it calls BeginPlay(), which executes c++ code, and then calls ReceiveBeginPlay(), which is implemented via BP code. C++ code still calls BeginPlay(), too.

My code now looks like this:

Weapon.h:

#pragma once

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

//DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBPDelegate);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBPDelegate);

UCLASS()
class TRAVELER_API AWeapon : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AWeapon();

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat)
		float Damage;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat)
		bool StopOnClank;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat)
		bool IsAttacking;


protected:
	//these are the "events" in BP
	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Start"))
		void Start_BP();
	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "End"))
		void End_BP();
	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Clank"))
		void Clank_BP();

public:
	//these are both the called c++ functions, and the functions called from BP
	UFUNCTION(BlueprintCallable, Category = "Combat")
		virtual void Start();
	UFUNCTION(BlueprintCallable, Category = "Combat")
		virtual void End();
	UFUNCTION(BlueprintCallable, Category = "Combat")
		virtual void Clank();
};

Weapon.cpp:

#include "Weapon.h"


AWeapon::AWeapon()
{
	PrimaryActorTick.bCanEverTick = true;
}

void AWeapon::BeginPlay()
{
	Super::BeginPlay();
	End_BP();
}

void AWeapon::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
}

void AWeapon::Start()
{
	IsAttacking = true;
	Start_BP();
}

void AWeapon::End()
{
	IsAttacking = false;
	End_BP();
}

void AWeapon::Clank()
{
	End();
Clank_BP();
}

Side note: I was only able to do this on Actors, not ActorComponents. Not sure why.