Android Unity-陀螺仪-仅绕一个轴旋转

Android Unity-陀螺仪-仅绕一个轴旋转,android,unity3d,quaternions,gyroscope,Android,Unity3d,Quaternions,Gyroscope,我用Unity制作了一个使用陀螺仪的游戏。我试图检测设备围绕穿过屏幕的轴的旋转,我假设它是Unity空间中的Z轴。我尝试使用Input.gyro.attitude.eulerAngles.z,但当围绕其他轴倾斜设备时,它不会保持不变,例如,我希望它保持不变,以便只有“z轴”决定汽车方向盘的旋转。我如何实现这一点 编辑: 我试着做些别的事。我使用了Input.gyro.rotationrate unbiased而不是Input.gyro.attitude.euleranges 代码如下:

我用Unity制作了一个使用陀螺仪的游戏。我试图检测设备围绕穿过屏幕的轴的旋转,我假设它是Unity空间中的Z轴。我尝试使用
Input.gyro.attitude.eulerAngles.z
,但当围绕其他轴倾斜设备时,它不会保持不变,例如,我希望它保持不变,以便只有“z轴”决定汽车方向盘的旋转。我如何实现这一点

编辑: 我试着做些别的事。我使用了
Input.gyro.rotationrate unbiased
而不是
Input.gyro.attitude.euleranges

代码如下:

    Vector3 gInput = Input.gyro.rotationRateUnbiased;
    gyroEuler += gInput * Time.deltaTime * Mathf.Rad2Deg;

    float rollAngle = gyroEuler.z;

    while (rollAngle < 0)
    {
        rollAngle += 360;
    }
    while (rollAngle > 360)
    {
        rollAngle -= 360;
    }
Vector3 gInput=Input.gyro.ROTATIONRATE无偏;
gyroEuler+=gInput*Time.deltaTime*Mathf.Rad2Deg;
浮动滚柱角度=回转欧拉.z;
同时(滚动角度<0)
{
滚转角+=360;
}
同时(滚动角度>360)
{
滚转角-=360;
}

但是
gyroEuler
将被设置为
(0,0,0)
,而不管游戏开始时设备的方向如何,因此设备的方向在开始时是未知的,并且
输入。gyro.rotationRateUnbiased
非常不准确。我想像很多游戏一样旋转屏幕,比如Temple Run 2,但我希望能够将屏幕旋转360度并获得旋转角度。

我刚刚尝试过,效果很好:

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

private void Update()
{
    Vector3 previousEulerAngles = transform.eulerAngles;
    Vector3 gyroInput = -Input.gyro.rotationRateUnbiased;

    Vector3 targetEulerAngles = previousEulerAngles + gyroInput * Time.deltaTime * Mathf.Rad2Deg;
    targetEulerAngles.x = 0.0f; // Only this line has been added
    targetEulerAngles.z = 0.0f;

    transform.eulerAngles = targetEulerAngles;

    //You should also be able do it in one line if you want:
    //transform.eulerAngles = new Vector3(0.0f, transform.eulerAngles.y - Input.gyro.rotationRateUnbiased.y * Time.deltaTime * Mathf.Rad2Deg, 0.0f);
}
你需要做的是创建一个中央变换(或使用你的播放器),并将你的相机作为它的子对象。然后设置相机z距离、高度和角度以调整视图。最后,将上面的脚本附加到中央变换中:旋转它将使您的相机沿着弧线移动

编辑:如果您想使用
Input.gyro.attitude
,您可以按如下操作

private Vector3 startEulerAngles;
private Vector3 startGyroAttitudeToEuler;

private void Start()
{
    Input.gyro.enabled = true;
    startEulerAngles = transform.eulerAngles;
    startGyroAttitudeToEuler = Input.gyro.attitude.eulerAngles;
}

private void Update()
{
    Vector3 deltaEulerAngles = Input.gyro.attitude.eulerAngles - startGyroAttitudeToEuler;
    deltaEulerAngles.x = 0.0f;
    deltaEulerAngles.z = 0.0f;

    transform.eulerAngles = startEulerAngles - deltaEulerAngles;
}

public void ResetGyro()
{
    startGyroAttitudeToEuler = Input.gyro.attitude.eulerAngles;
}
编辑2:

我猜你要找的是这样的:然后你可以检查
upVec.y
upVec.x
,查看你的下/上和左/右轴

首先创建一个空的游戏对象,该对象将用作包含陀螺仪旋转的虚拟对象,并在脚本的
phoneDummy
字段中进行设置

public Transform phoneDummy;

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

private void Update()
{
    Vector3 gyroEuler = Input.gyro.attitude.eulerAngles;
    phoneDummy.transform.eulerAngles = new Vector3(-1.0f * gyroEuler.x, -1.0f * gyroEuler.y, gyroEuler.z);

    Vector3 upVec = phoneDummy.transform.InverseTransformDirection(-1f * Vector3.forward);
}
upVec.y
将是你的俯仰
upVec.x
将是你的滚动轴。 (检查轴参考)

但是请记住
Input.gyro
中的值远非完美:如果您想寻找更持久的值(当然是不太精确的值),您可能需要使用
Input.compass.magneticeReading

希望这有帮助


花了我很多时间,但你只需要使用两个四元数值,一个可能重复的值对我没有多大帮助。例如,你不需要估计“euler角”,但你可以简单地估计变换轴(通过当前旋转)和地平面之间的角度。如果答案解决了你的问题,请考虑接受它作为正确的。除此之外,你还有其他问题吗?(接受一个答案有助于未来的访问者进入本页面)它工作正常,但无法准确计算角度。我想用它来测量屏幕的旋转角度,所以我想用Input.gyro.attitude,但我不知道如何使用它,我不太明白它是如何工作的。@MoazAshraf使用
Input.gyro.attitude
编辑了我的文章,但使用它会产生一些副作用(当装置围绕其垂直位置前后倾斜时,方向变化约180°)。这正是我说的我希望旋转保持恒定的意思。我的问题应该是如何消除副作用。为什么当我绕垂直轴旋转设备时,Z读数会发生变化?不确定Z读数为什么会发生变化,但是当您通过垂直方向,因为磁航向与水平保持的设备一起工作:所以当您移动“极值角度”值(设备X角度=+/-90°)时,磁航向会进行补偿。
Gyroscope jyro;
private void Start()
{
    jyro = Input.gyro;
    jyro.enabled = true;
}

void Update()
{
    if (SystemInfo.supportsGyroscope)
    {
        transform.rotation = new Quaternion(0, 0, -Input.gyro.attitude.z, Input.gyro.attitude.w);
    }
}