Hello.
Added UDP Component plugin (from here: GitHub - getnamo/UDP-Unreal: Convenience UDP wrapper for the Unreal Engine.) to my project and now im trying to bind a UFUNCTION HandleReceivedBytes (from my pawn class) to a Delegate event OnReceivedBytes (from this plugin).
.h file:
class UAVCESIUM_API AUavSimPawn : public APawn
{
GENERATED_BODY()
public:
AUavSimPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Utilities
UFUNCTION()
void HandleReceivedBytes(const TArray<uint8>& Bytes, const FString& IPAddress, const int32& Port);
// Components
UPROPERTY(VisibleAnywhere)
class UUDPComponent* UdpComp;
.cpp file:
AUavSimPawn::AUavSimPawn()
{
UdpComp = CreateDefaultSubobject<UUDPComponent>(TEXT("UdpComponent"));
UdpComp->Settings.bShouldAutoOpenReceive = false;
UdpComp->Settings.bShouldAutoOpenSend = false;
UdpComp->OpenReceiveSocket(TEXT("127.0.0.1"), 5228);
}
void AUavSimPawn::BeginPlay()
{
Super::BeginPlay();
// Binding a function for handling OnReceivedBytes delegate
// Exception happens here:
UdpComp->OnReceivedBytes.AddDynamic(this, &AUavSimPawn::HandleReceivedBytes);
The excpetion happens in “ScriptDelegates.h” in this line (556):
(void)ensure( InvocationList[ CurFunctionIndex ] != InDelegate )
from this code:
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
// Verify same function isn't already bound
const int32 NumFunctions = InvocationList.Num();
for( int32 CurFunctionIndex = 0; CurFunctionIndex < NumFunctions; ++CurFunctionIndex )
{
(void)ensure( InvocationList[ CurFunctionIndex ] != InDelegate ); // HERE
}
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
InvocationList.Add( InDelegate );
}
I figured out that this exception means that the function is already is in invokation list. Also i came to that point with debugger and yes, this function (“HandleReceivedBytes”) could be seen here before the function is actually added.
But i couldn’t find out why does it happens - i only have one call of function “AddDynamic” (put a breakpoint on it and it happened only once).
P.s. Also guess i should mention this one: if I put “AddDynamic” line in ctor of my Pawn class then the exception doesn’t appear but when i play it creates another copy of my Pawn and binds that HandleReceivedBytes method to it instead of an instance of my Pawn which is on a level.
upd: when using AddUniqueDynamic instead of AddDynamic the error does not appear but the function bound to delegate does not invokes. I noticed something strange. I added those two lines to check if OnReceivedBytes delegate already has any bound functions and with debugger I found out that it really has one - it’s my HandleReceivedBytes. I can’t understand how it could be already bound if I’m binding it after this check:
void AUavSimPawn::BeginPlay()
{
Super::BeginPlay();
if (UdpComp->OnReceivedBytes.IsBound())
UdpComp->OnReceivedBytes.Clear();
//UdpComp->OnReceivedBytes.AddDynamic(this, &AUavSimPawn::HandleReceivedBytes);
UdpComp->OnReceivedBytes.AddUniqueDynamic(this, &AUavSimPawn::HandleReceivedBytes); // Also tried AddUniqueDynamic just for overcoming the exception
}