Understanding a Delegates function signature

I’m implementing an OnHit function that will be bound to a dynamic multicast delegate.


Most tutorials have these parameters filled in (and they work ):

void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)

How does one know the correct parameters to feed the OnHit() function ?
Peeking into the declaration file for FComponentHitSignature I get the below signature for the function. Notice the UPrimitiveComponent* is in the “Fourth” place.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams( FComponentHitSignature, UPrimitiveComponent, OnComponentHit, UPrimitiveComponent*, HitComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, FVector, NormalImpulse, const FHitResult&, Hit );

How are we getting away without filling in the first 3 Parameters ?


In /Runtime/CoreUObject/Public/UObject/SparseDelegate.h

#define DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE( SparseDelegateClass, OwningClass, DelegateName ) ...
`#define DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam( SparseDelegateClass, OwningClass, DelegateName, Param1Type, Param1Name ) ...

And so on with two, three, four params…

1 Like

Thank you Emaer. Its clear now.

I’m trying to wrap my head around what’s going on under the hood with in C++ Events & Delegates. I know they have their roots in Function Pointers and have read up a few articles.
Would you know of some C++ article or tutorial that exposes what’s going on under the hood ?
I want to hit this topic from different directions in hopes of gaining insight on how the mechanism works under the hood.


That is the good thing about Unreal Engine, the hood is wide open just dive into the Delegate class.

1 Like

lol. I agree. Its better than the documentation as well !
I think I just have to ask more questions based on my findings in the Delegate class. It’s slightly intimidating but I’ll dig through it little by little.


@GarnerP57: Even with access to the source code, it’s not that clear and simple. If you look at the implementation of any delegates library for C++, the UE implementation looks…terrible.
Without knowing the idea behind, that whole delegates stuff is… yhh.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE macro expand to FUNC_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE, which expand to FUNC_DECLARE_DYNAMIC_MULTICAST_DELEGATE and define two structs, one derive from templated TSparseDynamicDelegate<...> which inherits from FSparseDelegate
In TSparseDynamicDelegate<...>:::GetDelegateOwner() function you can find hacky line:
UObject* DelegateOwner = reinterpret_cast<UObject*>((uint8*)this - OffsetToOwner);

AFAIK delegates in UE relies on reflection. Delegates won’t work if bounded function isn’t decorated with UFUNCTION macro. That’s why it’s so overcomplicated. (One of the many hidden costs of Blueprints)

1 Like

Thank you Emaer. My head is hurting now but I think I will get used to UE C++ in a year :stuck_out_tongue: