Использование 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
}

0 ответов

Другие вопросы по тегам