Проблемы зажима кватерниона вращения

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

В этой 2D игре Unity, над которой я работаю, я хочу, чтобы пушки следовали за мышью и вращались вокруг оси z. Текущий код делает именно это, но я также хотел бы ограничить вращение.

Vector3 dir = Camera.main.ScreenToWorldPoint (Input.mousePosition);
    Quaternion targetRotation = Quaternion.LookRotation(transform.position - dir.normalized, Vector3.forward);
    targetRotation.x = 0;
    targetRotation.y = 0;
    transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed * 10);

Я пытался использовать ifЗаявления об ограничении вращения:

if(eulerAngle > 65 && eulerAngle < 295) //pseudo code
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed * 10)

Это работает, но блокирует ствол пушки на 65 или 295 градусов. Мне не повезло с помощью ifзаявления, чтобы "разблокировать" вращение ствола.

Я также попробовал подобное утверждение, используя Quaternions:

float amountToRotate = Quaternion.Angle (transform.rotation, targetRotation);

Думаю, из-за того, как работают кватернионы, угол увеличивается даже при удалении от цели. Похожи на числа на комплексной плоскости?

mathf.clamp Функция не принесла мне удачи.

Вероятно, есть простое решение всех этих проблем, но я просто не могу решить это.

Изменить: я бы предпочел использовать mathf.clamp так как это кажется "самым чистым" решением.

1 ответ

Решение

Кажется, проблема в вашем if логика состояния.

Давайте разбить его на несколько логических блоков:

  • Если значение больше 65 > проверить следующий блок

Если это не так, это означает, что значение меньше или равно 65 и if не побежит В следующем блоке (если значение больше 65)

  • Если значение меньше 295 > выполнить оператор if

если это не так, это означает, что значение больше или равно 295.

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

if(eulerAngle >= 65 && eulerAngle <= 295)

Это дает нам несколько проверок, чтобы меньше думать. Теперь мы знаем, что если вращение вашей пушки замерзает, то это потому, что угол меньше 65 ( < 65) или выше 295 (> 295).

Чтобы оператор if мог продолжаться, вы захотите, чтобы значение снова находилось между значениями, потому что вы также добавили проверку = к значениям. Теперь вы можете просто установить их на 65 или 295, в зависимости от того, какой из них находится вне диапазона. Образец, чтобы дать вам идею:

else if( eulerAngle < 65)
    eulerAngle = 65;
Другие вопросы по тегам