Event Dispatchers / Delegates Quick Start Guide

Quick Start for the Event Dispatcher / Delegate communication method.

Windows
MacOS
Linux

Choose your implementation method:

Blueprints

C++

Overview

Event Dispatchers are an Actor communication method where one Actor dispatches an event and other Actors that are listening to that event are notified.

Using this method, the notifying Actor creates an Event Dispatcher to which the listening Actors subscribe. This communication method uses a one to many relationship, where the working Actor triggers the Event Dispatcher and many listening Actors are notified.

Goals

In this Quick Start guide, you will learn how to use Event Dispatchers to create an OnBossDied event that will trigger on two Actors in your Level.

Objectives

  • Create the BossDied Actor that will create the Event Dispatcher.

  • Create a door Actor that will bind to the OnBossDied event.

  • Modify the Blueprint_Effect_Explosion Blueprint to bind to the OnBossDied event.

1 - Required Setup

  1. In the New Project Categories section of the menu, select Games and click Next.

    image alt text

  2. Select the Third Person template and click Next.

    image alt text

  3. Select the Blueprint and With Starter Content options and click Create Project.

    image alt text

Section Results

You have created a new Third Person project and are now ready to learn about Event Dispatchers.

2 - Creating the OnBossDied Event

  1. Right-click the Content Browser and click Blueprint Class under the Create Basic Asset section.

    image alt text

  2. Select Actor class as your Parent Class and name the Blueprint BP_BossDied.

    image alt text

    image alt text

  3. Open BP_BossDied in the Blueprint editor and from the Viewport, click the Add Component button then search for and select Box Collision.

    image alt text

  4. With the Box collision selected, change the scale to X = 4, Y = 4, and Z = 2.

    image alt text

  5. With the Box collision selected, go to the Rendering section of the Details panel and deselect the Hidden in Game checkbox. This will display the collision box during gameplay.

    image alt text

  6. Right-click the Box collision and select Add OnComponentBeginOverlap. You will see the node added to the Event Graph.

    image alt text

  7. From the My Blueprint panel on the left, navigate to the Event Dispatchers section and click + Add New to add a new event. Name this event OnBossDied.

    image alt text

  8. Drag OnBossDied to the Event Graph and select Call to add the node.

    image alt text

  9. Connect the On Component Begin Overlap node to the Call OnBossDied node. Compile and Save the Blueprint.

    image alt text

  10. Drag the BP_BossDied Blueprint into the Level.

    image alt text

Section Results

In this section you created the BP_BossDied Actor to simulate what would happen if a boss character died in your game. In this Actor you created the OnBossDied Event Dispatcher which will be used to signal to other Actors when this event is triggered.

3 - Creating an Interactive Door

  1. Right-click the Content Browser and click Blueprint Class under the Create Basic Asset section.

    image alt text

  2. Select the Actor class as your Parent Class and name the Blueprint BP_BossDoor.

    image alt text

  3. Open BP_BossDoor and from the Viewport click the Add Component dropdown then search for and select Static Mesh. Name the component Frame.

    image alt text

  4. Add another Static Mesh component and name it Door.

  5. Select the Frame component and from the Details panel click the Static Mesh dropdown then search for and select SM_DoorFrame.

    image alt text

  6. Repeat the step above for the Door component and add the SM_Door static mesh.

  7. With the Door component still selected, set the Y location to 45 as seen below. You should see the door aligned with the frame.

    image alt text

    image alt text

  8. Right-click the Event Graph then search for and select Add Custom Event. Name the event OpenDoor.

    image alt text

  9. Drag from the OpenDoor event then search for and select Add Timeline. Name the Timeline TM_Door.

    image alt text

  10. Double-click TM_Door to open it. Click on the Add Float Curve button to add a Float Track and name it Alpha. Set the length to 1.0.

    image alt text

  11. Right-click the graph and select Add key to CurveFloat_1 to add a new point. Set the Time and Value to 0.0.

    image alt text image alt text

  12. Repeat the steps above to add another point with Time and Value set to 1.0.

  13. Go back to the Event Graph and drag the Door Static Mesh component into the Event Graph to create a node. Drag from the Door node then search for and select SetRelativeRotation.

    image alt text

  14. Connect the Update pin from TM_Door to the SetRelativeRotation node. Right-click the New Rotation pin and select Split Struct Pin.

    image alt text

  15. Right-click the Event Graph then search for and select Lerp Float. Connect the Return Value to the Yaw pin on the SetRelativeRotation node. Connect the Alpha pin from TM_Door to the Alpha pin on the Lerp node. Lastly, set the value of B to 90.0 as shown below.

    image alt text

  16. Add a new variable by clicking the + button next to the Variable section. Name the variable BossDiedReference.

    image alt text

  17. On the Details panel click the Variable Type dropdown then search for and select the Object Reference of BP_BossDied. Check the Instance Editable checkbox.

    image alt text

    image alt text

  18. Drag BossDiedReference to the Event Graph and select Get BossDiedRerence. From the node, drag then search for and select Bind Event to On Boss Died.

    image alt text

  19. From the red Event pin of Bind Event to On Boss Died, drag then search for and select Add Custom Event. Name the event BossDied.

    image alt text

  20. From the BossDied event node, drag then search for and select Open Door. Connect Event Begin Play to the Bind Event to On Boss Died node as seen below.

    image alt text

  21. Compile and Save the Blueprint.

