【Unity】⽹络同步⽅案帧同步与状态同步
前⾔
本⽂会详细说明说明帧同步与状态同步、细说实现原理、分析他们的优缺点。提及注意点、保证同步的⽅法、验证同步、防作弊防攻击等。
帧同步
简单来说,就是相同的状态+相同的指令+ 按帧顺序执⾏=相同的结果。
状态:所有客户端确保逻辑⼀致,接收⼀样的随机种⼦(randomseed),⼀样的房间信息;
指令:服务器只负责收集接收每个客户端操作指令(cmd),转发指令,服务器以恒定帧率(30帧1秒)派发指令,没有指令或指令没有变化也需要派发;
执⾏:真正游戏逻辑由各个客户端单独计算 ,客户端需要收到服务器派发的指令才能推进逻辑,没有收到指令时不能推进逻辑(LockStep)
顺序执⾏
帧同步会必定按到从第⼀帧开始⼀帧⼀帧的执⾏,才能保证运⾏结果⼀样,跳帧会导致逻辑不⼀样,如果玩家⽹络不好,则会在当前帧等待⾄下⼀帧的接受,如果丢包超时,则会再次发出需要帧的请求。
追帧
什么是追帧:当前玩家播放到帧⽐服务器的帧落后时,服务器下发多个帧,玩家便要开始快进到服务器当前帧
为什么要追帧:如果⽹络波动,服务器会有最晚的接受帧时间,
做法:超过则下次发送多个帧,然后快进播放(多次DoAction),快进期间,不播放特效⾳效等不影响运⾏结果的逻辑
重连
做法:接受从0开始所有帧重新快速播放到当前帧,如果帧列表count⼤于规定速度则按照最⼤速度播放,否则按照剩余的count播放相应次数的帧。
优点
第⼀,它的开发效率⽐较⾼。如果你开发思路的整体框架是验证可⾏的,如果你把它的缺点解决了,那么你的开发思路完全就跟写单机⼀样,你只需要遵从这样的思路,尽量保证性能,程序该怎么写就怎么写,服务端逻辑简单,只需要负责转发指令,压⼒也⼩。
⽐如我们以前要在状态同步下⾯做⼀个复杂的技能,有很多段位的技能,可能要开发好⼏天,才能有⼀个稍微过得去的结果,⽽在帧同步下⾯,英雄做多段位技能很可能半天就搞定了。
第⼆,它能实现更强的打击感,打击感强除了我们说的各种反馈、特效、⾳效外,还有它的准确性。利⽤帧同步,游戏⾥⾯看到这些挥舞的动作,就能做到在⽐较准确的时刻产⽣反馈,以及动作本⾝的密度也可以做到很⾼的频率,这在状态同步下是⽐较难做的。
第三,它的流量消耗是稳定的。⼤家应该看过《星级争霸》的录像,它只有⼏百K的⼤⼩,这⾥⾯只有驱动游戏的输⼊序列。帧同步只会随着玩家数量的增多,流量才会增长,如果玩家数量固定的话,不管你的游戏有多复杂,你的⾓⾊有多少,流量消耗基本上都是稳定的。
四,这点延伸开来还有⼀个好处,就是可以更⽅便地实现观战,录像的存储、回放,以及基于录像⽂件的后续处理。
缺点
第⼀,最致命的缺点是⽹络要求⽐较⾼,帧同步是锁帧的,如果有⽹络的抖动,⼀段时间调⽤次数不稳定,⽹络命令的延迟就会挤压,引起卡顿。
电源已接通未充电第⼆,它的反外挂能⼒很弱,帧同步的逻辑都在客户端⾥⾯,你可以⽐较容易的修改它。但为什么《王者荣耀》敢⽤帧同步,⼀⽅⾯是因为当时⽴项的时候开发周期很短,半年时间要做上线,要有⼏⼗个英雄,存在时间的压⼒,另⼀⽅⾯,MOBA类游戏不像数值成长类的游戏,它的玩法是基于单局的,单局的作弊修改,顶多影响这⼀局的胜负,不会存档,不会出现刷多少钱刷多少好的装备的问题,⽽且作弊之后我们也很容易监测到,并给予应有的惩罚,所以我们认为这不是致命的缺点。
第三,它的断线重回时间很长,相信台下也有很多王者玩家,也曾碰到过闪退以后重回加载⾮常长的情况,甚⾄加载完以后游戏也快结束了,这是帧同步⽐较致命的问题。
第四,它的逻辑性能优化有很⼤的压⼒。⼤家应该没有见到哪⼀款⼤型游戏是⽤帧同步来做的,因为这些游戏的每⼀个逻辑对象都是需要在客户端进⾏运算的。如果你做⼀个主城,主城⾥⾯有上千⼈,上千⼈虽然玩家看不到它,但游戏仍然需要对他们进⾏有效的逻辑运算,所以帧同步⽆法做⾮常多的对象都需要更新的游戏场景。
五,debug困难,出现不同的情况,难以查问题所在,⼀般通过debug输出关键改变信息来定位问题,但问题可能在1-20个函数之内,但只在第20个函数打了debug信息,然后需要⼀层层去查出现
问题的所在,考虑把出问题的局录下来,然后不断重播和调试,⽅便到问题
协议:
结构
2.event ①int frame ②event type ③byte[] param
event⽰例
1.房间信息(⾓⾊数量和⾓⾊信息)
2.⾓⾊死亡/重⽣
3.⽣成怪物/Boss
4.玩家信息改变(换装,位移)
5.游戏时间结束
保证同步
同样的逻辑帧数(10-30),渲染帧可以更⾼(30以上)
随机数、Time的接管
接管物理的update,Physics.SyncTransforms Physic.Simulate(time)
顺序⼀致 ⾓⾊的创建顺序、各种玩法的创建顺序、OnTriggerXX的顺序
帧同步驱动各系统update代码,不使⽤Mono的update和Invoke等、
写功能要注意 功能逻辑符合多⼈玩法,区分⾳效特效震动的播放,对是否⾃⼰的判断
帧同步会动画突然变化 不过帧同步的都⽆法避免吧 做⼀些过度和假动画⽆逻辑(例如转⾝和⾛)前端照常播放动画 不会但不会⾃⼰切换动画处于⼀个循环,只有接收到服务器的cmd进⾏下⼀个操作⽽转变动画才会跳到下⼀个动画
浮点数处理 ⽅案⼀、定点数 ⽅案⼆、公式尽量简化(随机float 转int),并且截取⼀定的精度范围(
⽬前是⼩数点后3位)不使⽤不确定性的插件、例如有时间的、随机数的
如何验证同步
1.把⼀些关键的运⾏(例如cmd,位置,动画,攻击,发射⼦弹等)在⼀帧的最后,整理为⼀个string然后转hashcode,上传
(①int 帧 ②int hashcode)⾄服务器,服务器对⽐hashcode,如果hashcode不⼀样,则发⽣了不⼀样的逻辑,然后服务器去请求这⼀帧的详细⽇志(string DebugDetail),获取回来有何不⼀样。
2.做验证服校验哪⾥不⼀样,既是把让服务器把cmd、相关玩家数据和随机种⼦存下来,然后再播放⼀次本局然后⼀次性上传⽇志,⽐较差异。
不同步debug记录
强行删除软件1. 物理结果
问题:当刚体同时进⼊到了2个碰撞体,有可能会在不同客户端计算出不同的结果,⽆法控制。
解决:不使⽤物理⼒kinimatic
2. 浮点数不⼀样
裁剪⼩数点,尽量⽤整数计算,这个不好,⽤定点数好
3. 不能使⽤unity的mono、time、 random、 Invoke,因为时机和结果每个客户端不确定。
4. 据说rootmotion也会可能不⼀样?
5. 据说导航结果也会不⼀样,因为多个⾓⾊运动互相挤兑会导致不⼀样的结果?还是导航结果会不⼀样?
状态同步
将其他玩家的状态⾏为同步的⽅式,⼀般情况下AI逻辑,技能逻辑,战⽃计算都由服务器运算,将运算的结果同步给客户端,客户端只需要接受服务器传过来的状态变化,然后更新⾃⼰本地的动作状态、Buff状态,位置等就可以了,但是为了给玩家好的体验,减少同步的数据量,客户端也会做很多的本地运算,减少服务器同步的频率以及数据量。
二手房税费优点
第⼀,它的安全性⾮常⾼,外挂基本上没有什么能⼒从中收益。未来最有前途的专业
第⼆,状态同步对于⽹络的带宽和抖动包有更强的适应能⼒,即便出现了200、300的输⼊延迟再恢复正常,玩家其实也感受不到不太舒服的地⽅。
第三,在开发游戏过程中,它的断线重连⽐较快,如果我的游戏崩溃了,客户端重启之后只需要服务器把所有重要对象的状态再同步⼀次过来,重新再创建出来就可以了。
第四,逻辑性能优化有优势,它的客户端性能优化优势也⽐较明显,⽐如优化时可以做裁剪,玩家看不到的⾓⾊可以不⽤创建,不⽤对它进⾏运算,节省消耗。
缺点
第⼀,它的开发效率低,相对帧同步⽽⾔要差⼀些,很多时候你需要保证服务器与客户端的每⼀个⾓⾊对象的状态之间保持⼀致,但事实上你很难做到⼀致。
⽐如客户端和服务器端更新的频率,对优化的⼀些裁剪,⽹络的抖动等等,你要让每⼀个状态在客户端同步是⽐较难的,⽽你要想调试这些东西,来优化它带来的漏洞、不⼀致的现象,花费的周期也会⽐较长,想要达到优化好的⽔平也⽐较难。
第⼆,打击感差,它⽐较难做出动作类游戏打击感和精确性。⽐如说你要做⼀个射击类⾓⾊,他的⼦弹每秒钟要产⽣⼏⼗颗,基于状态同步来做是⽐较难的,因为系统在很短时间内,会产⽣很多数据,
要通过创建、销毁、位置运算来同步。
第三,它的流量会随着游戏的复杂度,⽽逐渐增长,⽐如⾓⾊的多少。希望在3G、4G的⽹络条件下也能够玩PvP,所以我们希望它对付费流量的消耗能控制在⽐较合理的⽔平,不希望打⼀局游戏就消耗⼏⼗兆的数据流量。
防攻击
来⾃熊猫:
1.特别是搞的项⽬,还有⼩公司没法通过法律⼿段来防⽌别⼈攻击。特别有⽤处。因为⾼防实在太贵,⽤不起。
2. 需要有很多ip,客户端能够随时切换连接,这样别⼈攻击⼀个可以切换其他的进程去连接。
3. 需要保证状态不丢失,消息不丢失不重发,显然tcp做不到。
4. 使⽤udp。因为udp是⽆连接的
5. 需要保证消息可靠,所以kcp是⾮常合理的选择
甘南旅游景点大全
取保候审的条件6. 可以设计⼀个路由进程来转发,udp消息通过路由再转发给realm gate等等
7. 路由进程可以起⾮常多个,客户端在连接realm或者gate之前先请求路由进程,告诉路由进程⾃⼰需要真正连接的地址,路由进程记录下来。然后客户端⽤kcp连接,路由进程把发过来的udp消息转发给真正的地址,⽐如gate。所以服务端对外的是路由进程,gate realm变成了内⽹地址。
8. 客户端连接会每隔2秒ping⼀次,ping超过10s没有回消息则重新请求⼀个路由来连接。这样别⼈攻击⼀台路由我们就可以不停的关闭被攻击的路由进程,或者开启新的路由都可以。
9.因为udp⽆连接状态,kcp会保证不丢消息会重发,所以即使换了路由进程,仍然能够保证消息⼀致性
参考链接:
MMORPG服务器架构
tx王者
熊猫:状态同步做魔兽争霸3也是可以的,每个⼩兵不是时时刻刻都在变化移动路线,团战的时候⼤部分⼩兵都是站着不动的。移动消息量其实不⼤。移动消息改成发送移动路径,只要⼩兵移动路径不变,就不需要发送新的移动消息,状态同步完全可以做rtx。个⼈
有⼯具把unity的mesh导出成recast格式的mesh⽂件,然后⾃带的demo⽣成寻路⽂件。研究下吧,会c++就不难,⼀个星期可以搞定
观点
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论