项目要实现一个RPC的功能。调用服务器函数很简单,使用泛型蓝图节点然后解析里面的FPerperty类型序列化后传给服务器。这部分可以参考我之前的文章“蓝图Structure与Json的读写”解析类型。
本篇写的是服务器调用客户端函数。把即服务端发送一段buffer,客户端反序列化这段buffer,然后把里面的数据解析成函数名,参数1,参数2,参数…… 的形式来调用客户端的函数。这里的一个问题主要是,项目使用的不是UE4服务端,所以远程调用难以调用某个具体的对象,只能调用到静态函数。静态函数一般想到静态函数库,所以使用静态函数库来实现。
使用蓝图函数库的函数有一个概念,就是其实每一个蓝图函数库的函数都带一个默认的参数就是World Context Object。
World Context Object的解释:
A World Context Object is any UObject that can get back to a UWorld object. In the case of the Actor Blueprint, the blueprint editor can simply use that actor as the World Context Object, by passing that actor to GetWorldFromContextObject
所以UObjcet下才不能调用需要WorldContextObject的函数。
同理,在C++上调用蓝图函数库的函数,需要在最后的位置加上World Context Object参数
.h代码
enum BufferType
{
Enum_NULL,
Enum_TRUE,
Enum_FlASE,
Enum_BYTE,
Enum_INT16,
Enum_UINT16,
Enum_INT32,
Enum_UINT32,
Enum_FLOAT,
Enum_DOUBLE,
Enum_FSTRING,
Enum_TABLE,
};
struct BufferOffset
{
BufferType Type;
int32 ForwardOffset;
int32 Size;
};
UCLASS(BlueprintType, Blueprintable)
class My_API ParseBuffer final: public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
UObject* WorldContextAnchor;
UPROPERTY(BlueprintReadWrite)
UClass* CallFunctionClass;
UFUNCTION(BlueprintCallable)
void ProcessMethod(TArray<uint8> Data);
int32 IterateThroughPropery(FProperty* PropertyPtr, uint8* ParamPtr, const uint8* pbyBuf, int32 nBufSize, int32 Len);
bool CheckProperty(FProperty* Property, BufferType Type);
private:
int32 LoadBuffer2ProcessMethod(const uint8* pbyBuf, int32 nBufSize);
BufferOffset GetufferValueOffset(const uint8* pbyBuf, int32 nBufSize);
FString FunctionName;
TArray<FString> TempStrArray;
};
创建一个继承ParseBuffer的蓝图,WorldContexAnchor和CallFunctionClass在蓝图里赋值,BP Function Library是一个蓝图写的蓝图函数库。WorldContexAnchor就是调用蓝图函数库函数需要的参数World Context Object
(注意,这个GetGameInstanceWithoutContext是一个C++蓝图函数库函数,是因为在UObject下是难以获得game instance成员而扩展的)
一、
void ParseBuffer::ProcessMethod(TArray<uint8> Data)
{
if (Data.Num() <= 0)
{
return;
}
LoadBuffer2ProcessMethod(Data.GetData(), Data.Num());
}
调用ProcessMethod函数解析Buffer,然后调用到蓝图函数库里的具体函数
二、