Multi-cast delegates are a great way to broadcast an event to multiple objects who listen or subscribe to the event in question. They are particularly invaluable if you have a C++ module that generates events that potentially arbitrary Actors might want to be notified about. This recipe shows you how to create a multi-cast delegate in C++ that can notify a group of other Actors during runtime.
StaticMeshActor
class called King
. Add the following to the class header:DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnKingDeathSignature, AKing*, DeadKing);
UFUNCTION
to the class:UFUNCTION(BlueprintCallable, Category = King) void Die();
UPROPERTY(BlueprintAssignable) FOnKingDeathSignature OnKingDeath;
auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cone.Cone'")); if (MeshAsset.Object != nullptr) { GetStaticMeshComponent()->SetStaticMesh(MeshAsset.Object); GetStaticMeshComponent()->bGenerateOverlapEvents = true; } GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
Die
function:void AKing::Die() { OnKingDeath.Broadcast(this); }
Peasant
, also based on StaticMeshActor
.APeasant();
UFUNCTION(BlueprintCallable, category = Peasant) void Flee(AKing* DeadKing);
auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'")); if (MeshAsset.Object != nullptr) { GetStaticMeshComponent()->SetStaticMesh(MeshAsset.Object); GetStaticMeshComponent()->bGenerateOverlapEvents = true; } GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
.cpp
file:void APeasant::Flee(AKing* DeadKing) { GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Red, TEXT("Waily Waily!")); FVector FleeVector = GetActorLocation() – DeadKing->GetActorLocation(); FleeVector.Normalize(); FleeVector *= 500; SetActorLocation(GetActorLocation() + FleeVector); }
APeasant
called BPPeasant
.BeginPlay
node. Type get all
, and you should see Get All Actors Of Class. Select the node to place it in your graph.King
. You can type king
in the search bar to make locating the class in the list easier.Branch
node, and wire the execution pin of Branch
to our Get All Actors Of Class
node.Flee
.King
class into the level, then add a few BPPeasant
instances around it in a circle.BeginPlay,
and add a Delay
node. Set the delay to 5 seconds.King
instance selected in the level, right-click in the graph editor for the Level Blueprint.King
category for a function called Die
.Die
, then connect its execution pin to the output execution pin from the delay.StaticMeshActor
for convenience, as it saves us having to declare or create a Static Mesh component for the Actor
visual representation).DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam
macro. Dynamic multicast delegates allow an arbitrary number of objects to subscribe (listen) and unsubscribe (stop listening) so that they will be notified when the delegate is broadcast.King
that will allow us to tell it to die. Because we want to expose the function to Blueprints for prototyping, we mark it as BlueprintCallable
.DECLARE_DYNAMIC_MULTICAST_DELEGATE
macro that we used earlier only declared a type; it didn't declare an instance of the delegate, so we do that now, referencing the type name that we provided earlier when invoking the macro.BlueprintAssignable
in their UPROPERTY
declaration. This indicates to Unreal that the Blueprint system can dynamically assign events to the delegate that will be called when the delegate's Broadcast
function is called.King
so that it has a visual representation in the game scene.Die
function, we call Broadcast
on our own delegate. We specified that the delegate would have a parameter that is a pointer to the king which died, so we pass this pointer as a parameter to the broadcast function.If you want the king to be destroyed, rather than play an animation or other effect when it dies, you would need to change the delegate's declaration and pass in a different type. For example, you could use FVector
, and simply pass in the location of the dead king directly so that the peasants could still flee appropriately.
Without this, you potentially could have a situation where the King
pointer is valid when Broadcast
is called, but the call to Actor::Destroy()
invalidates it before your bound functions are executed.
StaticMeshActor
subclass, called Peasant
, we initialize the static mesh component as usual using, a different shape to the one that we used for the King
.Flee
function, we simulate the peasants playing sound by printing a message on the screen.SetActorLocation
is then used to actually teleport the peasants to that location.18.226.104.177