前言
- 多图, 不想在源代码写注释, 不想贴代码块, 看的不清楚
- 版本4.21混4.22, 区别不大
- 文章属于旧有文章搬运, 之前在csdn上面
- 2019.10.27修改一版
物体位置信息同步, 或者说物体的移动同步, 是一个很大的坑, 从个人目前魔改UE4位置同步后, 感觉至少要考虑以下几点
- 位置信息的数据结构
- 要减少单次网络同步时的传输数据大小, 但也要包含所需要的完整的位置信息.
- 同时在降低精度的情况下减少一些数据的大小, 例如降低Location和Rotation的精度, 用更少的位数传播
- 位置信息的同步触发时间, 生成时间
- 指控制什么时候位置进行网络同步, 什么时候不需要同步. 以及什么时候生成需要同步的位置信息
- 位置信息的权威端
- 以哪一端或者哪里的物体位置, 当做最新位置同步, 作为权威端
- 如果权威端只在服务器, 那很简单.
- 如果权威端只在单一客户端, 服务器做验证处理, 此时逻辑也比较简单, 客户端发送位置到服务器, 服务器直接应用(不考虑防作弊, 防作弊的话此时权威端还是服务器, 实现会很复杂和麻烦)
- 如果权威端在多个客户端和服务器之间切换, 嗯, 坑很深....
- 接受到位置信息之后的处理, 减少网络传输的延迟频率丢失的一些位置信息带来的影响, 使得整个物体移动平滑, 例如游戏中的角色运动同步
- 这里面学问很深, 自行百度谷歌(找不到当初看学习的文章了)
- 判断位置同步信息是否有意义, 丢弃掉无用的位置信息
- 对旧的信息不做处理, 主要是解决网络的丢包, 延迟等带来的问题
- 对不是权威端的信息不做处理, 解决一些事件调用先后顺序有别, 状态同步不及时等等的时序问题
UE4 的位置同步是一个比较常用的功能, 实现也比较简单, 只是服务器当方向向客户端同步物体的位置信息.
下文将深扒一下位置同步的代码实现, 以及对一些有坑的地方进行描述.
关键函数和结构体信息
/** Returns the properties used for network replication */
virtual void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
// 在属性同步前调用的一个函数, 这里生成需要同步的位置信息, 并重写是否需要位置同步
/**
* Called on the actor right before replication occurs.
* Only called on Server, and for autonomous proxies if recording a Client Replay.
*/
virtual void AActo