Section Results

In this section you created an interactive door Actor that binds to the On Boss Died Event Dispatcher found in the BP_BossDied Actor. This binding occurs on Begin Play, but is executed at runtime whenever this event is triggered by BP_BossDied.

4 - Creating an Interactive Explosion

  1. Go to Starter Content > Blueprints and select Blueprint_Effect_Explosion. Drag it into your gameplay folder and select Copy Here.

    image alt text

    image alt text

  2. Open Blueprint_Effect_Explosion in the Blueprint editor. From the Viewport, select the P_Explosion component and on the Details panel go to the Activation section and disable Auto Activate.

    image alt text

  3. Repeat the step above for the Explosion Audio component.

  4. Add a new variable by clicking the + button next to the Variable section. Name the variable BossDiedReference.

    image alt text

  5. From the Details panel click the Variable Type dropdown then search for and select the Object Reference of BP_BossDied. Check the Instance Editable checkbox.

    image alt text

    image alt text

  6. From the Event Graph right-click then search for and select Event Begin Play.

  7. Drag BossDiedReference to the Event Graph and select Get BossDiedReference. From the node, drag then search for and select Assign On Boss Died. Name the custom event BossDied.

    image alt text

  8. Connect Event Begin Play to the Bind Event to Boss Died node.

    image alt text

[REGION:note} When you select the Assign option for the Event Dispatcher, a binding will be created as well as a custom event. [/REGION}

  1. Drag the P_Explosion and Explosion Audio components to the Event Graph. Drag from P_Explosion then search for and select Activate. Connect Explosion Sound to the Target pin of the Activate node.

  2. Connect the BossDied event node to the Activate node.

    image alt text

  3. Compile and Save the Blueprint.

Section Results

In this section you modified Blueprint_Effect_Explosion to activate when the OnBossDied event is executed.

5 - Testing the Event Dispatcher

  1. Drag the BP_BossDoor Actor into your Level. Go to the Details panel and click the Boss Reference Died dropdown then search for and select BP_BossDied.

    image alt text

    image alt text

  2. Drag several instances of Blueprint_Effect_Explosion into your Level. Go to the Details panel and click the Boss Reference Died dropdown then search for and select BP_BossDied.

    image alt text

    image alt text

  3. Press Play and walk over the BP_BossDied trigger to simulate your boss dying in the game.

    image alt text

Section Results

In this section you tested the BP_BossDoor and Blueprint_Effect_Explosion Actors in the Level. You confirmed that each Actor responds to the OnBossDied event when the BP_BossDied Actor triggers it.

In this guide you learned how to use Event Dispatchers to communicate between one working Actor to many target Actors. You also learned how to create Event Dispatchers and how to bind Actors to the event in order to trigger specific functionality.

Next Steps

Now that you know how to use Event Dispatchers, take a look at the other types of communication referenced in the Actor Communication documentation page.

Overview

Delegates can call methods in Actor class Blueprints in a type-safe way. A delegate can be bound dynamically to form a communication where one Actor triggers an event on another Actor that is listening to be notified for that event.

See Delegates for additional documentation.

Goals

In this Quick Start guide, you will learn how to use Delegates to create an OnBossDied event that will trigger two Actor class Blueprints in your Level.

Objectives

  • Create the Boss Actor that will contain an OnBossDied Delegate.

  • Create an interactive door Actor with a timeline component that will bind to the OnBossDied event.

1 - Required Setup

  1. In the New Project Categories section of the menu, select Games and click Next.

    image alt text

  2. Select the Third Person template and click Next.

    image alt text

  3. Select the C++ and With Starter Content options and click Create Project.

    image alt text

Section Results

You have created a new C++ Third Person project and are now ready to learn about Delegates.

