I have built an environment using the VR Game Mode.
What I aim to do is receive coordinates (x, y, z) from the control of a robot arm in Unreal Engine’s virtual environment and have the real-world robot arm move according to those coordinates.
What I have in mind is to write the communication-related code using C++, turn it into a Blueprint, and then connect it with the existing controller coordinates for further processing.
I’ve created the client-side code so far. Could you provide feedback on it?
I plan to use C++ to create the Blueprint.
The Blueprint I’m making with C++ will handle socket communication with the manipulator’s controller computer, which operates on Python. I’ll write this in code, turn it into a Blueprint, and then use it.
In Unreal Engine, I have already successfully extracted the coordinates of the VR controller. Now, I want to create a socket communication system that will use the Blueprint I create to receive these coordinates and send the coordinate values (x, y, z) to the manipulator controller.
Here’s the code I have created:
// Copyright Epic Games, Inc. All Rights Reserved.
#include "MyBlueprintSocket.h"
// Sets default values
AMyBlueprintSocket::AMyBlueprintSocket()
: ClientSocket(nullptr), ServerPortNumber(0), bIsConnected(false)
{
PrimaryActorTick.bCanEverTick = false; // Disable ticking by default
}
// Called when the game starts or when spawned
void AMyBlueprintSocket::BeginPlay()
{
Super::BeginPlay();
}
bool AMyBlueprintSocket::InitializeSocket(const FString& ServerIP, int32 ServerPort)
{
// Store server details
ServerIPAddress = TEXT("113.198.234.193");
ServerPortNumber = 5000;
// Resolve the server address
ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
TSharedRef<FInternetAddr> RemoteAddress = SocketSubsystem->CreateInternetAddr();
bool bIsValidIP = false;
RemoteAddress->SetIp(*ServerIPAddress, bIsValidIP);
RemoteAddress->SetPort(ServerPortNumber);
if (!bIsValidIP)
{
UE_LOG(LogTemp, Error, TEXT("Invalid IP address."));
return false;
}
// Create the socket
ClientSocket = SocketSubsystem->CreateSocket(NAME_Stream, TEXT("VR Manipulator Socket"), false);
if (!ClientSocket)
{
UE_LOG(LogTemp, Error, TEXT("Failed to create socket."));
return false;
}
// Connect to the server
bIsConnected = ClientSocket->Connect(*RemoteAddress);
if (!bIsConnected)
{
UE_LOG(LogTemp, Error, TEXT("Failed to connect to server."));
CloseSocket();
return false;
}
UE_LOG(LogTemp, Log, TEXT("Socket successfully connected to %s:%d"), *ServerIPAddress, ServerPortNumber);
return true;
}
bool AMyBlueprintSocket::SendCoordinates(float X, float Y, float Z)
{
if (!bIsConnected || !ClientSocket)
{
UE_LOG(LogTemp, Error, TEXT("Socket is not connected."));
return false;
}
// Construct the coordinate data
FString CoordinateData = FString::Printf(TEXT("%f,%f,%f"), X, Y, Z);
TCHAR* DataToSend = CoordinateData.GetCharArray().GetData();
int32 DataSize = FCString::Strlen(DataToSend) * sizeof(TCHAR);
// Send the data
int32 BytesSent = 0;
bool bSuccess = ClientSocket->Send((uint8*)TCHAR_TO_UTF8(DataToSend), DataSize, BytesSent);
if (!bSuccess)
{
UE_LOG(LogTemp, Error, TEXT("Failed to send data."));
return false;
}
UE_LOG(LogTemp, Log, TEXT("Sent %d bytes: %s"), BytesSent, *CoordinateData);
return true;
}
void AMyBlueprintSocket::CloseSocket()
{
if (ClientSocket)
{
ClientSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ClientSocket);
ClientSocket = nullptr;
bIsConnected = false;
UE_LOG(LogTemp, Log, TEXT("Socket connection closed."));
}
}
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Networking.h"
#include "Sockets.h"
#include "SocketSubsystem.h"
#include "MyBlueprintSocket.generated.h"
UCLASS()
class DIGITAL_TWIN_API AMyBlueprintSocket : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyBlueprintSocket();
// Initializes the socket and connects to the server
UFUNCTION(BlueprintCallable, Category = "Socket")
bool InitializeSocket(const FString& ServerIP, int32 ServerPort);
// Sends coordinate data to the server
UFUNCTION(BlueprintCallable, Category = "Socket")
bool SendCoordinates(float X, float Y, float Z);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
private:
// Closes the socket connection
void CloseSocket();
// The socket used for communication
FSocket* ClientSocket;
// The IP address of the server
FString ServerIPAddress;
// The port used for communication
int32 ServerPortNumber;
// Indicates if the socket is connected
bool bIsConnected;
};
Please feel free to share any questions or point out anything that seems off!