使用Unity3D API理解陀螺仪读数

3

我正在开发一款游戏,其中某个部分需要使用陀螺仪的原始读数。我使用以下代码获取读数(我使用C#):

void Start () {
    Input.gyrometer.enabled = true;
}

void Update() {
    _guiText = Input.gyrometer.attitude.eulerAngles.ToString();
}

我在OnGUI()方法中将数值显示在屏幕上。由于我使用的是Unity,因此我使用了右手坐标系,并且我注意到陀螺仪的Y值对应于Unity中的X旋转。

问题在于这些值会大幅度跳动。例如,我可以将设备保持在X:90°并沿Y轴缓慢旋转;在某个点(大约在270°处),X将突然翻转180°。这意味着,如果我在设备的Y处于270°时启动应用程序,则X读数将完全无法使用。Z轴也会出现同样的效果。

我已经成功地通过以下代码片段在iOS设备上重置陀螺仪读数来解决这个问题:Input.gyro.enabled = false;接着是Input.gyro.enabled = true;我使用这个方法来获取设备的绝对旋转准确读数,然后使用旋转变化来获取任何其他设备移动。但是在Android上这种方法不起作用。

有人遇到过这种情况吗?如果有,请问你是如何解决的,还是这是一个无法解决的错误?


欧拉角始终不可靠(正如@fafase在他的答案中所述)。 直接使用四元数。我甚至会避免使用Quaternion.Angle。为了了解欧拉角有多危险,请查看维基百科关于Gimbal Lock的文章。 - Kay
嗨@Kay。我知道万向锁问题。我将四元数转换为欧拉角,编辑欧拉角,然后再转换回四元数。这样做会导致问题吗? - Rob Sanders
1个回答

1
这是因为您正在阅读四元数的转换。在Unity中,欧拉角只是一种友好的方式来获取难以理解的V3表示。建议不要直接影响eulerAngles,也不要将它们用作参考。相反,将平板设备视为一个旋转,然后开始获取默认旋转和当前旋转之间的角度,并使用该值来定义您的操作。
您可以使用Quaternion.Angle来实现这个目的。

谢谢。我正在清除代码中任何对欧拉的引用,并查看是否解决了问题。 - Rob Sanders
这将使调试和理解变得更加困难,因为你不再是在3D中工作,而是在4D中。直到你意识到你不需要完全理解发生了什么,只需要理解如何使用它以及期望什么。这并不意味着你不应该阅读四元数并学习,但这个主题相当深奥和高级。 - Everts
我已经能够使用四元数,只是因为欧拉角更简单,所以曾经卡在万向锁问题上了。只是想澄清一下,如果我想将陀螺仪沿X轴旋转-90度,那么代码应该是:Quaternion rotation = Input.gyro.attitude * new Quaternion(1, 0, 0, -(Mathf.PI / 2.0f)); - Rob Sanders
好的,这里可能会让你讨厌我,要通过欧拉值旋转四元数,你需要使用...Quaternion.Euler。原因是在四元数系统中,90度并没有任何意义,它完全取决于三角函数和其除法。你的旋转可以写成currentRotation *= Quaternion.Euler(-90f,0f,0f); - Everts
1
@RASS,你能否发布一个更完整的“答案”来回答这个问题?我感觉有很多讨论和一些自然语言表达数学的方式,但没有提供硬性的数学解决方案。 - toblerpwn
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接