集成平行云 数据通道 C++ sdk 到UE4
1新建c++ 项目 (我用的是4.25.4版本的引擎)
2新建第三方库插件
3不着急 关掉UE4界面,在Browser窗口空白地方右键,创建c++类
4经过综合考虑,还是Component组件比较合适
5记得要选插件的Runtime
6如果出现报错不要怕,正常显现,此时关闭UE4工程,关闭VS
7打开D:\SVN_Local\MyProject\Plugins\PXYDataChannel\Source\ThirdParty\PXYDataChannelLibrary
删除以下文件并将平行云提供的SDK放到指定文件夹
8对着 “ MyProject.uproject” 文件右键,重新生成VS文件,并等待进度条走完
9重新打开VS工程,找到PXYDataChannelLibrary.Build.cs
10 修改PXYDataChannel.cpp 文件
11此时编译,报错
12 在 PXYDataChannel.Build.cs 文件的 PrivateDependencyModuleNames.AddRange 中添加依赖
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
再次编译,正常通过。
13 将c++ 例子中的代码移植到UE4 component 组件中
PXYDataChannelComponent.h
include "LarkXRDataChannel.h"
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "PXYDataChannelComponent.generated.h"
static const char* P_Component_Data;
UENUM(BlueprintType)
enum class p_data_type : uint8
{
DATA_STRING = 0,
DATA_BIN = 1,
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FMuitDynamicDelegate, p_data_type, type, FString, dataText);
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UPXYDataChannelComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UPXYDataChannelComponent();
UPROPERTY(EditAnywhere, BlueprintReadWrite, BlueprintAssignable, Category = "Events|P")
FMuitDynamicDelegate p_MuitDynamicDelegate;
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
/* taskid, receive from command param with exe start */
UPROPERTY(EditAnywhere, Category = "P")
FString Command_taskid;
UPROPERTY(VisibleAnywhere, Category = "P")
FString PXY_ReceiveData;
/*
datachannel接口都是异步的
lr_client_start 返回成功只是说明接口创建成功
是否连接成功需要看接口调用的回调函数,如果失败了 请查看on_disconnected的参数
*/
UFUNCTION(BlueprintCallable, Category = "P")
static int PXY_Client_Start(FString TaskID);
/*
lr_client_send 发送字符串 时请 请保证 字符串是utf8编码,长度算上\0
发送成功 返回值为发送的长度
失败 请查看返回值
*/
UFUNCTION(BlueprintCallable, Category = "P")
static int PXY_Client_SendText(FString SendData);
UFUNCTION(BlueprintCallable, Category = "P")
static int PXY_Client_SendBinary(TArray<uint8> SendData);
/*
结束调用lr_client_stop
*/
UFUNCTION(BlueprintCallable, Category = "P")
static void PXY_Client_Stop();
static void cc_on_connected();
//回调事件,接收到数据时调用此函数
static void cc_on_data(data_type type, const char* data, int size);
static void cc_on_disconnected(enum ErrorCode code);
static UPXYDataChannelComponent* pThis;//静态对象指针
};
UPXYDataChannelComponent* UPXYDataChannelComponent::pThis = NULL;
PXYDataChannelComponent.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PXYDataChannelComponent.h"
// Sets default values for this component's properties
UPXYDataChannelComponent::UPXYDataChannelComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
pThis = this;
// ...
}
// Called when the game starts
void UPXYDataChannelComponent::BeginPlay()
{
Super::BeginPlay();
// ...
}
// Called every frame
void UPXYDataChannelComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
int UPXYDataChannelComponent::PXY_Client_Start(FString TaskID)
{
if (TaskID == "")
{
TaskID = "123456";
}
if (XR_SUCCESS != lr_client_start(TCHAR_TO_ANSI(*TaskID), cc_on_connected, cc_on_data, cc_on_disconnected))
{
return -1;
}
return 0;
}
int UPXYDataChannelComponent::PXY_Client_SendText(FString SendData)
{
int sendsize;
sendsize = lr_client_send(DATA_STRING, TCHAR_TO_ANSI(*SendData), SendData.Len());
return sendsize;
}
int UPXYDataChannelComponent::PXY_Client_SendBinary(TArray<uint8> SendData)
{
int sendsize = 0;
/*for (int32 i = 0; i < SendData.Num(); i++)
{
sendsize = lr_client_send(DATA_BIN, (const char*)SendData[i], sizeof(SendData[i]));
}*/
//sendsize = lr_client_send(DATA_BIN, (const char*)SendData[0], sizeof(SendData));
/*
const TArray<const char*> Content;
for (int32 i = 0; i < Content.Num(); i++)
{
sendsize = lr_client_send(DATA_BIN, Content[i], sizeof(Content[i]));
}
*/
//sendsize = lr_client_send(DATA_BIN, (CHAR*)SendData, sizeof(SendData));
return sendsize;
}
void UPXYDataChannelComponent::PXY_Client_Stop()
{
lr_client_stop();
}
void UPXYDataChannelComponent::cc_on_connected()
{
UE_LOG(LogTemp, Warning, TEXT("data channel connected!"));
}
void UPXYDataChannelComponent::cc_on_data(data_type type, const char* data, int size)
{
if (type == DATA_STRING)
{
P_Component_Data = data;
pThis->p_MuitDynamicDelegate.Broadcast(p_data_type::DATA_STRING, ANSI_TO_TCHAR(data));//回调函数中调用非静态成员函数
UE_LOG(LogTemp, Warning, TEXT("接收到数据:recv data string:%s size:%d"), ANSI_TO_TCHAR(data), size);
}
else {
UE_LOG(LogTemp, Warning, TEXT("接收到数据:recv data binary: size :%d"), size);
}
}
void UPXYDataChannelComponent::cc_on_disconnected(enum ErrorCode code)
{
UE_LOG(LogTemp, Warning, TEXT("data channel disconnected!"));
}
14 其中比较重要的是委托的实现,第三方示例中用的是C函数,一般是静态函数,无法直接调用UE4组件里的函数,反之,UE4组件里的函数也无法直接调用静态函数,因此UE4组件必须实例化一个,或者记录一个实例化指针。
即 .h文件中最后的部分
当然,还要在.cpp 中的构造函数中初始化记录一下实例指针
之后就可以通过实例指针来调用UE4组件中的非静态函数了,这样就达到了第三方回调函数 调用委托,在蓝图内显示收到的数据的 效果
15 使用方法 工程中随便建个Actor蓝图,add component 中选择PXYDataChannel。添加之后选中这个组件,在右侧EventGraph 视图里右键,选择 对应的Event即可,此时若通过第三方给我们发送数据,这个回调函数就会显示收到的数据
16测试结果
本文地址:https://blog.csdn.net/u011407338/article/details/112846890