试图统一和C#制作精确的重播系统
大家好, 我在赛车游戏上工作,因此我决定添加一个重播系统以允许“幽灵车”,最初我是在某些事件(例如按键)中记录数据,但只记录了所有帧中的数据,所以我管理着一个流畅的重播,好的,因为文件不是很大并且可以重播,但是麻烦的是时间总是有微小的变化,最多只有0.1秒或0.2,我有一个关键帧列表,并且在每个位置我都记录了一个要显示的时间,我认为麻烦是,因为fps会发生变化,因此并非在所有运行中都显示相同的时间标记,所以并不总是呈现获胜帧的时间,因此获胜帧会在下一次更新后稍稍显示。我使用c#和unity以防万一,但是我认为它主要独立于此。非常感谢任何线索,我已经讨论这个问题已有一段时间了
答案 0 :(得分:2)
听起来您正在逐帧重播,这已经发现,您需要以与录制相同的延迟播放帧。在游戏渲染循环中,不能保证会发生这种情况。
在记录每帧的赛车状态(位置,方向等)时,还需要记录时间戳(在这种情况下,从比赛开始累积Time.deltaTime
就足够了。)
回放时,找到当前时间戳并从记录的边界帧中插值(即Lerp
)汽车的状态。
帧插值的提示:
class Snapshot {
public float Timestamp;
public Matrix4x4 Transform; // As an example. Put more data here.
}
private int PrevIndex = 0;
private List<Snapshot> Snapshots = (new List<Snapshot>()).OrderBy(m => m.Timestamp).ToList();
private float GetLerpFactor(float currentTimestamp) {
if ( PrevIndex == Snapshots.Count - 1)
return 0; // Reached end of Snapshots
while (currentTimestamp >= Snapshots[PrevIndex + 1].Timestamp)
PrevIndex++; // move 'frame' forward
var currentDelta = Mathf.Max(0f, currentTimestamp - Snapshots[PrevIndex].Timestamp);
var fullDelta = Snapshots[PrevIndex + 1].Timestamp - Snapshots[PrevIndex].Timestamp;
var lerpFactor = currentDelta / fullDelta;
return lerpFactor;
}
答案 1 :(得分:1)
除非出于某种原因,您需要与“幽灵”汽车进行交互(例如碰撞),并在足够频繁的原始时间记录最终位置/速度/方向的数据,然后将其插值到新的模拟中。除非您需要测量/显示用户对某件事的反应速度,否则我不会记录原始输入,而是记录由此产生的变化(例如变速)。
如果您真的想重播相同的输入,则必须同时运行两个单独的模拟,这样“真实”版本的物理效果和时序不会影响“虚幻”版本,很可能您必须再次插值“幻影”模拟的输出以使其与真实模拟对齐(除非您有固定的时间步长)。