#unity3d #rotation #quaternions
#unity3d #вращение #кватернионы
Вопрос:
Следующие две строки в Update() гарантируют, что мое преобразование всегда будет обращено в прямом направлении (this.Направьте.вперед) на заданный угол поворота (this.Вращение, плавающее значение в диапазоне от 0 до 360) вокруг этой прямой оси.
this.transform.rotation = Quaternion.AngleAxis(this.Rotation, this.Point.forward);
this.transform.rotation = Quaternion.LookRotation(this.Point.forward, this.transform.up);
Однако по каким-то причинам теперь я хочу сгладить / уменьшить вращение; поэтому вместо того, чтобы напрямую устанавливать ‘this.transform.rotation’, я добавляю свойство ‘targetRotation’ в класс и изменяю эти строки на;
targetRotation = Quaternion.AngleAxis(this.Rotation, this.Point.forward);
targetRotation = Quaternion.LookRotation(this.Point.forward, this.transform.up);
И добавьте;
this.transform.rotation = Quaternion.Slerp(
this.transform.rotation,
targetRotation,
this.rotationSpeed * Time.deltaTime
);
(Очевидная) проблема с изменением заключается в том, что второе назначение targetRotation заменяет первое.
Я не уверен, как объединить операции кватерниона таким образом, чтобы воспроизвести то, что происходит, когда я устанавливаю вращение преобразования напрямую.
Я попытался их умножить, но это заставляет вращение вращаться все быстрее и быстрее, а не просто придерживаться значения this .Вращение.
Спасибо!
Ответ №1:
Сначала поверните глобал вверх на вращение вокруг this.Point.forward
. Для этого можно использовать *
оператор:
Vector3 upDir = Quaternion.AngleAxis(this.Rotation, this.Point.forward) * Vector3.up;
Затем, повернув его вверх, продолжайте, как и раньше:
targetRotation = Quaternion.LookRotation(this.Point.forward, upDir);
this.transform.rotation = Quaternion.Slerp(
this.transform.rotation,
targetRotation,
this.rotationSpeed * Time.deltaTime
);
И, кстати, использование функций Lerp / Slerp с a t
, значение которого никогда не гарантируется равным или превышающим 1, может привести к ошибкам из-за ошибок округления, если вам нужна гарантия, что результат в конечном итоге будет точно равен целевому.
Если эта гарантия не нужна, этот ответ здесь подойдет.
Если эта гарантия необходима, рассмотрите возможность использования чего-то другого (например, rotateTowards
) вместо Slerp
.