In this lesson, you will learn how to use Dynamic Delegates to broadcast specific information between decoupled gameplay systems at runtime.
Why Dynamic?
Previously, you learned about Multicast Delegates, which are excellent for simple event broadcasting. However, Dynamic Delegates take this a step further by allowing you to serialize the function binding. This means the engine can "remember" which function is connected to an event, even across saving/loading processes or when working within the Blueprint editor, where standard C++ delegates might lose their link.
The "Safe" Connection
The term "Safe" refers to the way dynamic delegates handle object lifetime. If an object (like a UI widget or an Actor) is destroyed while it is still bound to a dynamic delegate, the delegate system automatically detects that the target is no longer valid. Instead of crashing your game with a null pointer error, the delegate simply fails to execute the function.
This makes them perfect for modular systems, such as a Game Mode broadcasting a player's final score to a UI Scoreboard that might be created or destroyed as the match progresses.
Implementing the Delegate
To define a dynamic delegate that passes an integer (like a score), you declare it in your header file using the DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam macro:
// Define the delegate with a single integer parameter
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnScoreUpdated, int32, NewScore);
// Inside your class (e.g., GameMode)
UPROPERTY(BlueprintAssignable)
FOnScoreUpdated OnScoreUpdated;
By marking it as BlueprintAssignable, you make it visible in the editor, allowing designers to bind their own logic—like playing a sound effect or triggering an animation—whenever the score updates, without needing to modify your C++ code.
When you want to pass the data, you simply call the broadcast method:
OnScoreUpdated.Broadcast(CurrentScore);
This setup allows your Game Mode to remain completely unaware of the Scoreboard’s existence. The Game Mode simply shouts, "The score is now 50!" and any object listening to that specific delegate will receive that integer safely.
Key Takeaway: Dynamic delegates provide a robust, serialization-friendly way to broadcast data between actors while automatically managing the safety of the connection if the listening objects are destroyed.