BlueprintImplementableEvent function in a UBlueprintFunctionLibrary derived class?

I’m trying to implement an event that can be listened from anywhere (for game managers and things like mobile Ads, where I can receive an event once an Ad is cached, for example), while the focus is to listen it mainly from the level Blueprint.

The best approach seems declaring a function as BlueprintImplementableEvent, but then it only works if the class is an AActor. Why doesn’t it work in a UBlueprintFunctionLibrary or even UObject derived class?

So far the only thing that worked for me is creating a class derived from UObject, marking it as BlueprintType, creating an instance in the LevelBlueprint, then I can use multicast delegates. But it is looking a mess and doesn’t “feel right”, since a BlueprintImplementableEvent requires just one node and the instance approach is requiring around 6 nodes just before I can listen to the event.

Example code. In this case the OnAdCached doesn’t show up anywhere in the Blueprint editor:


UCLASS()
class UAdsManager: public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

	/** Add zone id */
	UFUNCTION(BlueprintCallable, Category = "Ads Test")
	static void InitAds(FName zoneId);
	
public:
	/** Called when an Ad is cached */
	UFUNCTION(BlueprintImplementableEvent, Category = "Ads Test")
	void OnAdCached(FName zoneId);
};

I wrote a similar topic before, but in there I am asking the best way to deal with the desired singleton/manager thing (still unaswered): How to broadcast delegates from static functions? And how to singletons/managers? - C++ Gameplay Programming - Unreal Engine Forums - anyone?

Do I have to end up creating an Ads AActor? Or keeping the UObject approach?

Any help would be appreciated.
Thanks.

BlueprintImplementableEvents can only be used in BPs that derive from that class. Because you don’t actually derive from a function library, you just call functions from it, that is why you can’t use that event. The approach from your other thread of using a delegate is probably the right one, that is the right mechanism for allowing an external party to register interest in an event. You need to register on an instance of a class though, and we never instance the function library classes, all functions are static.

You need to be careful with singleton patterns in Unreal, and think about situations like Play in Editor. Is your singleton designed to support multiple worlds coming and going (edited world, multiple played worlds for network testing)? Maybe the lifetime should be tied to one instance of the game, in which case using GameMode is probably a good place, as that is easy to access from everywhere.

Thanks, James! When you said maybe the lifetime should be tied to one instance of the game - it is exactly what I want to achieve.
So for the example situation of an Ads Manager, in which I have only one per game, is it better to hold a reference of it in the GameMode then?

Basically a good path would be?

  • AdsManager as an AActor or UObject?
  • Instantiate it in GameMode
  • Use delegates

Something we are currently working on, is an official advertising interface to make it easy to add and extend this particular subject.

You could have your ad actor sit on top of this new interface, or use this new interface as is. You will also be totally free to change, add a new one, or extend it! I just wanted to throw that out there in case it was useful :slight_smile: