C# 在Unity3d中跟随播放器时出现相机抖动问题

C# 在Unity3d中跟随播放器时出现相机抖动问题,c#,unity3d,camera,lerp,C#,Unity3d,Camera,Lerp,我正在做一个多人游戏的原型。客户端有一个循环,每20ms运行一次计时器,每一步用输入数据预测当前玩家的位置(也发送给服务器),并使用最后一个快照(来自服务器)预测其他玩家的位置,并将结果放入ObjectController类,然后在更新方法中,以一定速度将对象移动到目标位置(在循环中计算) 问题是对象在移动时会抖动 在测试了所有的unity对象移动方法后,我发现问题可能在于摄影机跟随脚本。因此,我在另一个Unity move示例(此repo:)上测试了我的相机跟随脚本,这里也存在问题 没有明确的

我正在做一个多人游戏的原型。客户端有一个循环,每20ms运行一次计时器,每一步用输入数据预测当前玩家的位置(也发送给服务器),并使用最后一个快照(来自服务器)预测其他玩家的位置,并将结果放入ObjectController类,然后在更新方法中,以一定速度将对象移动到目标位置(在循环中计算)

问题是对象在移动时会抖动

在测试了所有的unity对象移动方法后,我发现问题可能在于摄影机跟随脚本。因此,我在另一个Unity move示例(此repo:)上测试了我的相机跟随脚本,这里也存在问题

没有明确的漏洞来源

移动脚本(从此处开始:):

使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类控制器:单行为
{
[标题(“全局”)]
公共浮点MaxMovementPerUpdate=5;
公共浮动MinMovementPerUpdate=1;
公共布尔模拟工作时间=假;
公共网络延迟=0.05f;
公共浮点MaxNetworkDelay=0.6f;
私有向量3 startPos=Vector3.0;
私有向量3 endPos;
公共浮点数SendsPerSecond=10f;
公共bool CalculateBasedOnSendRate=true;
[工具提示(“如果CalculateBasedOnSendRate为true则无效”)]
公共浮球框架=0.5f;
[范围(0.01华氏度,60华氏度)]
公共浮动帧秒=10f;
公共插值类型current插值类型;
公共浮动t=0;
公共游戏机;
公共游戏对象LastPos;
//Time.deltaTime但它使用deltaTime作为我们伪造的帧速率。
私人浮动三角洲
{
得到
{
return Time.Time-lastFrame;
}
}
无效开始()
{
endPos=new Vector3(Random.Range(MinMovementPerUpdate,MaxMovementPerUpdate),0,Random.Range(MinMovementPerUpdate,MaxMovementPerUpdate));
CurrentPos.transform.position=endPos;
LastPos.transform.position=startPos;
start例程(SendPosition());
}
私有void OnValidate()
{
如果(!CalculateBasedOnSendRate&&CurrentInterpolationType==InterpolationType.StartTargetUsinglerp)
{
Debug.LogWarning(“在使用StartTarget.CalculateBasedOnSendRate时无法对lerp使用fixed movestep。”);
CalculateBasedOnSendRate=真;
}
}
私有浮动框架;
无效更新()
{
如果(Time.Time-lastFrame>(1f/FramesPerSecond))
{
if(CurrentInterpolationType==InterpolationType.CurrentToTargetSinglerP)
{
如果(计算出的固定汇率)
{
t+=延迟时间/(1f/发送秒);
transform.position=Vector3.Lerp(transform.position,endPos,t);
}
其他的
{
transform.position=Vector3.Lerp(transform.position,endPos,LerpPerFrame*DeltaTime);
}
}
else if(CurrentInterpolationType==InterpolationType.StartToTargetUsingLerp)
{
如果(计算出的固定汇率)
{
t+=延迟时间/(1f/发送秒);
transform.position=Vector3.Lerp(startPos,endPos,t);
}
}
else if(CurrentInterpolationType==InterpolationType.CurrentToTargetSingMoveToward)
{
如果(计算出的固定汇率)
{
transform.position=Vector3.movetoward(transform.position,endPos,Vector3.Distance(startPos,endPos)/(1f/SendsPerSecond)*DeltaTime);
}
其他的
{
transform.position=Vector3.moveToward(transform.position,endPos,LerpPerFrame*DeltaTime);
}
}
lastFrame=Time.Time;
}
}
IEnumerator SendPosition()
{
while(true)
{
//->(1/SendsPerSecond)=发送之间的时间
如果(工作时间)
返回新的WaitForSeconds((1f/SendsPerSecond)+Random.Range(MinNetworkDelay,MaxNetworkDelay));
其他的
产生返回新WaitForSeconds(1f/SendsPerSecond);
//这也可以设置为endPos。但如果它提前到达,则可能首选此currentPos。
startPos=transform.position;
endPos=GetTargetPosition();
t=0;
LastPos.transform.position=startPos;
CurrentPos.transform.position=endPos;
}
}
私有向量3 GetTargetPosition()
{
返回transform.position+new Vector3(Random.Range(MinMovementPerUpdate,MaxMovementPerUpdate),0,Random.Range(MinMovementPerUpdate,MaxMovementPerUpdate));
}
公共枚举插值类型
{
CurrentToTargetSinglerp,
StartTargetUsinglerp,
当前目标正在向上移动
}
}
以下脚本:

使用System.Collections.Generic;
使用UnityEngine;
公共阶层追随者:单一行为
{
公共游戏对象目标;
私人浮动平滑速度=0.125f;
公共矢量3偏移量;
私有更新()
{
如果(目标)
{
Vector3 dPos=Target.transform.position+偏移量;
Vector3 sPos=Vector3.Lerp(变换位置、DPO、平滑速度);
transform.position=sPos;
}
}
}
我测试了LateUpdate和FixeUpdate方法

视频: