Ideally, I want to capture locallyVisibleData in a lambda and bind the lambda to my delegate. However, I have not found any way of doing this. How can I bind a lambda to dynamic multicast delegates?
One way to pass local data is by creating a dummy UObject that will hold locallyVisibleData, e.g.
Thanks for the pointer. This function is part of TBaseDelegate.
The āissueā is that dynamic multicast delegates inherits directly from TBaseDynamicMulticastDelegate which in turn inherits from TMulticastScriptDelegate. The BindLambda only is part of TBaseDelegate, which isnāt in that hierarchy tree.
On that note, there is a non-dynamic delegate declared using DECLARE_MULTICAST_DELEGATE.
That declares a class of type TMulticastDelegate<void, ā¦>. This void returning delegate has an AddLambda function. However, sadly, this type of event is not visible to blueprints⦠if you mark such a delegate with an UPROPERTY, the UHT complains that you must specify a UCLASS, USTRUCT or UENUM.
Iām just trying to find a way of exposing an event to both blueprints and C++ AND be able to use lambdas on it. One way to do it would be to declare two events: one dynamic multicast and one just multicast; then, the code just calls both events whenever itās triggered. However that solution leaves me quite unsatisfiedā¦
I stumbled upon the same issue. Is it really not possible to have a delegate that can be used in both BP world and from C++ by binding a lambda function to it?
I use BindWeakLambda because Iāve run into some really strange crashes before. Normally if you bind dynamically, it handles the object being destroyed as well.
Thereās still no answer to this? Iām also looking to bind a lambda to delegate shared between BP and C++. Any workaround besides doubling delegates?
Dynamic delegates store invocation lists as object pointer + function name to call. It is not possible to bind a lambda or pass additional parameters through a dynamic delegate.
I expected lambda binding to not be possible, unfortunately.
Creating two separate events is a viable solution of course. I was wondering what other solutions other developers found, or whether it even is an issue.
A thought I had the other day: maybe would be viable to support the two event approach with a dedicated macro; it simply declares a blueprint and native event: the native event receives one subscriber that triggers the blueprint event. I doubt itās worth to implement such a mechanism though, especially in smaller projects, due to its complexity.
Unfortunately you can not create such a macro yourself, because DECLARE_DYNAMIC_DELEGATE_* macros must be clearly written in the file for UHT to parse them and generate the dynamic delegate reflection info.
This is not a safe solution, that UObject can be garbage-collected at any time.
Delegates (both dynamic and non-dynamic) do not keep strong/reflected references to UObjects and therefore cannot keep them alive. As soon as the garbage collector does a pass, this will fail.
So long as those wrapper objects have a valid outer, then in that case the UPROPERTY() will keep them alive - but now you have object lifetimes to manage too, all for the sake of using a lambda (which is supposed to be convenient). It doesnāt make it any better of a solution IMO.
Everything else sets you up for failure and bugs. I donāt know why the most dangerous and wrong hack got the most likes in this thread. There were replies warning about it afterawards that were correct, trying to āwork aroundā the problem with hacks is just wrong. There is a reason things are not supported directly like that. Soā¦
Use two signature types and two events, broadcast them always together (write a helper function if needed to wrap them to follow DRY principle) and you re good! This is also several times done in UEās engine code itself.