我正在开发用于Android的增强现实应用程序,但没有跟踪图像/对象。用户站在预定义的位置,并将虚拟对象放置到现实世界中。当用户转身或移动电话时,对象固定在各自的位置。我通过将陀螺仪数据应用于相机来实现此目的。
我的问题:我希望对象的位置始终固定在相同的位置,而不考虑用户启动应用程序时的观看方向。现在,在启动应用程序时,对象的位置取决于相机。之后,当用户更改其观看方向时,将它们固定在其位置。
我想知道哪些传感器与解决此问题有关。由于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());
}
}
答案 0 :(得分:0)
据我了解,Gyroskope
返回自启动以来的旋转差。
这就是为什么对象在启动过程中会以您面对的方向出现。
我想您至少想要Compass.magneticHeading是为了在游戏开始时设置一次正确的旋转次数
// Orient an object to point to magnetic north.
transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
您可以在开始时对要显示的所有对象的父对象执行一次此操作,以便将其正确定位在GPS北上。