关于解决延迟这类问题,最简单粗暴的方法就是提高网络的质量,但是身为程序猿我们也应该做些力所能及的事情,关于网络的延迟导致的画面不流畅,可以采用以下介绍的方法:
首先,当Player1的位置发生变化时,会发送一个变化的位置给服务器,服务器将这个位置的点发送给其他客户端,此时,我们需要一个list去保存这些点;
下一步,计算客户端中Player1的位置和list中的第一个位置,如果两个位置相距的距离足够近的话,删除掉第一个点的位置;
通过这样的方法,可以使Player的位置移动更加的平滑,附上代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine.UI;
[NetworkSettings(channel=0,sendInterval=0.1f)]
public class Player_SyncPosition : NetworkBehaviour {
[SyncVar(hook="SyncPositionValues")]private Vector3 syncPos;
[SerializeField]Transform myTransform;
private float lerpRate;
private float normalLerpRate = 16;
private float fasterLerpRate = 27;
private Vector3 lastPos;
private float threshold = 0.5f;
private NetworkClient nClient;
private int latency;
private Text latencyText;
private List<Vector3> syncPosList = new List<Vector3>();
[SerializeField]private bool useHistoricalLerping=false;
private float closeEnough = 0.11f;
void Start()
{
nClient = GameObject.Find("NetworkManager").GetComponent<NetworkManager>().client;
latencyText = GameObject.Find("Latency Text").GetComponent<Text>();
lerpRate = normalLerpRate;
}
void Update()
{
LerpPosition();
ShowLatency();
}
void FixedUpdate()
{
TransformPosition();
}
void LerpPosition()
{
if (!isLocalPlayer)
{
if (useHistoricalLerping)
{
HistoricalLerping();
}
else
{
OrdinaryLerping();
}
}
}
[Command]
void CmdProvidePositionToServer(Vector3 pos)
{
syncPos = pos;
}
[ClientCallback]
void TransformPosition()
{
if (isLocalPlayer&&Vector3.Distance(myTransform.position,lastPos)>threshold)
{
CmdProvidePositionToServer(myTransform.position);
lastPos = myTransform.position;
}
}
[Client]
void SyncPositionValues(Vector3 latestPos)
{
syncPos = latestPos;
syncPosList.Add(syncPos);
}
void ShowLatency()
{
if (isLocalPlayer)
{
latency = nClient.GetRTT();
latencyText.text = latency.ToString();
}
}
void OrdinaryLerping()
{
myTransform.position = Vector3.Lerp(myTransform.position, syncPos, Time.deltaTime * lerpRate);
}
void HistoricalLerping()
{
if (syncPosList.Count > 0)
{
myTransform.position = Vector3.Lerp(myTransform.position, syncPosList[0], Time.deltaTime * lerpRate);
if (Vector3.Distance(myTransform.position, syncPosList[0]) < closeEnough)
{
syncPosList.RemoveAt(0);
}
if (syncPosList.Count > 10)
{
lerpRate = fasterLerpRate;
}
else
{
lerpRate = normalLerpRate;
}
}
}
}
上段代码中提供两种不同的同步运动的方式(OrdinaryLerping和HistoricalLerping),以供对比。
SyncVar(hook="SyncPositionValues")指的是当这个值发生变化的时候就调用SyncPositionValues函数。
至于normalLerpRate和fasterLerpRate的值各位读者可以自己衡量一个更为恰当的值。
另外附上一篇相关文章的链接http://www.gabrielgambetta.com/fpm1.html
上面所介绍的内容还是相当给力的~