Edit: I found the solution, when I created blueprints of my new c++ classes I named them the same name as the c++ classes. So when I spawned them inside my gamemode blueprint I apparently choose the c++ classes and not the blueprints themselves. Thus the reason why the c++ code worked but the blueprints event were never called. So yeah, I was just being dumb.
It should be noted I’m not a c++ programmer, I’ve just been following Rama’s tutorial on creating a UDP A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums and I’ve gotten far enough that it nearly works. The only thing that doesn’t seem to work is that the event is never called in the blueprint. I’ve been trying to google for c++ event not being called in blueprint and I’m probably stupid or just missed something but I couldn’t find anything that helped me.
RamaUDPReceiver.h
UFUNCTION(BlueprintImplementableEvent, Category = "MyUDPSender")
void BPEvent_DataReceived(FAnyCustomData ReceivedData);
RamaUDPReceiver.cpp
ScreenMsg(Data.Name);
this->BPEvent_DataReceived(Data);
Here is the full code if that helps
RamaUDPReceiver.h
[SPOILER]
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Networking.h"
#include "MyProject.h"
#include "RamaUDPReceiver.generated.h"
UCLASS()
class ARamaUDPReceiver : public AActor
{
GENERATED_UCLASS_BODY()
//====================================================
// Data Received Events!
public:
/** Data has been received!! */
UFUNCTION(BlueprintImplementableEvent, Category = "MyUDPSender")
void BPEvent_DataReceived(FAnyCustomData ReceivedData);
//====================================================
public:
FSocket* ListenSocket;
FUdpSocketReceiver* UDPReceiver = nullptr;
void Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt);
UFUNCTION(BlueprintCallable, Category = "MyUDPSender")
bool StartUDPReceiver(
const FString& YourChosenSocketName,
const FString& TheIP,
const int32 ThePort
);
//ScreenMsg
FORCEINLINE void ScreenMsg(const FString& Msg)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
}
FORCEINLINE void ScreenMsg(const FString& Msg, const float Value)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %f"), *Msg, Value));
}
FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %s"), *Msg, *Msg2));
}
public:
/** Called whenever this actor is being removed from a level */
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
};
[/SPOILER]
RamaUDPReceiver.cpp
[SPOILER]
// Fill out your copyright notice in the Description page of Project Settings.
#include "RamaUDPReceiver.h"
#include "Async.h"
void ARamaUDPReceiver::BeginPlay()
{
// Call the base class
Super::BeginPlay();
}
ARamaUDPReceiver::ARamaUDPReceiver(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
ListenSocket = NULL;
}
void ARamaUDPReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
//~~~~~~~~~~~~~~~~
delete UDPReceiver;
UDPReceiver = nullptr;
//Clear all sockets!
// makes sure repeat plays in Editor dont hold on to old sockets!
if (ListenSocket)
{
ListenSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Rama's Start TCP Receiver
bool ARamaUDPReceiver::StartUDPReceiver(
const FString& YourChosenSocketName,
const FString& TheIP,
const int32 ThePort
) {
ScreenMsg("RECEIVER INIT");
ScreenMsg(TheIP);
ScreenMsg(FString::FromInt(ThePort));
//~~~
FIPv4Address Addr;
FIPv4Address::Parse(TheIP, Addr);
//Create Socket
FIPv4Endpoint Endpoint(Addr, ThePort);
//BUFFER SIZE
int32 BufferSize = 2 * 1024 * 1024;
ListenSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsNonBlocking()
.AsReusable()
.BoundToEndpoint(Endpoint)
.WithReceiveBufferSize(BufferSize);
;
FTimespan ThreadWaitTime = FTimespan::FromMilliseconds(100);
UDPReceiver = new FUdpSocketReceiver(ListenSocket, ThreadWaitTime, TEXT("UDP RECEIVER"));
UDPReceiver->OnDataReceived().BindUObject(this, &ARamaUDPReceiver::Recv);
UDPReceiver->Start();
ScreenMsg("UDP Receiver Initialized Successfully!!!");
return true;
}
void ARamaUDPReceiver::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
ScreenMsg("Received bytes", ArrayReaderPtr->Num());
FAnyCustomData Data;
*ArrayReaderPtr << Data; //Now de-serializing! See AnyCustomData.h
//BP Event
ScreenMsg(Data.Name);
this->BPEvent_DataReceived(Data);
}
[/SPOILER]
Thanks in advance.