【笔记】unity逻辑类各种即使方案汇总

迷雾遮罩:
1.使用war3的地图拼接
2.改变网格范围,传到shader中

寻路:
需要高精度的则不适合用Navmesh

1.https://howtorts.github.io/2014/01/04/basic-flow-fields.html
基于流场,估计类似sdf,使用Dijkstra生成路径

2.rts寻路
A Start Pathfinding Project Pro + Unity NavMesh
寻路算法+精确碰撞(以及避碰)

3.多人寻路中的交互避碰
RVO2

4.定时器,当有大量定时器时
时间轮
分级时间轮

5.mmo同步位置,预测拉扯
#客户端A在p1发起移动的包里有客户端和服务端的时差和移动方向和速度以及目标点p4, 服务端接收到包后跟距时差T1和T3估算出客户端当前位置(可能会需要校验,矫正)
再讲这个位置下发给所有客户端,其他客户端接收到数据包后再根据T4和T3的时差去预测客户端A当前位置p3,用以下公式计算速度S,插值移动到p4
S = (P4-P1)/(P4-P3)
客户端A在发起移动消息时,本地生成队列,接收到校验通过的消息时移除,校验失败则回扯到p1

#用于同步位置的协议
Msg_PlayerMove                            //客户端向服务端发送玩家移动
(a)MSG_PlayerMove_Pos           //客户端向服务端发送移动中玩家位置改变
(b)MSG_PlayerMove_Pos_Rotate, //客户端向服务端发送移动中玩家位置和朝向改变
(c)MSG_PlayerMove_StopPos,                //服务端通知客户端原地不动玩家的位置消息(移动到目标点后)
(d)MSG_PlayerMove_StopPos_Rotate,        //服务端通知客户端原地不动玩家的位置和朝向消息(移动到目标点后)

#角色移动同步,位置同步
服务端做九宫格,九宫格一个格子比手机的一半大一点
客户单移动时每移动一定间隔,发一次位置到服务端,服务端判断是否跨越了大格子,跨越了就发跨越消息包到客户端,否则不进行广播
客户端状态变化很快时,比如快死时玩家一直点地图,当2次状态变化之间小于阈值时,启用一个消息缓存队列,延迟发送有效数据(接到消息后再发下一个)

#怪物的随机移动不同步

#减少怪物攻击同步
怪物可以每进行一次攻击,客户端就发一个消息给服务器。这样做,消息还是有点多,特别是一群怪围着几个角色进行攻击时,消息广播还是有点多。
所以可以将状态的概念向上扩大,只同步怪物在攻击哪个玩家,而不同步每一次的攻击,然后由每个客户端根据怪物固定的攻击速度各自去表现。这样一个怪去攻击一个玩家,就会只有一次消息广播了。

6.技能系统设计
一个技能由n个效果组成,程序维护效果,通过编辑器看表现
解耦逻辑与显示

7.Buff机制设计
回调点机制:BuffOccur(添加),BuffOnTick(间隔触发),BuffRemoved(移除),BuffBeHurt(在受到攻击的时候触发,已确定被打中,盾类技能受到攻击)
BuffOnHit(被攻击,未确定是否会被击中,以及未确定伤害是多少,可传参isHit像isCrit),BuffBeforeKilled(杀死buff附着者前),BuffAfterKilled(杀死buff附着者后)

8.反外挂
限制客户端发送移动消息的频率
移动距离检测
消息时间检测
1天内经验和金币增加数量限制
抽查

9.万象锁根源
x,z轴绕模型坐标系旋转,y轴绕惯性坐标系旋转,所以会出现,y和z轴共旋转面的情况

10.mmorpg Animator使用(大量动作文件时)
# 使用Mecanim Control插件,使用方法类似Play CrossFade,缺点不支持BlendTree
#代码生成AnimatorController,同时类似于多个idle动画到技能的切换,可做成在状态机A(包含n个idle)到状态机B的切换
#多个idle到多个技能的切换,可做成运行时动态替换idle动画

11.帧同步平滑位移
服务端为主,缺点为启动重,停止时刹不住
影子追随算法

12.处理网络抖动
插值逼近
预备动作
引入硬直
丢包处理(UDP丢包章节介绍)
对时、对帧

13.状态同步经验
 server 对攻击目标的位置做估算的时候,可以不按上次发出包的运动方向去做位置估计,而选择用最有利于被攻击者的运动方向来做。这样,可以减少网络状况差的玩家的劣势。
 对于 PVE 的战斗,甚至可以做更多的取舍,达到游戏流畅的效果。比如一个网络状态差的玩家去打 npc,他攻击 npc 的时刻,npc 是处于攻击范围之内的。但是由于网络延迟,数据包被 server 收到的时候,npc 已经离开。这个时候 server 可以判定为miss

14.时间校准
1.客户端发给服务端 时间戳 t1
2.服务端接收到 时间戳 t2
3.服务端发给客户端 时间戳 t3
4.客户端接收到 时间戳 t4
网络来回总延时 delay = (t4 - t1) - (t3-t2) //t3-t2为服务器内部耗时
客户端与服务端时间差 delta = ( (t2-t1) + (t4-t3) - delay ) / 2
delay1 为 t1 至 t2 延时,delay2 为 t3至t4延时
t2 - t1 即 delta + delay1
t4 - t3 即 delta + delay2
delay = delay1 + delay2

15.定点数的物理模拟
有隐患:只使用unity的射线0,BoxCollider,尾数截断,按碰撞方向截断,只使用Navmesh计算出的路点(估计只能有一个客户端作为决定源)

