3-网络同步

状态同步

跟随算法

使得物体以一定速度运动而不是直接同步位置

预测算法

使得物体提前到达预测位置==(这就是项目中坦克看起来会回退的原因)==

步骤:

  1. 计算坦克下一个同步到达的位置forecastPos

由于匀速运动,相同间隔走的路程是一样的 从a到c只要加上2倍的距离差就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//移动同步
public void SyncPos(MsgSyncTank msg){
//预测位置
Vector3 pos = new Vector3(msg.x, msg.y, msg.z);
Vector3 rot = new Vector3(msg.ex, msg.ey, msg.ez);
forecastPos = pos + 2*(pos - lastPos);
forecastRot = rot + 2*(rot - lastRot);
//更新
lastPos = pos;
lastRot = rot;
forecastTime = Time.time;
//炮塔
Vector3 le = turret.localEulerAngles;
le.y = msg.turretY;
turret.localEulerAngles = le;
}
  1. 使得坦克提前向forecastPos移动
    • 移动方式使用线性插值匀速移动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void ForecastUpdate(){
//时间
float t = (Time.time - forecastTime)/CtrlTank.syncInterval;
t = Mathf.Clamp(t, 0f, 1f);
//位置
Vector3 pos = transform.position;
pos = Vector3.Lerp(pos, forecastPos, t);
transform.position = pos;
//旋转
Quaternion quat = transform.rotation;
Quaternion forcastQuat = Quaternion.Euler(forecastRot);
quat = Quaternion.Lerp(quat, forcastQuat, t) ;
transform.rotation = quat;
}

现象与问题

在游戏画面中可以看到,经过预测算法的,对于每秒10次的同步有明显的抖动现象。为了去除这些抖动,我们可以提高同步的频率。

1
2
3
//同步帧率  
public static float syncInterval = 0.1f;
public static float syncInterval = 0.03f;

将同步拉高到每秒30次,虽然抖动现象不明显了,可是有的客户端延迟非常严重,现在还原因不明确。

经过测试

同步次数 现象
每秒10次 可以完美支持6人联机
每秒30次 在2人时 非常流畅
每秒30次 在3人时 打包好的客户端接收syncTank的同步消息延迟非常高 ,然而unity运行的客户端接收并不卡顿,目前原因不明确。
每秒30次 3人以上客户端与3人时现象一致