Использование Input.Gyro, чтобы получить величину "наклона" от начала координат
В моем сценарии у меня есть таблица (плоскость), по которой шарик будет вращаться, используя только физику, создавая иллюзию, что мобильное устройство - это таблица, использующая Input.gyro.attitude. Сделав еще один шаг вперед, я хотел бы, чтобы это было относительно источника устройства во время вызова Start(), поэтому, если оно не удерживается перед лицом или плоскостью на столе, а только относительно того, где оно началось, и даже может быть сброшен при сбросе мяча. Таким образом, вопрос в том, как мне получить разницу между текущим отношением и исходным отношением, а затем преобразовать разницу X и Z(?) В Vector3 в AddForce() в мой шаровой объект, ограничивая максимальное вращение примерно 30 градусы? Я просмотрел множество сценариев менеджера ввода на основе гироскопа, и ничто действительно не помогает мне понять тайну кватернионов.
Я мог бы использовать относительное вращение, чтобы вращать сам стол, но тогда я имею дело с проблемой вращения камеры вдоль того же вращения, но также и следования мячу на относительной высоте, но теперь с наклонным смещением.
AddForce() хорошо работает для моих целей с Input.GetAxis в редакторе, просто пытаясь перенести его на устройство без использования контроллера интерфейса пользователя в стиле джойстика.
Изменить: следующий код работает, но у меня нет правильных углов / эйлеров, чтобы дать правильное направление. Игра ведется только в альбомной ориентации влево / вправо, поэтому мне нужно только ось тангажа и рыскания (представьте, что телефон лежит на столе), а не катиться (вращаться вокруг камеры / экрана). Я могу со временем ответить на свой вопрос методом проб и ошибок, что, я уверен, то, что делает большинство программистов.... XD
Начал на правильном пути через этот ответ: Ответ 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
}