Квартернионы в Единстве - PullRequest
1 голос
/ 07 мая 2019

Я программирую космический шутер 6DOF в 3D с Unity и C #.Я использую мышь и клавиатуру для движения.С помощью мыши я использую Quarterions для вращения по осям X, Y и Z.

Я попробовал следующий код:

void Update()
{
    float test = Input.GetAxis("Pitch");
    float test2 = Input.GetAxis("Yaw");

    float test3 = Input.GetAxis("Roll");

    rotX += test;
    Quaternion q1 = Quaternion.AngleAxis(rotX, Vector3.right);


    rotY += test2;
    Quaternion q2 = Quaternion.AngleAxis(rotY, Vector3.up);

    roll += test3;
    Quaternion q3 = Quaternion.AngleAxis(roll, Vector3.forward);

    transform.rotation = q1 * q2 * q3;
}

Код работает, но не для всех углов.Похоже, что каждые 90 градусов движение не является правильным (ось X и Y поворачиваются).Я ожидаю, что этот код работает для каждого угла, что не так в этом коде?

Ответы [ 2 ]

1 голос
/ 08 мая 2019

Вы используете абсолютные (мировые) векторы в качестве своей системы отсчета. замените Vector3.up на transform.up, Vector3.forward на transform.forward и Vector3.right для преобразования вправо. Таким образом, вы будете вращаться вдоль локальной оси, и блокировка карданного подвеса должна быть менее проблематичной.

Порядок операций все равно будет иметь значение, но для относительно небольшой дельты он должен работать как положено.

Я думаю, что вы правильно делаете умножение кватернионов перед назначением нового поворота, иначе каждый локальный вектор будет меняться с каждой операцией - поведение будет немного отличаться

0 голосов
/ 08 мая 2019

Как сказал @Zambari, убедитесь, что вы вращаетесь вокруг локальных осей. Но вы также, похоже, сохраняете ориентацию в углах Эйлера rotX, rotY, rotZ, а затем устанавливаете ее как абсолютное вращение. Это плохо. Вы хотите применить дельта / модификацию к сохраненному кватерниону преобразования:

void Update() {

    var yaw = Quaternion.AngleAxis(Input.GetAxis("Yaw"), transform.up);
    var pitch = Quaternion.AngleAxis(Input.GetAxis("Pitch"), transform.right);            
    var roll = Quaternion.AngleAxis(Input.GetAxis("Roll"), transform.forward);

    transform.rotation = transform.rotation * yaw * pitch * roll;
}

примечание: порядок умножения в последней строке может быть неправильным.

Сказав все это, если все, что вам нужно, это управлять своим персонажем, попробуйте (углы в градусах):

transform.Rotate(xAngle, yAngle, zAngle, Space.Self);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...