陀螺仪和拖动在 3d 房间中一起工作
Posted
技术标签:
【中文标题】陀螺仪和拖动在 3d 房间中一起工作【英文标题】:Gyroscope and Dragging working together in a 3d room 【发布时间】:2021-10-21 14:52:43 【问题描述】:我正在开发一个统一的应用程序,它基本上是一个 3D 房间,用户可以使用手机的陀螺仪在房间内导航。 我遇到的问题是,我还希望用户能够拖动房间,而在拖动完成后陀螺仪仍然可以工作,但是我的拖动代码效果不佳,而且它也破坏了陀螺仪导航。
我制作了一个视频来更好地解释这个问题:https://youtu.be/7liSyZAdxL4
这是我的陀螺仪代码(它附在相机上):
using UnityEngine;
public class GyroHandler : MonoBehaviour
bool m_gyroEnabled;
UnityEngine.Gyroscope m_gyro;
GameObject m_gyroParent;
Quaternion m_rotation;
float m_rotateAmount = 0;
public static GyroHandler Instance;
void Awake()
Instance = this;
void Start()
Screen.sleepTimeout = SleepTimeout.NeverSleep;
ResetGyro();
void ResetGyro()
m_gyroParent = new GameObject("Gyro Parent");
m_gyroParent.transform.position = transform.position;
transform.SetParent(m_gyroParent.transform);
m_gyroEnabled = EnableGyro();
bool EnableGyro()
if (SystemInfo.supportsGyroscope)
m_gyro = Input.gyro;
m_gyro.enabled = true;
m_gyroParent.transform.rotation = Quaternion.Euler(90f, -90f, 0f);
m_rotation = new Quaternion(0, 0, 1, 0);
return true;
else
Debug.Log("Device doesn't support gyro.");
return false;
void Update()
if (m_gyroEnabled && SystemInfo.supportsGyroscope)
transform.localRotation = m_gyro.attitude * m_rotation;
transform.Rotate(0, -m_rotateAmount, 0);
public void ToggleGyro(bool enable, float rotateAmount)
m_rotateAmount += rotateAmount;
m_gyroEnabled = enable;
这是我拖动房间的代码:
using UnityEngine;
using UnityEngine.EventSystems;
public class RoomDragHandler : MonoBehaviour, IDragHandler, IEndDragHandler
float m_rotateAmount = 0;
public void OnDrag(PointerEventData eventData)
GyroHandler.Instance.ToggleGyro(false, 0);
float speedx = eventData.delta.x * 0.05f;
m_rotateAmount += speedx;
Camera.main.transform.Rotate(0, -speedx, 0);
public void OnEndDrag(PointerEventData eventData)
GyroHandler.Instance.ToggleGyro(true, m_rotateAmount);
m_rotateAmount = 0;
我的拖拽逻辑是这样的:拖拽开始时,禁用陀螺仪,拖拽完成后,启用陀螺仪返回。当用户拖动时,将拖动量保存在变量 (m_rotateAmount) 中,当拖动完成时,将该值传递给陀螺仪处理程序,以便当陀螺仪再次接管时,它会将相机旋转到该量。如果没有这部分,一旦阻力结束,房间就会迅速恢复,所以我们需要告诉陀螺仪进行额外的旋转。这是执行此操作的代码部分:
void Update()
if (m_gyroEnabled && SystemInfo.supportsGyroscope)
transform.localRotation = m_gyro.attitude * m_rotation;
transform.Rotate(0, -m_rotateAmount, 0);
第一部分只是使用陀螺仪进行正常旋转,第二行添加了在拖动过程中保存的额外旋转。
我不确定我错过了什么,但我一直在使用这段代码,试图更好地计算数学以了解为什么阻力会破坏陀螺仪,但到目前为止还没有运气。
如果有人能告诉我我做错了什么,我将不胜感激。
非常感谢。
【问题讨论】:
【参考方案1】:默认transform.Rotate(x, y, z) 围绕对象的局部坐标系旋转,而不是世界坐标系。这意味着当您在应用陀螺仪旋转后应用拖动旋转时,y 轴不再指向正上方,并且应用的旋转不一定在预期的方向上。
解决这个问题:
transform.Rotate(0, -m_rotateAmount, 0, Space.World)
【讨论】:
以上是关于陀螺仪和拖动在 3d 房间中一起工作的主要内容,如果未能解决你的问题,请参考以下文章