欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

集成平行云 数据通道 C++ sdk 到UE4

程序员文章站 2022-06-15 09:29:57
1新建c++ 项目 (我用的是4.25.4版本的引擎)2新建第三方库插件3不着急 关掉UE4界面,在Browser窗口空白地方右键,创建c++类4经过综合考虑,还是Component组件比较合适5记得要选插件的Runtime6如果出现报错不要怕,正常显现,此时关闭UE4工程,关闭VS7打开D:\SVN_Local\MyProject\Plugins\PXYDataChannel\Source\ThirdParty\PXYDataChannelLibrary....

1新建c++ 项目  (我用的是4.25.4版本的引擎)

集成平行云 数据通道 C++  sdk 到UE4

2新建第三方库插件

集成平行云 数据通道 C++  sdk 到UE4集成平行云 数据通道 C++  sdk 到UE4

3不着急 关掉UE4界面,在Browser窗口空白地方右键,创建c++类

集成平行云 数据通道 C++  sdk 到UE4

4经过综合考虑,还是Component组件比较合适

集成平行云 数据通道 C++  sdk 到UE4

5记得要选插件的Runtime

集成平行云 数据通道 C++  sdk 到UE4

6如果出现报错不要怕,正常显现,此时关闭UE4工程,关闭VS

集成平行云 数据通道 C++  sdk 到UE4

7打开D:\SVN_Local\MyProject\Plugins\PXYDataChannel\Source\ThirdParty\PXYDataChannelLibrary

删除以下文件并将平行云提供的SDK放到指定文件夹

集成平行云 数据通道 C++  sdk 到UE4

集成平行云 数据通道 C++  sdk 到UE4          集成平行云 数据通道 C++  sdk 到UE4

集成平行云 数据通道 C++  sdk 到UE4             集成平行云 数据通道 C++  sdk 到UE4

8对着 “ MyProject.uproject”  文件右键,重新生成VS文件,并等待进度条走完

集成平行云 数据通道 C++  sdk 到UE4

9重新打开VS工程,找到PXYDataChannelLibrary.Build.cs

集成平行云 数据通道 C++  sdk 到UE4

10 修改PXYDataChannel.cpp 文件

集成平行云 数据通道 C++  sdk 到UE4

11此时编译,报错

集成平行云 数据通道 C++  sdk 到UE4

12 在 PXYDataChannel.Build.cs 文件的 PrivateDependencyModuleNames.AddRange 中添加依赖

"CoreUObject",
                "Engine",
                "Slate",
                "SlateCore",

再次编译,正常通过。

集成平行云 数据通道 C++  sdk 到UE4

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文件中最后的部分

集成平行云 数据通道 C++  sdk 到UE4

当然,还要在.cpp 中的构造函数中初始化记录一下实例指针

集成平行云 数据通道 C++  sdk 到UE4

之后就可以通过实例指针来调用UE4组件中的非静态函数了,这样就达到了第三方回调函数 调用委托,在蓝图内显示收到的数据的 效果

集成平行云 数据通道 C++  sdk 到UE4

15  使用方法 工程中随便建个Actor蓝图,add component 中选择PXYDataChannel。添加之后选中这个组件,在右侧EventGraph 视图里右键,选择 对应的Event即可,此时若通过第三方给我们发送数据,这个回调函数就会显示收到的数据

集成平行云 数据通道 C++  sdk 到UE4

 

16测试结果 

集成平行云 数据通道 C++  sdk 到UE4

 

 

 

 

本文地址:https://blog.csdn.net/u011407338/article/details/112846890