Components - Handling delegates with return values between c++ and blueprints

Hi there,

I have been writing some components for several gameplay interactions so we can freely use them on many different types of actors throughout a game.

I have run into a bit of an issue and am not sure how to get around it. I have some delegates with a return value, to help let anything use them.

For a delegate to by blueprint assignable it must be a multicast delegate (wont compile otherwise).
However a mutlicast delegate does not allow return value.

If you give it a non const reference parameter like bool& It throws a compile error: BlueprintAssignable delegates do not support non-const references at the moment.

Usually to get round that all that I create BlueprintImplementableEvents with the relevant property as a reference to be set in the blueprint to return to the code to do its thing. However component based events cannot be implemented in the blueprint . There are a few bugs around about that (eg https://answers.unrealengine.com/questions/210255/how-would-i-create-an-event-on-an-actorcomponent-t.htm or https://answers.unrealengine.com/questions/259969/blueprint-implementable-custom-component-events.html)

This leaves me with very little options. Obviously I could create a code class which just had the component and exposed its own BlueprintImplementableEvent to talk to it, but that means I lose the power of the component and it makes it harder when trying to use an actor which wants a few different ones.

Another option is to just create structs and special vars the blueprint could set to override/change behaviours.

I was wondering a few things

  1. Since events can have parameters which are by reference, why does BlueprintAssignable not support by ref non const variables?

  2. I noticed that UMG created a whole system (Property Binding) to get around this very problem, to allow blueprints to have functions bound which return things. Is this something that could be potentially used elsewhere? How hard would this be to replicate?

  3. Is there any plan to allow us to override the events of the components?

  4. If you were to write a special case system to get around this, to say set one variable, which method would you follow.

Has anyone else thought or come across a way around this issue, or have any thoughts on the matter?

I am running into the same issue. I’d like to have the owning Actor modify a damage float via a delegate instead of using interfaces. Looks like return values are still not available for these type of delegates in Blueprint…

Bump! This would be useful for me as well.

Same here, it would be really useful :frowning:

Hi. I’m not a core UE developer, but I have some answers and ideas how to play around this. At first as you wrote you using multicast delegate(s). Non-const references is impossible to use with multicast delegate just because it’s multicast - it can be invoked for many event listeners in a random order. If event listener changes a context it can broke something important for other listeners. But if you really need to change something inside master component inside events you can create a mock FStruct that will be acting as usual structure (and will be copied to the event context) but have a reference to the UObject you want to interact.

USTRUCT(BlueprintType)
struct TBRNRUNTIME_API FMockingContext
{
	GENERATED_BODY()

public:

	TWeakObjectPtr<UObject> ImpersonatingObject;
};

UCLASS()
class UMockingContextBlueprintLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintPure, Category = "Utility|MockingContext")
	static UObject* Impersonate(const FMockingContext& In) { return In.ImpersonatingObject.Get(); };

	UFUNCTION(BlueprintCallable, Category = "Utility|MockingContext")
	static void SetObject(UPARAM(ref) FMockingContext& In, UObject* Obj) { In.ImpersonatingObject = Obj; };
};

P.S. Maybe it will also work with Struct Box, but I didn’t test it.

1 Like