16.帧同步针对延迟的优化
逻辑层和表现层完全分离
不使用FixedUpdate的方式降低输出延迟
使用了TCP,自己实现的可靠UDP和冗余包的非可靠UDP三种方式通信;
极致压缩优化协议包降低在MTU范围以内;逻辑帧负载均衡;分地域部署和匹配;多线程收发

17.可能引起不同步的:
不同的调用顺序,时序,浮点数计算的偏差,容器的排序不确定性,Coroutine内写逻辑带来的不确定性,
物理浮点数,随机数值带来的不确定性
逻辑到表现的通知不能用事件,因为回滚的话会漏掉事件的触发

18.帧同步同步
可靠传输的UDP,冗余信息的不可靠UDP(最好使用这个方案)
#基于可靠传输的UDP,是指在UDP上加一层封装,自己去实现丢包处理,消息序列,重传等类似TCP的消息处理方式,保证上层逻辑在处理数据包的时候,不需要考虑包的顺序,丢包等。类似的实现有Enet,KCP等。
#冗余信息的UDP,是指需要上层逻辑自己处理丢包,乱序,重传等问题,底层直接用原始的UDP,或者用类似Enet的Unsequenced模式。常见的处理方式,就是两端的消息里面,带有确认帧信息,比如客户端(C)通知服务器(S)第100帧的数据,S收到后通知C,已收到C的第100帧,如果C一直没收到S的通知(丢包,乱序等原因),就会继续发送第100帧的数据给S,直到收到S的确认信息。

19.帧同步下的动作切换,技能播放
时间轮+从动画片段抽象出的逻辑帧(可与数据核心的帧率结合,不能依赖于Animator播放的时间,或者AnimatorStateInfo的NormalizedTime)

20.帧同步逻辑层面的预测
http://dy.163.com/v2/article/detail/DN3MIAE00511L9VL.html
客户端领先服务端的帧数,网络好的领先的少,大概2帧,网络差的领先的多,大概5帧 
当前客户端(A,B)执行到100帧,服务器执行到97帧。在100帧的时候,A执行了移动,B执行了攻击,A和B都通知服务器:我已经执行到100帧,我的操作是移动(A),攻击(B)。服务器在自己的98帧或99帧收到了A,B的消息,存在对应帧的操作数据中,等服务器执行到100帧的时候(或提前),将这个数据广播给AB。
  然后A和B立刻开始执行100帧,A执行移动,预测B不执行操作。而B执行攻击,预测A执行攻击(可能A的99帧也是攻击),A和B各自预测对方的操作。
  在A和B执行完100帧后,他们会各自保存100帧的状态快照,以及100帧各自的操作(包括预测的操作),以备万一预测错误,做逻辑回滚。
  执行几帧后,A和B来到了103帧,服务器到了100帧,他开始广播数据给AB,在一定延迟后,AB收到了服务器确认的100帧的数据,这时候,AB可能已经执行到104了。A和B各自去核对服务器的数据和自己预测的数据是否相同。例如A核对后,100帧的操作,和自己预测的一样,A不做任何处理,继续往前。而B核对后,发现在100帧,B对A的预测,和服务器确认的A的操作,是不一样的(B预测的是攻击,而实际A的操作是移动),B就回滚到上一个确认一样的帧,即99帧,然后根据确认的100帧操作去执行100帧,然后快速执行101~103的帧逻辑,之后继续执行104帧,其中(101~104)还是预测的逻辑帧。
  因为客户端对当前操作的立刻执行,这个操作手感,是完全和PVE(不联网状态)是一样的,不存在任何Delay。所以,能做到绝佳的操作手感。当预测不一样的时候,做逻辑回滚,快速追回当前操作。
  这样,对于网络好的玩家,和网络不好的玩家,都不会互相影响,不会像Lockstep一样,网络好的玩家,会被网络不好的玩家Lock住。也不会被网络延迟Lock住,客户端可以一直往前预测。
  对于网络好的玩家(A),可以动态调整(根据动态的Latency),让客户端领先服务器少一些,尽量减少预测量,就会尽量减少回滚,例如网络好的,可能客户端只领先2~3帧。
  对于网络不好的玩家(B),动态调整,领先服务器多一些,根据Latency调整,例如领先5帧。
  那么,A可能预测错的情况,只有2~3帧,而网络不好的B,可能预测错误的帧有5帧。通过优化的预测技术,和消息通知的优化,可以进一步减少A和B的预测错误率。对于A而言,战斗是顺畅的,手感很好,少数情况的回滚,优化好了,并不会带来卡顿和延迟感。
  重点优化的是B,即网络不好的玩家,他的操作体验。因为客户端不等待服务器确认,就执行操作,所以B的操作手感,和A是一致的,区别只在于,B因为延迟,预测了比较多的帧,可能导致预测错,回滚会多一些。比如按照B的预测,应该在100帧击中A,但是因为预测错误A的操作,回滚重新执行后,B可能在100帧不会击中A。这对于B来说,通过插值和一些平滑方式,B的感受是不会有太大区别的,因为B看自己,操作自己都是及时反馈的,他感觉自己是平滑的。
  这种方式,保证了网络不好的B的操作手感,和A一致。回滚导致的一些轻微的抖动,都是B看A的抖动,通过优化(插值,平滑等),进一步减少这些后,B的感受是很好的。我们测试在200~300毫秒随机延迟的情况下,B的操作手感良好。
  这里,客户端提前服务器的方式,并且在延迟增大的情况下,客户端将加速

21.检测udp丢包&#

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值