在我的场景中,我有一个桌子(平面),球会在不经过物理处理的情况下绕着球滚动,这给人一种错觉,即使用Input.gyro.attitude,移动设备就是桌子。更进一步,我希望相对于调用Start()时的设备原点,如果不是将其放在桌子前面或桌子上,而是相对于它的开始位置,甚至可以在重设球时重设。所以问题是,如何获得当前姿态和原点姿态之间的差异,然后将X和Z(?)差异转换为Vector3到AddForce()到我的球对象,同时将最大旋转上限设置为30度?我研究了很多基于陀螺仪的输入管理器脚本,没有什么能真正帮助我理解四元数的奥秘。
我可以使用相对旋转来旋转桌子本身,但是接下来我要解决的问题是使相机沿相同的旋转方向旋转,但是还要以相对的高度跟随球,但是现在有一个倾斜的偏移量。
AddForce()可以与我在编辑器中的Input.GetAxis很好地配合使用,只是尝试在不使用游戏杆样式的UI控制器的情况下将其转换到设备上。
编辑:以下代码有效,但我没有正确的角度/欧拉角给出正确的方向。游戏仅在“横向/左右”模式下播放,因此我只需要一个俯仰和偏航轴(将手机平放在桌子上想象),而无需滚动(围绕相机/屏幕旋转)。我最终可能会通过反复试验来回答自己的问题,我敢肯定,这是大多数程序员的工作。...XD
从正确的答案开始: Answer 434096
private Gyroscope m_Gyro;
private speedForce = 3.0f;
private Rigidbody rb;
private void Start() {
m_Gyro = Input.gyro;
m_Gyro.enabled = true;
rb = GetComponent<Rigidbody>();
}
private Vector3 GetGyroForces() {
Vector3 resultantForce = Vector3.zero;
//Quaternion deviceRotation = new Quaternion(0.5f, 0.5f, -0.5f, -0.5f) * m_Gyro.attitude * new Quaternion(0,1,0,0);
float xForce = GetAngleByDeviceAxis(Vector3.up);
float zForce = GetAngleByDeviceAxis(Vector3.right);
//float zForce = diffRot.z;
resultantForce = new Vector3(xForce, 0, zForce);
return resultantForce;
}
private float GetAngleByDeviceAxis(Vector3 axis) {
Quaternion currentRotation = m_Gyro.attitude;
Quaternion eliminationOfOthers = Quaternion.Inverse(Quaternion.FromToRotation(axis, currentRotation * axis));
Vector3 filteredEuler = (eliminationOfOthers * currentRotation).eulerAngles;
float result = filteredEuler.z;
if (axis == Vector3.up) {
result = filteredEuler.y;
}
if (axis == Vector3.right) {
result = (filteredEuler.y > 90 && filteredEuler.y < 270) ? 180 - filteredEuler.x : filteredEuler.x;
}
return result;
}
void FixedUpdate() {
#if UNITY_EDITOR
rb.AddForce(new Vector3(Input.GetHorizontal * speedForce, 0, Input.GetVertical * speedForce));
#endif
#if UNITY_ANDROID
rb.AddForce(GetGyroForces);
#endif
}