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
相关产品推荐
相关产品推荐

