You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中保存VR头显头部位置数据时时间戳更新异常问题排查

问题:VR头显位置数据时间戳阶梯式重复异常

我用以下代码保存VR头显的头部位置数据,帧索引和头部位置记录正常,但时间戳更新异常——同一个时间戳重复约2分10秒,之后切换新时间戳再重复该时长,呈现“阶梯”模式。请问成因是什么?

[System.Serializable]
private struct MotionFrame
{
    public int frameIndex;
    public float timeStamp;
    public Vector3 position;
    public Quaternion orientation;
}

public GameObject vrcam;
private StreamWriter writer;
private bool firstFrameWritten;

void Start()
{
    string path = "<my path>";
    writer = new StreamWriter(path, false);
    writer.AutoFlush = false;
    writer.WriteLine("{");
    writer.WriteLine("\"frames\":[");
    InvokeRepeating("SaveHeadData", 0f, 0.1f);
}
void SaveHeadData()
{
    MotionFrame frame;
    frame.frameIndex = Time.frameCount;
    frame.timeStamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();
    frame.position = vrcam.transform.position;
    frame.orientation = vrcam.transform.rotation;

    string jsonFrame = JsonUtility.ToJson(frame, true);
    if (firstFrameWritten)
    {
        writer.WriteLine(",");
    }
    writer.Write(jsonFrame);
    writer.FlushAsync();
    firstFrameWritten = true;
}
void OnApplicationQuit()
{
    writer.WriteLine("]");
    writer.WriteLine("}");
    writer.Close();
}

时间戳异常图表:
时间戳阶梯式重复异常

问题成因分析

核心问题是时间戳的类型精度不足:

  • ToUnixTimeMilliseconds()返回的是long类型的毫秒级时间戳(当前值约13位十进制数),但你用float类型存储它。
  • float的有效精度只有6-7位十进制数字,当存储超过这个位数的数值时,低位的精细变化会被舍入丢失。
  • 也就是说,相邻的毫秒级时间戳转成float后会变成同一个值,直到时间戳的高位变化足够大,才会让float的表示产生跳变,这就导致了你看到的“同一个时间戳重复很久,然后突然跳变”的阶梯模式。

修复建议

  • 把MotionFrame里的timeStamp类型从float改成long,直接完整存储毫秒级时间戳,不会损失精度。
  • 如果必须用浮点类型,改用double,它的有效精度足够覆盖当前毫秒级时间戳的所有位数。

内容的提问来源于stack exchange,提问作者Jarshah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:57:10