Unity3D——强联网实时PVP思路

网络层:

为了保证网络的稳定性,选择UDP+KCP协议的协议方式

业务层:

实现方案:

网络游戏同步方案主要有两种:状态同步帧同步

  • 状态同步:顾名思义,是指的将其他玩家的状态行为同步的方式,一帮情况下AI逻辑,技能逻辑,战斗计算都由服务器运算,只是将运算的结果同步给客户端,客户端只需要接受服务器传过来的状态变化,然后更新自己本地的动作状态、Buff状态,位置等就可以了,但是为了给玩家好的体验,减少同步的数据量,客户端也会做很多的本地运算,减少服务器同步的频率以及数据量。
  • **帧同步:**RTS游戏常采用的一种同步技术 ,上一种状态同步方式数据量会随着需要同步的单位数量增长,对于RTS游戏来讲动不动就是几百个的单位可以被操作,如果这些都需要同步的话,数据量是不能被接受的,所以帧同步不同步状态,只同步操作,每个客户端接受到操作以后,通过运算可以达到一致的状态(通过随机种子保证所有客户端随机序列一致),这样的情况下就算单位再多,他的同步量也不会随之增加。

方案优缺点:

下面我们从各种业务需求和性能上来分析一下这两个方案的优缺点,这样也有助于根据游戏的具体类型和需求来选择实现方式:

进行对比的需求 帧同步 状态同步
离线战斗和联网战斗并存 大部分的逻辑在于客户端,要求战斗逻辑部分与显示部分分离,甚至可以让逻辑部分代码客户端与服务器公用,这部分代码服务器用来实现实时战斗和战斗校验 大部分的逻辑在服务器,所以需要服务器开发人员将服务器战斗逻辑写成能够在客户端运行的模块,客户端人员不需要特别要求就可以实现
PVP、PVE在线战斗 可实现 可实现
节省流量 流量小,例如王者荣耀,30分钟8M 流量大,例如全名超神,30分钟20M
战斗回放 记录文件较小 通过记录所有的状态同步数据实现,记录数据量较大
离线战斗防作弊 可以用记录下来的输入,在服务器将战斗逻辑跑一遍,可以准确验证战斗结果 只能通过协议加密、内存混淆或者大量的数据验证来实现,没办法彻底解决
网络延迟大的表现 网络环境差的时候,整个战斗会停止,网络恢复之后逻辑会加速执行以赶上进度 会频繁出现玩家瞬移、回位、莫名掉血
实现难度 客户端按照单机战斗的方式实现,保证显示层和逻辑层分离,保证逻辑层不要用到浮点数(不同平台有效位数不同,可用定点数解决),不要用到不确定顺序的逻辑结构,例如Unity中的physics navmesh都不可以在战斗中使用,因为他们都是用了浮点计算。 需要服务器和客户端开发人员对于实现有较深的经验,达成共识,调优过程比较困难,客户端还需要做差值处理等。

实现过程:

以服务器以固定帧数想客户端发送数据的形式,例如:

  • 客户端假如有操作输入,直接发送操作cmd给服务器,服务器在下发数据给当前PVP所有玩家时,携带操作数据内容,这样即可实现操作同步;
  • 服务器收集每个客户端发送过来的指令集,然后再下一帧的时候将指令集广播给所有客户端;
  • 帧数为20:即服务器每秒向客户端发送20次数据;
  • 客户端的工作则是通过解析协议数据,然后对表现进行调整即可。

优化建议:

  • 预表现:
    假如要针对网络差进行体验的优化,建议构思一下预表现 ,其实没那么复杂,就是参考之前的帧数据,推测下一帧的结果,然后预先执行,假如与真实数据有误差,再进行校正即可。

  • 定点数:
    由于不同操作系统的浮点数精度有差别,特别是Android与iOS两个系统之间,假如在帧同步中不对浮点数进行处理,跨平台肯定会出现精度不同而带来的不同步的问题,比较常见的解决方案就是使用定点数(也就是分数)来替代浮点数,当然也会带来相应的效率下降。

你可能感兴趣的:(Unity3D游戏开发,Unity学习笔记)