I want to subscribe to OnActorBeginOverlap using function pointer. I tried This:
void ATriggerTest::SetTouch(void (ATriggerTest::*func)(AActor*, AActor*))
{
OnActorBeginOverlap.AddDynamic(this, func);
}
But it crashes UE with error:
Assertion failed: Result && Result[2] != (TCHAR)'0' [File:E:\Dev\Unreal Engine\UE_5.0\Engine\Source\Runtime\Core\Public\Delegates\Delegate.h] [Line: 469]
'func' does not look like a member function
Is there a possibility to subscribe to this event using function pointer? If yes how to do this?
It has to be a member function like noted in another topic:
The function signature to bind to the OnActorBeginOverlap event should be: UFUNCTION() void OnOverlap(AActor* MyOverlappedActor, AActor* OtherActor);
The function that the pointer is pointing to looks like this:
void ATriggerTest::OnOverlapBegin(class AActor* OverlappedActor, class AActor* OtherActor)
{
// check if Actors do not equal nullptr and that
if (OtherActor && (OtherActor != this)) {
UE_LOG(LogTemp, Warning, TEXT("OBJECT OVERLAPPED\n"));
}
}
so it should be correct
I think this link describes it, in particular:
“The reason “&MyFrameGrabber::HookFunction” cannot be converted to a BUF_HOOK_FUNCTION_PTR is that, being a member of the class, it has implicitly as first parameter the “this” pointer, thus you cannot convert a member function to a non-member function: the two signatures look the same but are actually different.”
So why this doesn’t work:
void ATriggerTest::SetTouch()
{
auto foo = &ATriggerTest::OnOverlapBegin;
OnActorBeginOverlap.AddDynamic(this, foo);
}
but this does?:
void ATriggerTest::SetTouch()
{
OnActorBeginOverlap.AddDynamic(this, &ATriggerTest::OnOverlapBegin);
}
I think that i found out why is that. AddDynamic
gets argument name as string by using some macro magic and then passes it to this function located in delegate.h:
inline FName GetTrimmedMemberFunctionName(const TCHAR* InMacroFunctionName)
{
// We strip off the class prefix and just return the function name by itself.
check(InMacroFunctionName);
const TCHAR* Result = FCString::Strrstr( InMacroFunctionName, TEXT( "::" ) );
checkf(Result && Result[2] != (TCHAR)'0', TEXT("'%s' does not look like a member function"), InMacroFunctionName);
return FName(Result + 2);
}
If name doesn’t check out it throws error. Coming from Unity Engine and this is confusing as hell.
1 Like
Interesting! It looks like it’s pretty good a catching errors and wrong class types which has to be a good thing!