Creating a multicast delegate

The standard delegates used so far in this chapter are essentially a function pointer—they allow you to call one particular function on one particular object instance. Multicast delegates are a collection of function pointers, each potentially on different objects, that will all be invoked when the delegate is broadcast.

Getting ready

This recipe assumes you have followed the initial recipe in the chapter, as it shows you how to create TriggerVolume that is used to broadcast the multicast delegate.

How to do it...

  1. Add a new delegate declaration to the GameMode header:
    DECLARE_MULTICAST_DELEGATE(FMulticastDelegateSignature)
  2. Create a new Actor class called MulticastDelegateListener. Add the following to the declaration:
    UFUNCTION()
    void ToggleLight();
    UFUNCTION()
    virtual void EndPlay(constEEndPlayReason::Type EndPlayReason) override;
    
    UPROPERTY()
    UPointLightComponent* PointLight;
    
    FDelegateHandleMyDelegateHandle;
  3. In the class implementation, add this to the constructor:
    PointLight = CreateDefaultSubobject<UPointLightComponent>("PointLight");
    RootComponent = PointLight;
  4. In the MulticastDelegateListener.cpp file, add #include "UE4CookbookGameMode.h" between your project's include file and the MulticastDelegateListener header include. Inside the MulticastDelegateListener::BeginPlay implementation, add the following:
    Super::BeginPlay();
    UWorld* TheWorld = GetWorld();
    if (TheWorld != nullptr)
    {
      AGameMode* GameMode = UGameplayStatics::GetGameMode(TheWorld);
      AUE4CookbookGameMode * MyGameMode = Cast<AUE4CookbookGameMode>(GameMode);
      if (MyGameMode != nullptr)
      {
        MyDelegateHandle  = MyGameMode->MyMulticastDelegate.AddUObject(this, &AMulticastDelegateListener::ToggleLight);
      }
    }
  5. Implement ToggleLight:
    void AMulticastDelegateListener::ToggleLight()
    {
      PointLight->ToggleVisibility();
    }
  6. Implement our EndPlay overridden function:
    void AMulticastDelegateListener::EndPlay(constEEndPlayReason::Type EndPlayReason)
    {
      Super::EndPlay(EndPlayReason);
      UWorld* TheWorld = GetWorld();
      if (TheWorld != nullptr)
      {
        AGameMode* GameMode = UGameplayStatics::GetGameMode(TheWorld);
        AUE4CookbookGameMode * MyGameMode = Cast<AUE4CookbookGameMode>(GameMode);
        if (MyGameMode != nullptr)
        {
          MyGameMode->MyMulticastDelegate.Remove(MyDelegateHandle);
        }
      }
    }
  7. Add the following line to TriggerVolume::NotifyActorBeginOverlap():
    MyGameMode->MyMulticastDelegate.Broadcast();
  8. Compile and load your project. Set the GameMode in your level to be our cookbook game mode, then drag four or five instances of the MulticastDelegateListener into the scene.
  9. Step into TriggerVolume to see all the MulticastDelegateListener toggle their light's visibility.

How it works...

  1. As you might expect, the delegate type needs to be explicitly declared as a multicast delegate rather than a standard single-binding one.
  2. Our new Listener class is very similar to our original DelegateListener. The primary difference is that we need to store a reference to our delegate instance in FDelegateHandle.
  3. When the actor is destroyed, we safely remove ourselves from the list of functions bound to the delegate by using the stored FDelegateHandle as a parameter to Remove().
  4. The Broadcast() function is the multicast equivalent of ExecuteIfBound(). Unlike standard delegates, there is no need to check if the delegate is bound either in advance or with a call like ExecuteIfBound. Broadcast() is safe to run no matter how many functions are bound, or even if none are.
  5. When we have multiple instances of our multicast listener in the scene, they each register themselves with the multicast delegate implemented in the GameMode.
  6. Then, when the TriggerVolume overlaps a player, it broadcasts the delegate, and each Listener is notified causing them to toggle the visibility of their associated point light.
  7. Multicast delegates can take parameters in exactly the same way that a standard delegate can.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.125.139