2 - Creating the Boss Actor and OnBossDied Delegate

  1. From the C++ Class Wizard, create a new Actor class named BossActor.

    image alt text

  2. Navigate to your BossActor.h. Underneath your library includes, declare the following Delegate.

    DECLARE_DELEGATE(FOnBossDiedDelegate);
  3. In your class defaults, declare the following

    protected:
        UFUNCTION()
        void HandleBossDiedEvent();
        UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
        class UBoxComponent* BoxComp;
        virtual void NotifyActorBeginOverlap(AActor* OtherActor);
    
    public:
        FOnBossDiedDelegate OnBossDied;
  4. Navigate to your BossActor.cpp and add the following class library.

    #include "Components/BoxComponent.h"
  5. Implement the following class definitions.

    ABossActor::ABossActor()
    {
        BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp"));
        BoxComp->SetBoxExtent(FVector(128, 128, 64));
        BoxComp->SetVisibility(true);
    }
    
    void ABossActor::HandleBossDiedEvent()
    {
        OnBossDied.ExecuteIfBound();
    }
    
    void ABossActor::NotifyActorBeginOverlap(AActor* OtherActor)
    {
        HandleBossDiedEvent();
    }
  6. Compile your code.

  7. From the C++ Classes folder, right-click your BossActor, then from the C++ Class Actions dropdown menu, select Create Blueprint class based on BossActor. Name your Blueprint class BP_BossActor.

    image alt text

  8. Drag an instance of your BossActor into the Level.

    image alt text

Finished Code

BossActor.h

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BossActor.generated.h"

DECLARE_DELEGATE(FOnBossDiedDelegate);
UCLASS()

class BPCOMMUNICATION_API ABossActor : public AActor
{
    GENERATED_BODY()

public: 

    // Sets default values for this actor's properties
    ABossActor();

protected:

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
    UFUNCTION()
    void HandleBossDiedEvent();
    UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
    class UBoxComponent* BoxComp;
    virtual void NotifyActorBeginOverlap(AActor* OtherActor);

public: 

    // Called every frame
    virtual void Tick(float DeltaTime) override;
    FOnBossDiedDelegate OnBossDied;
};

BossActor.cpp

#include "BossActor.h"
#include "Components/BoxComponent.h"
#include "BPCommunicationGameMode.h"

// Sets default values
ABossActor::ABossActor()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
    BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp"));
    BoxComp->SetBoxExtent(FVector(128, 128, 64));
    BoxComp->SetVisibility(true);
}

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

void ABossActor::HandleBossDiedEvent()
{
    OnBossDied.ExecuteIfBound();
}

void ABossActor::NotifyActorBeginOverlap(AActor* OtherActor)
{
    HandleBossDiedEvent();
}

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

Section Results

In this section you created the BossActor class, which contains a Box Component, and Delegate for a OnBossDied event, which will be used to signal other Actor classes when the event has been executed.

3 - Creating an Interactive Door

  1. From the C++ Class Wizard, create a new Actor class named DoorActor.

  2. Navigate to your DoorActor.h file and declare the following include:

    #include "Components/TimelineComponent.h"
  3. Then declare the following class definitions.

    // Variable to hold the Curve asset
        UPROPERTY(EditInstanceOnly)
        UCurveFloat* DoorTimelineFloatCurve;
    
    protected:
    
        void BossDiedEventFunction();
        UPROPERTY(EditInstanceOnly,BlueprintReadWrite)
        class ABossActor* BossActorReference;
    
        //MeshComponents to represent Door assets
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* DoorFrame;
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* Door;
    
        //TimelineComponent to animate Door meshes
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        UTimelineComponent* DoorTimelineComp;
    
        //Float Track Signature to handle our update track event
        FOnTimelineFloat UpdateFunctionFloat;
    
        //Function which updates our Door's relative location with the timeline graph
        UFUNCTION()
        void UpdateTimelineComp(float Output);
  4. Inside of DoorActor.cpp declare the following class library.

    #include "BossActor.h"
  5. Implement the following class definitions.

    ADoorActor::ADoorActor()
    {
        //Create our Default Components
        DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
        Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
        DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
    
        //Setup our Attachments
        DoorFrame->SetupAttachment(RootComponent);
        Door->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform);
        Door->SetRelativeLocation(FVector(0, 35, 0));
    }
    
    // Called when the game starts or when spawned
    void ADoorActor::BeginPlay()
    {
        Super::BeginPlay();
    
        //Binding our float track to our UpdateTimelineComp Function's output
        UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);
    
        //If we have a float curve, bind it's graph to our update function
        if (DoorTimelineFloatCurve)
        {
            DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);
        }
    
        if (BossActorReference)
        {
        BossActorReference->OnBossDied.BindUObject(this, &ADoorActor::BossDiedEventFunction);
        }
    }
    
    void ADoorActor::BossDiedEventFunction()
    {
        DoorTimelineComp->Play();
    }
    
    void ADoorActor::UpdateTimelineComp(float Output)
    {
        // Create and set our Door's new relative location based on the output from our Timeline Curve
        FRotator DoorNewRotation = FRotator(0.0f, Output, 0.f);
        Door->SetRelativeRotation(DoorNewRotation);
    }
  6. Compile your code.

  7. From the Content Browser, select Add/Import > Miscellaneous > Curve.

    image alt text

  8. Select CurveFloat and name your CurveFloat asset DoorCurveFloat, then double-click your DoorCurveFloat asset. Add two keys to your Float Curve and give one key the time-value (0,0), and the other key the time-value of (4,90).

    image alt text

  9. Shift-click to select both your keys, and set them to Auto Cubic interpolation, then save your Curve.

    image alt text

  10. Save your DoorCurveFloat.

  11. From the Content Browser, navigate to your C++ Classes folder, right-click your DoorActor class, then select Create Blueprint Class based on Door Actor. Name your Blueprint Actor Bp_DoorActor.

    image alt text

  12. Inside BP_DoorActor's class defaults, find the Components tab, and select the DoorFrame Static Mesh component, navigate to the Details panel and change the Static Mesh to SM_DoorFrame.

    image alt text

  13. Next, from the Components tab, select the DoorMesh component. Navigate to the Details panel and change the static mesh to SM_Door. image alt text

  14. From the Details panel, select DoorCurveFloat from the Door Timeline Float Curve dropdown menu.

    image alt text

  15. Compile and save your Blueprint.

