Bootstrap

UE4 C++利用反射UFUNCTION实现RPC

 

项目要实现一个RPC的功能。调用服务器函数很简单,使用泛型蓝图节点然后解析里面的FPerperty类型序列化后传给服务器。这部分可以参考我之前的文章“蓝图Structure与Json的读写”解析类型。

本篇写的是服务器调用客户端函数。把即服务端发送一段buffer,客户端反序列化这段buffer,然后把里面的数据解析成函数名,参数1,参数2,参数…… 的形式来调用客户端的函数。这里的一个问题主要是,项目使用的不是UE4服务端,所以远程调用难以调用某个具体的对象,只能调用到静态函数。静态函数一般想到静态函数库,所以使用静态函数库来实现。

使用蓝图函数库的函数有一个概念,就是其实每一个蓝图函数库的函数都带一个默认的参数就是World Context Object。

World Context Object的解释:

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,然后调用到蓝图函数库里的具体函数

 

二、

;