TL;DR - How shall I create the Dynamic Single Delegate (with Return Value) within C++ in the way that will make this delegate possible to bind from Blueprints?
Context:
I wanted to override some of Component’s functionality within its owning Actor.
I’m already using Dynamic Multicast Sparse Delegates to extend Component’s functionality, so I thought that there should be a similiar Delegate type that would do a job.
After reading more about Delegates, I realized that Dynamic Single Delegate with Return Value is probably what I’m looking for.
According to the linked article and to the source, these are indeed Blueprint friendly.
/** Declares a blueprint-accessible delegate with return value that can only bind to one UNFUNCTION at a time */
#define DECLARE_DYNAMIC_DELEGATE_RetVal( ReturnValueType, DelegateName ) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) FUNC_DECLARE_DYNAMIC_DELEGATE_RETVAL( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, ReturnValueType, , FUNC_CONCAT( *this ), ReturnValueType )
My problem:
I just don’t know how to set this thing up in the right way. I’m not sure which UPROPERTY Specifiers shall I use for delegate property. I tried multiple things, and they don’t really work.
What I’ve tried:
Making delegate’s property “BlueprintAssignable”.
Sadly, this is only allowed for Multicast Delegates.
// this is inside class declaration:
public:
DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(bool, FTestDelegate, bool, Param)
UPROPERTY(BlueprintAssignable)
FTestDelegate TestDelegate;
Making delegate’s property “EditAnywhere” or “EditDefaultsOnly”.
This doesn’t seem to be supported. In this case, Delegate variable is just disabled in Details panel.
Making delegate’s property “BlueprintReadOnly” or “BlueprintReadWrite”.
This kidna seems to work. But this approach is very ugly. It’s hard to belive that delegates would be used in such way. This would also ment that assigned function won’t be known untill BeginPlay runs (which is big NO NO for me)
This would indeed avoid the need of using property specifiers on the Delegate itself.
However, if I understand right, the outcome is pretty much the same. You’re just providing your very own setter function, same as the one that would be generated automatically. Also, after all you gotta use a specifier on the BindSomeFunc, if you want to make it accessible from Blueprints.
Not a big fan of this solution, unless I’m missing something here. Please, tell me, if I do!