Finished Code

DoorActor.h

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TimelineComponent.h"
#include "DoorActor.generated.h"

UCLASS()
class BPCOMMUNICATION_API ADoorActor : public AActor
{   
    GENERATED_BODY()

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

    // Variable to hold the Curve asset
    UPROPERTY(EditInstanceOnly)
    UCurveFloat* DoorTimelineFloatCurve;

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
    void BossDiedEventFunction();
    UPROPERTY(EditInstanceOnly,BlueprintReadWrite)
    class ABossActor* BossActorReference;

    //MeshComponents to represent Door assets
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* DoorFrame;
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* Door;

    //TimelineComponent to animate Door meshes
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UTimelineComponent* DoorTimelineComp;

    //Float Track Signature to handle our update track event
    FOnTimelineFloat UpdateFunctionFloat;

    //Function which updates our Door's relative location with the timeline graph
    UFUNCTION()
    void UpdateTimelineComp(float Output);

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;
};

DoorActor.cpp

#include "DoorActor.h"
#include "BossActor.h"

// Sets default values
ADoorActor::ADoorActor()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    //Create our Default Components
    DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
    Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
    DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));

    //Setup our Attachments
    DoorFrame->SetupAttachment(RootComponent);
    Door->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform);
    Door->SetRelativeLocation(FVector(0, 35, 0));
}

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

    //Binding our float track to our UpdateTimelineComp Function's output
    UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);

    //If we have a float curve, bind its graph to our update function
    if (DoorTimelineFloatCurve)
    {
        DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);
    }
if (DoorTimelineFloatCurve)
    {
        BossActorReference->OnBossDied.BindUObject(this, &ADoorActor::BossDiedEventFunction);
    }
}

void ADoorActor::BossDiedEventFunction()
{
    DoorTimelineComp->Play();
}

void ADoorActor::UpdateTimelineComp(float Output)
{
    // Create and set our Door's new relative location based on the output from our Timeline Curve
    FRotator DoorNewRotation = FRotator(0.0f, Output, 0.f);
    Door->SetRelativeRotation(DoorNewRotation);
}

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

Section Results

In this section you created an interactive DoorActor that binds to the OnBossDied Event Dispatcher found in the BossActor class. This binding occurs in Begin Play, but is executed at runtime whenever this event is triggered by an overlap in BossActor's Box Component.

5 - Testing the Event Dispatcher

  1. Drag the BP_Door Blueprint into your Level. Go to the Details panel and click the Boss Reference Died dropdown and search for and select BP_BossDied.image alt text

  2. With your Bp_DoorActor selected, navigate to the Details panel, click the Boss Actor Reference dropdown arrow, then search for and select BP_BossActpr.

  3. Press Play and walk over the BP_BossActor trigger to simulate your boss dying in the game.

    image alt text

Section Results

In this section you tested the BP_DoorActor in the Level. You confirmed that the Actor responds to the OnBossDied event when the BP_BossActor's Box Component overlaps with another Actor to trigger the Delegate.

In this guide you learned how to use Delegates to communicate between multiple Actor class Blueprints.

Next Steps

Now that you know how to use Delegates, take a look at the other communication types referenced in the Actor Communication documentation page.

Help shape the future of Unreal Engine documentation! Tell us how we're doing so we can serve you better.
Take our survey
Dismiss