I’d suggest to use an Interface in that case, as it gives you at least some type safety while still allowing you to use a regular typed C++ function pointer to a member function (although, to be honest, I consider that part of the C++ syntax horrible…).
However, if you’d prefer to use type erasure and want to use UE4 types (what I’d recommend, as those interact properly with UE4’s memory management), I’d suggest a regular DECLARE_DELEGATE_whatever
, as those are probably the most simple type unreal offers for that purpose. I’d bind the function using the AddUObject(object, function)
syntax, as this will keep a weak pointer to the object on which the function should be called, and will not call the function if the object has been destroyed.
And just to give you a short reminder:
DECLARE_DELEGATE_*
: A C++ only delegate, to which only one function can be bound at a time
DECLARE_MULTICAST_DELEGATE_*
: A list of delegates for C++ only. Meaning an arbitrary number of functions can be bound.
DECLARE_DYNAMIC_*
: A string based delegate, meant to be used with Blueprint
*_Retval*
: A delegate with return value (of course only makes sense for non-multicast delegates).
DECLARE_EVENT_*
: Just like a delegate, but can only be broadcast by the owning class.