YuHang’s Blog

Unreal新手笔记(三)——网络代理

Unreal中如何进行网络传输,以及一些源码分析,希望能为你提供一些帮助

开头写点啥

Unreal十分奇特的一点在于,有些代码写在客户端,有些代码跑在服务器,hmm..编程的时候需要十分清楚,这个变量是不是跑在你想要的地方的,它对于需要同步的网络数据做了很好的封装,今天就看一下网络代理这边的代码

怎么用

在学习什么原理之前首先看看怎么使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//声明:
// 定义代理类型
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCharacterKilledTipsDelegate, FKilledTipsBlock, BlockData);
这个宏的定义是这样的;
// 声明一个代理的实例,也就是发起广播的实例
UPROPERTY(BlueprintAssignable, Category = STExtraDelegate)
FOnCharacterKilledTipsDelegate OnKilledTips;
// 同步数据的定义,ReplicatedUsing 表示当这个属性改变的时候,使用哪个方法通知客户端
UPROPERTY(EditAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_KillTipsNotify, Category = STExtraBaseCharacter)
FKilledTipsBlock BlockData;
//实现:
// 通知所有客户端
DOREPLIFETIME(ASTExtraBaseCharacter, BlockData);
// 在被调用的时候进行广播
void ASTExtraBaseCharacter::OnRep_KillTipsNotify() {
if (USTExtraDelegateMgr::STExtraDelegateMgrInstance()->OnKilledTips.IsBound())
{
USTExtraDelegateMgr::STExtraDelegateMgrInstance()->OnKilledTips.Broadcast(BlockData);
}
}

怎么实现的

先看第一句声明,进入到它的实现中是这样的:

1
2
3
4
5
#define DECLARE_DYNAMIC_DELEGATE_OneParam( DelegateName, Param1Type, Param1Name )
BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE)
FUNC_DECLARE_DYNAMIC_DELEGATE( FWeakObjectPtr, DelegateName,
DelegateName##_DelegateWrapper, FUNC_CONCAT( Param1Type InParam1 ),
FUNC_CONCAT( *this, InParam1 ), void, Param1Type )

在BODY_MACRO_COMBINE部分将文件ID与代理绑定了起来,看样子是想做一个签名之类的东西,确定代理的发出者。之后的FUNC_DECLARE_DYNAMIC_DELEGATE部分应该是多播代理的具体实现了。通过FUNC_CONCAT整理的参数格式。

在声明的时候填的参数会成为一个BaseDynamicDelegate的子类实例
在构造里面接受参数之后调用自己的execute方法,看到广播是任意输入安全的,已经检查过IsBound了,在外面不用做可用性检查了。

紧接着在内联函数的源文件里,看到了具体的实现
可以看到多播其实是使用单播实现的。。。。
通过维护单播的列表进行add,remove进行对于多播池的维护。这里可以发现多播并不能保证数据的发送顺序