启动应用程序时如何确定Android手机的观看方向

时间:2019-03-27 17:29:54

标签: c# android unity3d

我正在开发用于Android的增强现实应用程序,但没有跟踪图像/对象。用户站在预定义的位置,并将虚拟对象放置到现实世界中。当用户转身或移动电话时,对象固定在各自的位置。我通过将陀螺仪数据应用于相机来实现此目的。

我的问题:我希望对象的位置始终固定在相同的位置,而不考虑用户启动应用程序时的观看方向。现在,在启动应用程序时,对象的位置取决于相机。之后,当用户更改其观看方向时,将它们固定在其位置。

我画了一个确切的问题图像,以便更好地阐述: user viewing direction image

我想知道哪些传感器与解决此问题有关。由于Google Maps可以准确确定用户的观看方向,因此我假设内置传感器可以找出用户的观看方向,以便在一开始就将这些信息应用于相机的旋转。

这是我用于将手机旋转应用于相机的代码(我正在使用Unity和C#):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gyrotransform : MonoBehaviour
{
    // STATE
    private float _initialYAngle = 0f;
    private float _appliedGyroYAngle = 0f;
    private float _calibrationYAngle = 0f;
    private Transform _rawGyroRotation;
    private float _tempSmoothing;

    // SETTINGS
    [SerializeField] private float _smoothing = 0.1f;

    private IEnumerator Start()
    {
        Input.gyro.enabled = true;
        Application.targetFrameRate = 60;
        _initialYAngle = transform.eulerAngles.y;

        _rawGyroRotation = new GameObject("GyroRaw").transform;
       // _rawGyroRotation.parent = Core.Instance.transform;
        _rawGyroRotation.position = transform.position;
        _rawGyroRotation.rotation = transform.rotation;

        // Wait until gyro is active, then calibrate to reset starting rotation.
        yield return new WaitForSeconds(1);

        StartCoroutine(CalibrateYAngle());
    }

    private void Update()
    {
        ApplyGyroRotation();
        ApplyCalibration();

        transform.rotation = Quaternion.Slerp(transform.rotation, _rawGyroRotation.rotation, _smoothing);
    }

    private IEnumerator CalibrateYAngle()
    {
        _tempSmoothing = _smoothing;
        _smoothing = 1;
        _calibrationYAngle = _appliedGyroYAngle - _initialYAngle; // Offsets the y angle in case it wasn't 0 at edit time.
        yield return null;
        _smoothing = _tempSmoothing;
    }

    private void ApplyGyroRotation()
    {
        _rawGyroRotation.rotation = Input.gyro.attitude;
        _rawGyroRotation.Rotate(0f, 0f, 180f, Space.Self); // Swap "handedness" of quaternion from gyro.
        _rawGyroRotation.Rotate(90f, 180f, 0f, Space.World); // Rotate to make sense as a camera pointing out the back of your device.
        _appliedGyroYAngle = _rawGyroRotation.eulerAngles.y; // Save the angle around y axis for use in calibration.
    }

    private void ApplyCalibration()
    {
        _rawGyroRotation.Rotate(0f, -_calibrationYAngle, 0f, Space.World); // Rotates y angle back however much it deviated when calibrationYAngle was saved.
    }

    public void SetEnabled(bool value)
    {
        enabled = true;
        StartCoroutine(CalibrateYAngle());
    }
}

1 个答案:

答案 0 :(得分:0)

据我了解,Gyroskope返回自启动以来的旋转差。

这就是为什么对象在启动过程中会以您面对的方向出现。


我想您至少想要Compass.magneticHeading是为了在游戏开始时设置一次正确的旋转次数

 // Orient an object to point to magnetic north.
transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);

您可以在开始时对要显示的所有对象的父对象执行一次此操作,以便将其正确定位在GPS北上。