Unity как изменить ось вращения

Доброго времени суток. Имеется прямоугольник-палка с RigidBody2D и BoxCollider2D. У RigidBody2D заморожено вращение по x и y. Теперь если на прямоугольник падает другой объект, прямоугольник поворачивается относительно своего центра. Подскажите, как можно изменить точку, вокруг которой будет происходить это вращение?

Изменить центр вращения [Решено]

Изменить центр вращения [Решено]

Доброго времени суток. Имеется прямоугольник-палка с RigidBody2D и BoxCollider2D. У RigidBody2D заморожено вращение по x и y. Теперь если на прямоугольник падает другой объект, прямоугольник поворачивается относительно своего центра. Подскажите, как можно изменить точку, вокруг которой будет происходить это вращение?

Последний раз редактировалось Pollux 17 ноя 2017, 18:17, всего редактировалось 1 раз.

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31

Re: Изменить центр вращения

Сообщение waruiyume 17 ноя 2017, 05:03

Используйте один из типов вращающихся джойнтов.

Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6060
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Изменить центр вращения

Сообщение Pollux 17 ноя 2017, 14:47

waruiyume писал(а):Используйте один из типов вращающихся джойнтов.

Не могли бы Вы привести небольшой пример? Методом научного тыка попробовал несколько разных джоинтов, но абсолютно никакого эффекта не придало. До этого с ними никогда не работал.

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31

Re: Изменить центр вращения

Сообщение waruiyume 17 ноя 2017, 14:57

Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6060
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Изменить центр вращения

Сообщение Pollux 17 ноя 2017, 15:24

Спасибо, фактически работает, но на практике есть проблема. Точка опоры проседает под весом других объектов. Такое же у меня наблюдается если делать вращение вокруг центра оси, заморозив в RigidBody2D оси x и y. Можно ли как то очень жестко закрепить точку?

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31

Re: Изменить центр вращения

Сообщение waruiyume 17 ноя 2017, 15:53

Насколько я знаю нет, но можно уменьшить это провисание.
Попробуйте:
Увеличить массу всех объектов в 10-100 раз(с 3d физикой такое прокатывало)
Уменьшить таймстеп пля 2d физики.
Увеличить solver iteration count(вроде так называется).
———
Проверил, у меня такого провисания нет. Может у вас слишком маленький масштаб или вы меняли настройки физики, или ваши объекты двигаются напрямую в обход физики? У меня 2017.2.

Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6060
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Изменить центр вращения

Сообщение Pollux 17 ноя 2017, 16:09

solver iteration count никак не повлиял.

waruiyume писал(а):Уменьшить таймстеп пля 2d физики.

Подскажите, где меняется данное значение? В настройках 2D физики есть только Time To Sleep.

———
Unity 5.6.2p4
У меня канвас 1920х1080 и уже в нем относительно него создаю объекты, масштаб везде 1, 1, 1.

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31


Re: Изменить центр вращения

Сообщение Pollux 17 ноя 2017, 16:19

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31

Re: Изменить центр вращения

Сообщение Pollux 17 ноя 2017, 17:27

Установил версию 2017.2, проблема осталась.

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31

Re: Изменить центр вращения [Решено]

Сообщение Pollux 17 ноя 2017, 18:16

Решил проблему абсолютно случайно, помог метод научного тыка. Сталкиваются палка, зафиксированная в определенной точке, и падающий на неё куб. Если хотя бы на одном из объектов в Rigidbody2D стоит CollisionDetection -> Continuous начинаются такие ненужные эффекты. Выставил в обоих CollisionDetection -> Discrete и теперь точка опоры палки жестко стоит на месте при любых массах объектов (но если разница будет слишком большая объект пройдет насквозь, но точка все равно будет на месте).

Аватара пользователя
Pollux
UNITрон
 
Сообщения: 276
Зарегистрирован: 01 сен 2016, 22:31


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 17



In Unity, you can use both Euler angles and quaternions to represent rotations and orientation. These representations are equivalent but have different uses and limitations.

Typically, you rotate objects in your sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary
using the Transform componentA Transform component determines the Position, Rotation, and Scale of each object in the scene. Every GameObject has a Transform. More info
See in Glossary
, which displays orientation as a Euler angle. However, Unity stores rotations and orientations internally as quaternions, which can be useful for more complex motions that might otherwise lead to gimbal lock.

Euler angles

In the Transform coordinate, Unity displays rotation with the vector property Transform.eulerAngles X, Y, and Z. Unlike a normal vector, these values actually represent the angle (in degrees) of rotation about the X, Y, and Z axes.

Euler angle rotations perform three separate rotations around the three axes. Unity performs the Euler rotations sequentially around the z-axis, the x-axis and then the y-axis. This method of rotation is extrinsic rotation; the original coordinate system doesn’t change while the rotations occur.

To rotate a GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary
, you can enter angle values of how far you want each axis to rotate into the Transform component. To rotate your GameObjects with script, use Transform.eulerAngles. If you convert to Euler angles to do calculations and rotations, you risk problems with gimbal lock.

Gimbal lock

When an object in 3D space loses a degree of freedom and can only rotate within two dimensions, it’s called gimbal lock. Gimbal lock can occur with Euler angles if two axes become parallel.
If you don’t convert the rotational values to Euler angles in your script, the use of quaternions should prevent gimbal lock.

If you do have problems with gimbal lock, you can avoid Euler angles if you use Transform.RotateAround for rotations. You can also use Quaternion.AngleAxis on each axis and multiply them together (quaternion multiplication applies each rotation in turn).

Quaternions

Quaternions provide mathematical notation for unique representations of spatial orientation and rotation in 3D space. A quaternion uses four numbers to encode the direction and angle of rotation around unit axes in 3D. These four values are complex numbers rather than angles or degrees. You can look into the mathematics of quaternions for more information.

Unity converts rotational values to quaternions to store them because quaternion rotations are efficient and stable to compute. The Editor doesn’t display rotations as quaternions because a single quaternion can’t represent a rotation greater than 360 degrees about any axis.

You can use quaternions directly if you use the Quaternion class. If you use script for your rotations, you can use the Quaternion class and functions to create and change rotational values. You can apply values to your rotation as Euler angles but you need to store them as quaternions to avoid problems.

Convert between Euler angles and quaternions

To convert between quaternions and Euler angles to view and edit your rotations in your preferred way, you can use script:

  • To convert from Euler angles to quaternions, you can use the Quaternion.Euler function.
  • To convert a quaternion to Euler angles, you can use the Quaternion.eulerAngles function.

Additional resources

  • Rotations in animations
  • Transforms
  • Transform.rotate
  • Important Classes — Quaternions
  • Quaternion

Каждый разработчик игр знает, что без вращения и поворотов игровых объектов невозможно сделать нормальную игру. И перед тем, как начать разбор поворота/вращения объекта, создадим игровой объект, и назовём его Player. Его мы и будем вращать.

Как поворот объекта, так и вращение, осуществляется путём изменения значений компонента Transform, и его свойства Transform.rotation.

И начнём данную статью с вращения, так как он более прост и понятен.

Вращение игрового объекта

Для начала разберём, что означает вращение? Вращение, это плавное изменение значений Transform.rotation, вокруг определённых осей. Вот их нам и нужно менять.

Для изменения этих значений, нам поможет метод Transform.Rotate. Работает он следующим образом:

void Update()
{
    transform.Rotate(0, 0, 1);
}

Этот скрипт будет вращать вашего персонажа по оси Z со скоростью 1. Вы так же можете выбрать другую ось вращения, например X или Y. Или же увеличить скорость вращения на 2.

void Update()
{
    transform.Rotate(2, 0, 0);
}

На этом всё! Как видите, вращать игровые объекты очень просто. Теперь перейдём к повороту, который по своей сути немного тяжелее.

Поворот игрового объекта

Поворот персонажа подразумевает его поворот на 180 градусов по одной из осей. Например, очень часто такое может понадобиться в 2д играх, преимущественно платформерного типа. Поэтому в качестве примера мы будем использовать 2д персонажа, которого нужно развернуть по горизонтали, то-есть по оси X.

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

Для того, чтобы это сделать, необходимо прописать следующий код:

Vector3 rotate = transform.eulerAngles;
rotate.y = 180;
transform.rotation = Quaternion.Euler(rotate);

Давайте разберём код:

  • В первой строке с помощью метода Transform.eulerAngles мы получаем значения roration в виде углов эйлера.
  • Во второй строке установили значение y в 180, тем самым развернули объект на 180 градусов.
  • В третьей строке, элеровские значения конвертируем в кватернионы, и сохраняем полученные данные.

Таким же образом мы можем вернуть объект в нормальное положение:

Vector3 rotate = transform.eulerAngles;
rotate.y = 0;
transform.rotation = Quaternion.Euler(rotate);

Аналогичным образом мы можем разворачивать наш объект по любой оси, изменив rotate.y на rotate.x или на rotate.z.

Если остались вопросы, пишите в комментариях. А так же ставьте лайки, если помог :)

Rotation and Orientation in Unity

Rotations in 3D applications are usually represented in one of two ways, Quaternions or Euler angles. Each has its own uses and drawbacks. Unity uses Quaternions internally, but shows values of the equivalent Euler angles in the inspector to make it easy for you to edit.

The Difference Between Euler Angles and Quaternions

Euler Angles

Euler angles have a simpler representation, that being three angle values for X, Y and Z that are applied sequentially. To apply a Euler rotation to a particular object, each rotation value is applied in turn, as a rotation around its corresponding axis.

  • Benefit: Euler angles have an intuitive “human readable” format, consisting of three angles.
  • Benefit: Euler angles can represent the rotation from one orientation to another through a turn of more than 180 degrees
  • Limitation: Euler angles suffer from Gimbal Lock. When applying the three rotations in turn, it is possible for the first or second rotation to result in the third axis pointing in the same direction as one of the previous axes. This means a “degree of freedom” has been lost, because the third rotation value cannot be applied around a unique axis.

Quaternions

Quaternions can be used to represent the orientation or rotation of an object. This representation internally consists of four numbers (referenced in Unity as x, y, z & w) however these numbers don’t represent angles or axes and you never normally need to access them directly. Unless you are particularly interested in delving into the mathematics of Quaternions, you only really need to know that a Quaternion represents a rotation in 3D space and you will never normally need to know or modify the x, y & z properties.

In the same way that a Vector can represent either a position or a direction (where the direction is measured from the origin), a Quaternion can represent either an orientation or a rotation — where the rotation is measured from the rotational “origin” or “Identity”. It because the rotation is measured in this way — from one orientation to another — that a quaternion can’t represent a rotation beyond 180 degrees.

  • Benefit: Quaternion rotations do not suffer from Gimbal Lock.
  • Limitation: A single quaternion cannot represent a rotation exceeding 180 degrees in any direction.
  • Limitation: The numeric representation of a Quaternion is not intuitively understandable.

In Unity all Game Object rotations are stored internally as Quaternions, because the benefits outweigh the limitations.

In the Transform Inspector however, we display the rotation using Euler angles, because this is more easily understood and edited. New values entered into the inspector for the rotation of a Game Object are converted “under the hood” into a new Quaternion rotation value for the object.

The rotation of a Game Object is displayed and edited as Euler angles in the inspector, but is stored internally as a QuaternionThe rotation of a Game Object is displayed and edited as Euler angles in the inspector, but is stored internally as a Quaternion

As a side-effect, it is possible in the inspector to enter a value of, say, X: 0, Y: 365, Z: 0 for a Game Object’s rotation. This is a value that is not possible to represent as a quaternion, so when you hit Play you’ll see that the object’s rotation values change to X: 0, Y: 5, Z: 0 (or thereabouts). This is because the rotation was converted to a Quaternion which does not have the concept of “A full 360-degree rotation plus 5 degrees”, and instead has simply been set to be oriented in the same way as the result of the rotation.

Implications for Scripting

When dealing with handling rotations in your scripts, you should use the Quaternion class and its functions to create and modify rotational values. There are some situations where it is valid to use Euler angles, but you should bear in mind: — You should use the Quaternion Class functions that deal with Euler angles — Retrieving, modifying, and re-applying Euler values from a rotation can cause unintentional side-effects.

Creating and Manipulating Quaternions Directly

Unity’s Quaternion class has a number of functions which allow you to create and manipulate rotations without needing to use Euler angles at all. For example:

However sometimes it’s desirable to use Euler angles in your scripts. In this case it’s important to note that you must keep your angles in variables, and only use them to apply them as Euler angles to your rotation. While it’s possible to retrieve Euler angles from a quaternion, if you retrieve, modify and re-apply, problems will arise.

Here are some examples of mistakes commonly made using a hypothetical example of trying to rotate an object around the X axis at 10 degrees per second. This is what you should avoid:

And here is an example of using Euler angles in script correctly:

Implications for Animation

Many 3D authoring packages, and indeed Unity’s own internal animation window, allow you to use Euler angles to specify rotations during an animation.

These rotations values can frequently exceed range expressable by quaternions. For example, if an object should rotate 720 degrees in-place, this could be represented by Euler angles X: 0, Y: 720, Z:0. But this is simply not representable by a Quaternion value.

Unity’s Animation Window

Within Unity’s own animation window, there are options which allow you to specify how the rotation should be interpolated — using Quaternion or Euler interpolation. By specifying Euler interpolation you are telling Unity that you want the full range of motion specified by the angles. With Quaternion rotation however, you are saying you simply want the rotation to end at a particular orientation, and Unity will use Quaternion interpolation and rotate across the shortest distance to get there. See Using Animation Curves for more information on this.

External Animation Sources

When importing animation from external sources, these files usually contain rotational keyframe animation in Euler format. Unity’s default behaviour is to resample these animations and generate a new Quaternion keyframe for every frame in the animation, in an attempt to avoid any situations where the rotation between keyframes may exceed the Quaternion’s valid range.

For example, imagine two keyframes, 6 frames apart, with values for X as 0 on the first keyframe and 270 on the second keyframe. Without resampling, a quaternion interpolation between these two keyframes would rotate 90 degrees in the opposite direction, because that is the shortest way to get from the first orientation to the second orientation. However by resampling and adding a keyframe on every frame, there are now only 45 degrees between keyframes so the rotation will work correctly.

There are still some situations where — even with resampling — the quaternion representation of the imported animation may not match the original closely enough, For this reason, in Unity 5.3 and onwards there is the option to turn off animation resampling, so that you can instead use the original Euler animation keyframes at runtime. For more information, see Animation Import of Euler Curve Rotations.

Трансформации

Компонент Transform (трансформация) используется для хранения значений позиции, вращения, размеров и состояния наследования GameObject’а, потому он очень важен. К GameObject’у всегда добавлен компонент Transform — его невозможно удалить или создать GameObject без него.

Редактирование трансформаций

Компоненты Transform управляются в 3D пространстве по осям X, Y, и Z, или в 2D пространстве просто по X и Y. В Unity эти оси представлены красным, зелёным и синим цветами соответственно.

Tramsform c цветными осямиTramsform c цветными осями

Transform может быть изменён в окне Scene или путём изменения параметров в инспекторе. В сцене вы можете изменять Transform используя инструменты Translate, Rotate и Scale (двигать, вращать и масштабировать). Эти инструменты расположены в верхнем левом углу редактора Unity.

Инструменты View, Translate, Rotate и ScaleИнструменты View, Translate, Rotate и Scale

Эти инструменты можно применить к любому объекту в сцене. Когда вы кликнете на объект, вы увидите, что у объекта появится гизмо инструмента. Вид гизмо зависит от выбранного инструмента.

Гизмо TransfromаГизмо Transfrom’а

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

Transfrom с выделенной (жёлтой) осью XTransfrom с выделенной (жёлтой) осью X

Для режима перемещения есть дополнительная опция — перемещение объекта в отдельной плоскости (другими словами, позволяет перемещать объект в двух осях сразу, не затрагивая третью). Три маленьких цветных квадрата вокруг центра гизмо перемещения активируют фиксацию для каждой из плоскостей; цвета соответствуют оси, которая будет зафиксирована, если нажать на квадрате (например, синий квадрат фиксирует ось Z).

Наследование

Наследование — один из самых важных концептов, который следует понимать при использовании Unity. Когда GameObject является родительским для другого объекта, дочерний GameObject будет двигаться, вращаться и менять размер в той же степени, что и родительский объект. Вы можете представлять наследование как связь между вашими руками и вашим телом; когда ваше тело движется, то ваши руки также двигаются вместе с ним. Дочерние объекты могут иметь и свои дочерние объекты и так далее. Таким образом, ваши ладони могут считаться “детьми” ваших рук, а у каждой ладони есть несколько пальцев и т.д. Любой объект может иметь несколько “детей”, но только одного родителя. Эти многоуровневые связи родители-дети формируют иерархию трансформаций. Объект на самом верху иерархии (т.е. единственный объект, у которого нет родителя) известен как root (корень).

Вы можете создать родительский объект перетягиванием любого GameObject’а в окне Hierarchy на другой объект. Это создаст связь родительский-дочерний между двумя игровыми объектами.

Пример родительской иерархии. Объекты с раскрывающимися стрелками слева от их имён являются родительскими.Пример родительской иерархии. Объекты с раскрывающимися стрелками слева от их имён являются родительскими.

Учтите, что значения Transform в инспекторе для любого дочернего объекта показаны относительно значений Transform родительского объекта. Эти значения известны как локальные координаты . Возвращаясь к аналогии тела и рук, положение вашего тела может изменяться по мере ходьбы, но ваши руки будут присоединены в одном и том же месте относительно тела. Для построения сцены обычно достаточно работать с локальными координатами для дочерних объектов, но во время игрового процесса зачастую полезно найти их точное положение в мировом пространстве или их мировые координаты . API скриптинга для компонента Transform имеет отдельные настройки для локальных и мировых координат.

Проблемы производительности и ограничения неравномерного (Non-Uniform) масштабирования

Неравномерное масштабирование (Non-uniform Scaling) — это когда параметр Scale в Transform имеет разные значения для x, y, и z; например (2, 4, 2). И наоборот, при равномерном масштабировании, x, y и z имеют одинаковые значения; например (3, 3, 3). Неравномерное масштабирование может быть полезно в некоторых особых случаях, но вам лучше стараться этого избегать, поскольку это замедляет рендеринг графики. Также могут появиться некоторые странности, которых не бывает при равномерном масштабировании:-

  • Некоторые компоненты не имеют полной поддержки неравномерного масштабирования. Например у некоторых компонентов есть круглый или сферический элемент с заданным параметром radius . Среди таких компонентов есть Sphere Collider , Capsule Collider , Light и Audio Source . В подобных случаях круглая форма не станет эллиптической под влиянием неравномерного масштабирования, а просто останется круглой.
  • Если у дочернего объекта есть неравномерно отмасштабированный родитель, и он (дочерний объект) повёрнут относительно родителя, он может стать перекошенным или “сдвинутым”. Есть компоненты, которые поддерживают простое неравномерное масштабирование, но некорректно работают такими перекосами. Например, перекошенный Box Collider не будет точно совпадать с формой меша.
  • По причинам производительности, масштаб дочернего объекта неравномерно отмасштабированного родителя не будет автоматически обновлён при вращении. В результате, форма дочернего объекта может резко измениться, после того как масштаб уже обновился, например, после отделения дочернего объекта от родителя.

Важность масштаба

Масштаб Transform’а определяет разницу между размером меша в приложении для моделирования и размером этого же меша в Unity. Размер меша в Unity (он же — масштаб Transform’a) очень важен, особенно во время физических симуляций. По умолчанию, физический движок предполагает, что одна единица меры в мировом пространстве соответствует одному метру. Если объект очень большой, может получиться, что он будет падать “в замедленном времени”; симуляция на самом деле правильная, т.к. по сути, вы смотрите с большого расстояния на то, как падает очень большой объект.

Есть 3 фактора которые могут повлиять на масштаб вашего объекта:

  • Размер вашего меша в вашем приложении для 3D моделирования.
  • Коэффициент Mesh Scale Factor устанавливаемый в настройках импорта объекта ( Import Settings ).
  • Значение параметра Scale компонента Transfrom.

В идеале, вам не надо настраивать параметр Scale вашего объекта в компоненте Transform. Лучшим вариантом является создание моделей реалистичного размера, таким образом, чтобы вам не пришлось менять масштаб. Следующим лучшим вариантом является настройка масштаба в настройках Import Settings импортированного меша, для конкретного меша. Некоторые оптимизации производятся на основе размера при импорте, и создание экземпляра объекта с изменённым значением масштаба может снизить производительность. Для дополнительной информации, прочитайте раздел об оптимизации масштаба на странице справки по компоненту Rigidbody.

Rotation and Orientation in Unity

Rotations in 3D applications are usually represented in one of two ways, Quaternions or Euler angles. Each has its own uses and drawbacks. Unity uses Quaternions internally, but shows values of the equivalent Euler angles in the inspector to make it easy for you to edit.

The Difference Between Euler Angles and Quaternions

Euler Angles

Euler angles have a simpler representation, that being three angle values for X, Y and Z that are applied sequentially. To apply a Euler rotation to a particular object, each rotation value is applied in turn, as a rotation around its corresponding axis.

  • Benefit: Euler angles have an intuitive “human readable” format, consisting of three angles.
  • Benefit: Euler angles can represent the rotation from one orientation to another through a turn of more than 180 degrees
  • Limitation: Euler angles suffer from Gimbal Lock. When applying the three rotations in turn, it is possible for the first or second rotation to result in the third axis pointing in the same direction as one of the previous axes. This means a “degree of freedom” has been lost, because the third rotation value cannot be applied around a unique axis.

Quaternions

Quaternions can be used to represent the orientation or rotation of an object. This representation internally consists of four numbers (referenced in Unity as x, y, z & w) however these numbers don’t represent angles or axes and you never normally need to access them directly. Unless you are particularly interested in delving into the mathematics of Quaternions, you only really need to know that a Quaternion represents a rotation in 3D space and you will never normally need to know or modify the x, y & z properties.

In the same way that a Vector can represent either a position or a direction (where the direction is measured from the origin), a Quaternion can represent either an orientation or a rotation — where the rotation is measured from the rotational “origin” or “Identity”. It because the rotation is measured in this way — from one orientation to another — that a quaternion can’t represent a rotation beyond 180 degrees.

  • Benefit: Quaternion rotations do not suffer from Gimbal Lock.
  • Limitation: A single quaternion cannot represent a rotation exceeding 180 degrees in any direction.
  • Limitation: The numeric representation of a Quaternion is not intuitively understandable.

In Unity all Game Object rotations are stored internally as Quaternions, because the benefits outweigh the limitations.

In the Transform Inspector however, we display the rotation using Euler angles, because this is more easily understood and edited. New values entered into the inspector for the rotation of a Game Object are converted “under the hood” into a new Quaternion rotation value for the object.

The rotation of a Game Object is displayed and edited as Euler angles in the inspector, but is stored internally as a QuaternionThe rotation of a Game Object is displayed and edited as Euler angles in the inspector, but is stored internally as a Quaternion

As a side-effect, it is possible in the inspector to enter a value of, say, X: 0, Y: 365, Z: 0 for a Game Object’s rotation. This is a value that is not possible to represent as a quaternion, so when you hit Play you’ll see that the object’s rotation values change to X: 0, Y: 5, Z: 0 (or thereabouts). This is because the rotation was converted to a Quaternion which does not have the concept of “A full 360-degree rotation plus 5 degrees”, and instead has simply been set to be oriented in the same way as the result of the rotation.

Implications for Scripting

When dealing with handling rotations in your scripts, you should use the Quaternion class and its functions to create and modify rotational values. There are some situations where it is valid to use Euler angles, but you should bear in mind: — You should use the Quaternion Class functions that deal with Euler angles — Retrieving, modifying, and re-applying Euler values from a rotation can cause unintentional side-effects.

Creating and Manipulating Quaternions Directly

Unity’s Quaternion class has a number of functions which allow you to create and manipulate rotations without needing to use Euler angles at all. For example:

However sometimes it’s desirable to use Euler angles in your scripts. In this case it’s important to note that you must keep your angles in variables, and only use them to apply them as Euler angles to your rotation. While it’s possible to retrieve Euler angles from a quaternion, if you retrieve, modify and re-apply, problems will arise.

Here are some examples of mistakes commonly made using a hypothetical example of trying to rotate an object around the X axis at 10 degrees per second. This is what you should avoid:

And here is an example of using Euler angles in script correctly:

Implications for Animation

Many 3D authoring packages, and indeed Unity’s own internal animation window, allow you to use Euler angles to specify rotations during an animation.

These rotations values can frequently exceed range expressable by quaternions. For example, if an object should rotate 720 degrees in-place, this could be represented by Euler angles X: 0, Y: 720, Z:0. But this is simply not representable by a Quaternion value.

Unity’s Animation Window

Within Unity’s own animation window, there are options which allow you to specify how the rotation should be interpolated — using Quaternion or Euler interpolation. By specifying Euler interpolation you are telling Unity that you want the full range of motion specified by the angles. With Quaternion rotation however, you are saying you simply want the rotation to end at a particular orientation, and Unity will use Quaternion interpolation and rotate across the shortest distance to get there. See Using Animation Curves for more information on this.

External Animation Sources

When importing animation from external sources, these files usually contain rotational keyframe animation in Euler format. Unity’s default behaviour is to resample these animations and generate a new Quaternion keyframe for every frame in the animation, in an attempt to avoid any situations where the rotation between keyframes may exceed the Quaternion’s valid range.

For example, imagine two keyframes, 6 frames apart, with values for X as 0 on the first keyframe and 270 on the second keyframe. Without resampling, a quaternion interpolation between these two keyframes would rotate 90 degrees in the opposite direction, because that is the shortest way to get from the first orientation to the second orientation. However by resampling and adding a keyframe on every frame, there are now only 45 degrees between keyframes so the rotation will work correctly.

There are still some situations where — even with resampling — the quaternion representation of the imported animation may not match the original closely enough, For this reason, in Unity 5.3 and onwards there is the option to turn off animation resampling, so that you can instead use the original Euler animation keyframes at runtime. For more information, see Animation Import of Euler Curve Rotations.

Rotating an object in Unity can be very straightforward.

However,

Just as there are many different ways to move an object, there are many different ways to rotate one too.

Which means that knowing the right method to use, in order to get the effect that you want, can be a little confusing at first.

But don’t worry, because in this in-depth guide I’ll show you all of the different methods for rotating an object in Unity, and the best time to use each of them, step by step.

Here’s what you’ll find on this page:

  • How to rotate an object in Unity
  • How to rotate an object around a point in Unity
  • How to rotate a vector in Unity
  • How to rotate the camera around an object in Unity
  • How to rotate an object towards another
  • How to rotate an object over time (Lerp & Slerp)
  • How to Rotate a Rigidbody with the mouse
  • How to Rotate objects in 2D

Rotation in Unity: Overview video

For a general overview of how to rotate in Unity, try my video, or continue to the full article below.



How to rotate an object in Unity

There are a lot of different ways to rotate an object in Unity.

Some methods are simple, some are more complex.

While others work best for certain tasks.

But don’t worry,

While there are a lot of different options available to you, many of them work in similar ways.

Which means that once you’re used to the basics of rotating an object in Unity, you’ll find it easier to use some of the more advanced rotation features that Unity offers.

So what is the basic method?

Rotation in Unity typically works by specifying an amount of rotation in degrees around the X, Y or Z axis of an object.

In the Inspector, you’ll see an object’s rotation as a Vector 3 value:

Unity Game Object Transform

In the same way that a game object’s position in the world can be set using its Transform component…

Like this:

Vector3 newPosition = new Vector3(0, 10, 0);
transform.position = newPosition;

An object’s rotation can also be set directly via its Transform,

Like this:

Vector3 newRotation = new Vector3(0, 10, 0);
transform.eulerAngles = newRotation;

In this example, I’ve set the rotation of the object to 10 degrees around the Y Axis.

Unity XYZ Axes

Rotational vector 3 values describe a degree of rotation around each of the 3 axes, X Y and Z.

Notice, however, that I didn’t set the rotation property directly like I might do when setting an object’s position, for example.

Instead, I set a different property, Euler Angles.

Why did I do it like that?

Behind the scenes, Unity calculates rotation using Quaternions, meaning that the rotation property of an object is not actually a Vector 3, it’s a Quaternion.

The rotation value you see in the Inspector is the real Quaternion rotation converted to a Vector 3 value, an Euler Angle, which is rotation expressed as an XYZ value for pitch, yaw and roll.

So, when using Transform.eulerAngles, you’re essentially setting and reading a converted value.

This means that if you want to set the rotation property directly, you’ll need to use a Quaternion value instead.

Like this:

// Copies another object's rotation
Quaternion objectRotation = otherObject.transform.rotation;
transform.rotation = objectRotation;

Or, instead of working in Quaternions, you can convert a Vector 3 Euler Angle rotation into a Quaternion.

Like this:

transform.rotation = Quaternion.Euler(new Vector3(0,10,0));

The Euler Angles property is a convenient way to set and read an object’s rotation in a format that’s easier to read and work with than Quaternions.

Quaternions vs Euler Angles in Unity

Should you use Quaternions or Euler Angles in Unity?

While Unity uses Quaternions behind the scenes, many of Unity’s rotation functions will allow you to use either type of value, either natively or by converting the value.

But which is better?

Generally speaking, Unity uses Quaternions because they’re efficient and avoid some of the problems of using Euler Angles, such as gimbal lock, which is the loss of a degree of movement when two axes are aligned the same way.

However, Quaternions are complex and aren’t designed to be worked with directly.

Euler Angles, on the other hand, are easier to read and work with.

Because of this, if you want to manually set a rotation, or provide a rotation amount in degrees, then it will be much easier to use an Euler Angle value to do so, and you’ll likely find that there’s an Euler based function available for you to do just that.

However, you may start to run into problems if you directly apply Euler Angle based rotation on a per axis basis or manually over time.

So what’s the answer?

It’s best to think of Euler Angles as a method of describing Quaternions in Unity.

They make reading and manually setting the rotation of an object easier to do.

However…

Trying to work exclusively in Euler Angles can cause unexpected behaviour.

For example, the converted Euler Angle value can vary, since the same Quaternion rotation can be described using different Euler values, or you might reintroduce gimbal lock by trying to work only with Euler Angles in local variables.

In practice, when using Unity’s built-in rotation functions, you shouldn’t need to worry about gimbal lock, even when passing in Euler Angles.

Unity will convert the Euler value and work with Quaternions behind the scenes, avoiding the typical problems associated with Eulers, while keeping their ease of use.

So while it’s generally better to use Quaternions when you can, there’s nothing wrong with using Euler Angles with Unity’s built-in rotation functions.

Setting the rotation of an object directly via its rotation property can be very straightforward.

However…

While this works well for setting an absolute rotation, one time, it’s not as useful for adding rotation to an object.

For example, to rotate an object by a set amount of degrees from its current orientation to a new one.

For that, you’ll need the Rotate function.

How to Rotate an object in Unity using the Rotate function

 While setting the Euler Angles property of an object changes its absolute rotation, there will often be times when you want to add an amount of rotation to an object instead.

For example, to turn an object round by 90 degrees:

void RotateByDegrees()
    {
        Vector3 rotationToAdd = new Vector3(0, 90, 0);
        transform.Rotate(rotationToAdd);
    }

Instead of setting the rotation directly, like before, the Rotate function adds 90 degrees to the Y-Axis every time it’s called.

Rotate an object by 90 degrees in Unity

Or you could add rotation every frame to make an object spin smoothly.

Like this:

float degreesPerSecond = 20;
private void Update()
{
    transform.Rotate(new Vector3(0, degreesPerSecond, 0) * Time.deltaTime);
}

In this example, I’m multiplying the rotation amount by Time.deltaTime (the duration of the last frame) to make sure that the rotation is smooth and consistent.

Even if you’re a beginner, you may have already multiplied values by Delta Time before in Unity, as it’s usually required for any kind of function that occurs over time, such as movement, rotation or lerping. This is to make sure that, even if the framerate changes, the amount of movement over time remains the same.

In this case, it changes the amount of rotation from 20 degrees per frame to 20 degrees per second.

Which looks like this:

Rotate an object automatically in Unity

Rotate vs Rotation in Unity

Typically, Rotation in Unity refers to the rotation property of an object. In other words, the rotation values you see in the inspector, while Rotate is a function for adding an amount of rotation to an object.

So if you want to read the rotation of an object, or set it directly, you’d typically use the rotation property (or the Vector 3 shortcut: transform.eulerAngles). Whereas, if you want to apply an amount of rotation to an object, the Rotate function is designed to do exactly that.

Local rotation vs world rotation

An object’s rotation in Unity can be relative to the world or it can be local, where the rotation amount is relative to the rotation of its parent object.

Both an object’s local rotation and its absolute world rotation can be read as properties of the object’s transform.

Vector3 worldRotation = transform.eulerAngles;
Vector3 localRotation = transform.localEulerAngles;

A lot of the time, the local and world rotation of an object will be the same.

This is because, either the object that’s being rotated doesn’t have a parent object or because that parent object doesn’t have any rotation applied to it, in which case there’s no difference between the two values.

For example, if you rotate a child object by 90 degrees but don’t apply any rotation to the parent object, then the world rotation and the local rotation of the child object will both be the same.

This makes sense, because the child object has an amount of rotation applied to it which, when added to the parent’s rotation of zero, matches the object’s real rotation in the world.

However, if you only apply rotation to an object’s parent then the local rotation value for the child object will be different.

While the world rotation will match the parent, the local rotation will be zero, as no rotation is being applied by the child object’s transform.

Put simply, the world rotation value is the absolute rotation relative to world space. In this example, it’s the rotation of the parent object plus any locally applied rotation, if there is any. While the local rotation value is just the extra rotation added by that object’s Transform component.

So, which one should you use?

When working with rotation directly, for example when setting the rotation of an object via its Euler Angle property, you’ll have the option to set either its world rotation or its local rotation.

By default, when setting rotation directly, you’re setting the object’s world rotation:

// World Rotation
transform.eulerAngles = new Vector3(0,90,0);

Setting the world rotation of a child object will rotate it into that position absolutely.

This means that if the object has a parent with any rotation, the local rotation of the child will not be set to the new rotation value as you might expect. Instead, it will be set to a value that is equal to the difference between the parent’s rotation and the world rotation.

Basically, the local rotation will be set to whatever it needs to be in order to achieve the absolute world rotation you specified.

For example, if you set a child object to a world rotation of 50 degrees around an axis, and the object’s parent is already rotated by 10 degrees, the child object’s rotation will be set to 40 degrees, not the 50 you passed in.

The rotation of the object will technically be correct, you’ll get exactly what you asked for, but you may get some confusing results if you apply world rotation to child objects in this way.

So if you find that, when setting the rotation of an object via scripting, the Inspector values and the rotation don’t match, it might be because you’re setting the world rotation of a child object.

If, however, you only want to apply rotation locally, you can do that by using the local rotation value:

// Local Rotation
transform.localEulerAngles = new Vector3(0,90,0);

A lot of the time, this won’t make any difference.

When the object you rotate doesn’t have a parent, or if the parent isn’t rotated, using either method will produce the same effect.

However, there may be times when you’d like to position an object one way and rotate it another.

For example, if you want to spin an object that’s already rotated, like this titled chair:

Titled chair rotating on a flat Y Axis

This chair is already rotated but spins on a flat Y-Axis.

One of the easiest ways to achieve this, and other rotation effects like it, is to simply nest the object inside another empty game object.

Nested game object in unity

The child object can then be tilted to any local rotation you like, while the parent container can be automatically rotated on a flat Y-Axis in world space.

Separating the orientation of an object from its rotation like this can be useful for making rotation simpler to manage and easier to control. 

Alternatively, if you don’t want to nest objects together, many of Unity’s built-in rotation functions, such as Transform Rotate can be overridden to operate in local or world space, recreating this effect, without the need for additional game objects.

How to rotate an object around a point in Unity

Rotating an object in Unity around one of its axes can be very simple.

For example, spinning a cube or turning an object upside-down can be very straightforward.

However…

As you start to rotate more complex objects, you may begin to notice that the position of the pivot point around which an object rotates is just as important as the rotation itself.

For example, if you build a basic door out of some primitive shapes, and then try to rotate it by 90 degrees to open it, you’ll quickly notice that something is wrong.

How not to rotate a door in Unity

This is not how doors work.

In this example, I’ve built a door out of primitive objects, which means that the pivot point for the parent object, the main part of the door in my case, is in the centre.

This means that, when I rotate the object on its Y-Axis, it rotates around its centre.

Which, as I’m sure you’ve noticed, is not how most doors work.

So what can I do about it?

To fix it, I need to change the pivot point of the 3D object.

How to move the pivot point of a 3d object

Usually, when working with 3D objects that have been created using other tools, the pivot point of the object is set when the object is created.

For example, if I purchase a door model from the Asset Store, chances are that the pivot point will be in the correct place, on the door’s hinge.

I didn’t do that so, instead, I need to move the pivot point to a different position that allows me to rotate the door in the way I want.

Luckily it’s an easy problem to solve, by adding the game object you want to rotate as a child of another object that can act as a pivot point.

Here’s how:

  1. Place the object you want to rotate in position
  2. Next, create a new game object, the pivot, and place it at the pivot point of the rotation. Keep it separate while you’re positioning it.
  3. Finally, in the hierarchy, drag the object you want to rotate on to the pivot object, making it a child of the pivot

Then, instead of rotating the object directly, simply rotate the pivot.

Rotate a door on a hinge in Unity

Creating a parent object is an easy way to change the pivot point in Unity

The same technique can be used to centre an object’s pivot point if, for whatever reason, it’s not already in the middle of your object.

You could even nest the root object (now the pivot) in another object that doesn’t rotate, and manage the local rotation of the pivot using a script.

Creating a parent object is an easy way to move the pivot point of an object.

However, it’s also possible to rotate an object around a point, without creating a parent object pivot, using Rotate Around.

How to use Rotate Around in Unity

Rotate Around works in a similar way to the parent object pivot method.

However, instead of creating a pivot point object and rotating it, the Rotate Around function takes a Vector 3 position, in world space, an axis to rotate around, and an angle in degrees.

Transform.RotateAround(Vector3 point, Vector3 axis, float angle);

This means that you can use Rotate Around to rotate an object either around a fixed point in world space,

Like this:

Vector3 pivotPoint = new Vector3 (-3.5f,0,0);
void RotateAroundPoint()
{
    // Rotates around the pivot point and the Y-Axis by 90 degrees
    transform.RotateAround(pivotPoint, Vector3.up, 90);
}

Or around another object entirely,

Like this:

public Transform objectToRotateAround;
void RotateAroundObject()
{
    // Rotates around the pivot object's position and the Y-Axis by 90 degrees
    transform.RotateAround(objectToRotateAround.position, Vector3.up, 90);
}

When using Rotate Around, the first argument, the Vector 3 point, is the pivot of the rotation while the 2nd Vector 3, the axis, decides which direction rotation will be applied.

This is important, as it determines which route around the point the object will rotate.

Finally, the float value, the angle, is the amount of rotation that will be applied in degrees.

How to define an axis of rotation in Unity

Several of Unity’s built-in rotation functions, such as Rotate Around, require you to enter an axis parameter in the form of a Vector 3 value, to determine the direction of the rotation that’s applied.

Entering a vector, using XYZ values, creates the definition of direction that’s used to determine the rotational axis.

For example, a vector of (1,0,0) would rotate around the X-Axis, while (0,1,0) rotates around the Y-Axis and (0,0,1) rotates around the Z-Axis.

Entering a mix of values creates a direction vector that’s proportionate to the values entered.

However, most of the time, you’ll probably only need to enter basic Axis values which, helpfully, can be accessed using Vector 3 shorthand, such as Vector3.left for the X-Axis, Vector3.up for the Y-Axis and Vector3.forward for the Z-Axis.

While these shortcuts represent basic directions relative to world space, it’s also possible to define an local directional value by referencing an object’s Transform component.

So, while Vector3.up represents the global up direction, Transform.up represents up in relation to a game object’s Transform.

Just like the Rotate function, Rotate Around is only applied once when it’s called, which means if you want to create continuous rotation, you’ll need to call Rotate Around in Update, multiplying the angle value by Delta Time.

Like this:

public Transform objectToOrbit;
void Update()
{
    transform.RotateAround(objectToOrbit.position, Vector3.up, 10 * Time.deltaTime);
}

Rotate Around can be used to create rotation around other objects and points without using the parent object method, which can be useful for rotating an object around another, without needing to rotate both of them.

For example, I could use Rotate Around to create a basic orbit where the planet rotates around the sun and the planet’s moon rotates around the planet.

How to orbit an object in Unity

Rotate Around can be used to create a simple planetary orbit.

In this example, the moon is a child of the planet, which means that the moon’s position is being affected by the rotation of the planet.

While Rotate Around can be very useful and straightforward, there are a couple of drawbacks to using this method.

For example, if you use Rotate Around to move one object around another, and the object that’s being orbited moves, it’s going to affect the path of rotation.

And, while it’s possible to adjust the position of the object to avoid this, there’s another problem.

When using the Rotate Around function, the rotating object turns towards the point it’s rotating around.

Example of Rotate Around in Unity

Using Rotate Around will also turn the orbiting object to face its point of rotation

This isn’t necessarily a bad thing.

In fact, it can be very useful, such as when rotating a camera around an object.

However, if you’re making an object orbit another, like in this example, it isn’t really how planetary orbits work.

Planets tend to spin around their own axis, while their position orbits around the sun.

So how can you rotate one object around another, without turning the object towards its point of orbit?

How can you rotate an object’s position around a point, without rotating the object itself?

Here’s how…

How to rotate a vector in Unity

A vector is a geometric value that defines a direction and length (which is the magnitude of the vector).

If you’ve worked with any kind of movement from one position to another, or done anything with Raycasts in Unity, then you will have used vectors before. Put simply, they describe direction and distance using Vector 3 values.

A Vector in Unity

A vector is a definition of direction and distance (the vector’s magnitude).

However… did you know that you can also rotate a vector by multiplying it by a Quaternion?

This works by multiplying the Quaternion rotation by the vector you want to rotate.

Like this:

// Defines a point forward from the origin by 10 units.
Vector3 orbit = Vector3.forward * 10;
// Rotates the orbit vector by degrees around the Y-Axis
orbit = Quaternion.Euler(0, 10, 0) * orbit;

The resulting vector, which has now been rotated, can be used to calculate where the rotated object should be in relation to the object it’s orbiting.

Like this: 

transform.position = objectToOrbit.transform.position + orbit;

Which means that, using vectors, it’s possible to rotate the position of one object around another in Unity, without actually rotating the object itself.

For example…

Let’s say that I want to orbit one object, a planet, around another, the sun, at a radius of 10 units and at a speed of 30 degrees per second.

First, I need a Vector.

In this case, all I want to do is define a direction and a radius, which will be the distance from the sun that the planet should orbit.

For that, I can multiply Vector3.forward, which is shorthand for (0,0,1) by 10, the radius. 

That will give me a vector of (0,0,10).

I can then rotate the vector with an angle value, which I can add to every frame at 30 degrees per second, to create a circular orbit.

Like this:

public GameObject objectToOrbit;
    public float angle;
    public float radius = 10;
    public float degreesPerSecond=30;
    private void Update()
    {
        angle += degreesPerSecond * Time.deltaTime;
        if (angle > 360)
        {
            angle -= 360;
        }
        Vector3 orbit = Vector3.forward * radius;
        orbit = Quaternion.Euler(0, angle, 0) * orbit;
        transform.position = objectToOrbit.transform.position + orbit;
    }

What’s happening here is that I’m taking a basic forward vector and rotating it from its starting point every frame by the angle value.

In this case, I’m rotating around the Y-Axis, but I could also have entered different values to produce different results.

Note, however, that the order of multiplication matters. When Multiplying a vector by a Quaternion the Quaternion must go on the left, otherwise, this won’t work (it won’t even compile).

Finally, because the vector that I’ve created and rotated isn’t attached to anything (it basically describes a vector from the centre of the world), I’ve set it as an offset to the position of the orbited object, the Sun.

The result is a rotation of a vector between two virtual points, not objects, that calculates where one object should be in relation to another, creating a path of rotation. The orbiting object behaves as if it’s nested, however rotating the sun has no effect on the planet and it’s possible to rotate the planet independently of its orbit around the sun.

In this example, I only rotated around the global Y-Axis, which is useful for creating an easy orbit.

However, if I wanted to, I could also set the rotation to match a specific direction-based axis.

For example, imagine that the planet is 10 units away but is also several units higher than the sun and I wanted to create a rotation based on that existing direction.

HOw to rotate an object in orbit - visualisation

Getting the direction of the planet from the sun allows me to create an orbit on a tilt.

It’s possible to get a direction vector between two objects in Unity by subtracting their positions.

Like this:

Vector3 direction = transform.position - objectToOrbit.transform.position;

I can then calculate a plane of rotation based on the starting direction and distance of the object from its point of orbit.

Like this:

public class Orbit2 : MonoBehaviour
{
    public GameObject objectToOrbit;
    public Vector3 direction;
    public float angle;
    public float radius;
    public float degreesPerSecond = 10;
    private void Start()
    {
        direction = (transform.position - objectToOrbit.transform.position).normalized;
        radius = Vector3.Distance(objectToOrbit.transform.position, transform.position);
    }
    private void Update()
    {
        angle += degreesPerSecond * Time.deltaTime;
        if (angle > 360)
        {
            angle -= 360;
        }
        Vector3 orbit = Vector3.forward * radius;
        orbit = Quaternion.LookRotation(direction) * Quaternion.Euler(0, angle, 0) * orbit;
        transform.position = objectToOrbit.transform.position + orbit;
    }
}

In this example, I’m measuring the direction and the distance of the object in Start, which gives me my orbit direction and radius.

I’m also normalising the vector, which limits its magnitude to 1. This basically limits the vector to directional information only, and while you don’t need to do this, I’m doing it so that I can multiply the direction vector by the radius variable, allowing me to change it later.

Once I have a direction vector, instead of rotating it around the world’s Y-Axis, which would cause the planet to orbit somewhere above the sun, I’m creating a new Quaternion angle using the Quaternion Look Rotation function instead. Look Rotation basically turns a direction vector into a Quaternion angle.

Then, to get the combined angle, I can multiply the Quaternion direction angle (which is the amount of tilt) by the angle of rotation (the angle float variable) to combine the two angles.

I’m still using the basic forward vector as a starting point, however now, instead of only multiplying it by the angle of rotation, I’m also rotating it by the angle of direction as well.

This is useful for creating automatic planet orbits as now, all I need to do is position the object relative to the point or object I want it to orbit, and the script will calculate a trajectory around that object.

Rotate around a tilted orbit in Unity

Planets can be given a more natural-looking orbit by rotating on an axis that’s based on their direction.

And if I want to change the axis of the orbit, I can do so by simply entering the angle into the X-Axis or the Z-axis instead.

This method is great for creating a path of rotation around a single axis.

However, there will often be times when you don’t want to just rotate one way around an object.

For example, what if you want to freely rotate a camera around the player using the mouse, or the keyboard, or using controller thumbsticks?

How can you pass input axes into a rotation function, to give the player control of the camera?

How to rotate the camera around an object in Unity

Being able to freely rotate the camera around an object with the mouse or other controls is a very common mechanic in many games; For example, to control the position of the camera around a player in 3rd-person.

In the previous example, moving a planet around the sun, I moved one object around another on a single plane of rotation, around the Y-Axis.

Rotating a camera around an object works in a similar way except, instead of a single fixed path, the player is able to freely move the camera around the object using two axes from the combined vertical and horizontal movements of the mouse, a controller thumbstick or keyboard keys.

So how do you do it?

One of the easiest ways to rotate the camera around an object is by using the Rotate Around function.

Rotate Camera with Mouse in Unity

Using Rotate Around is an easy way to give the player camera control with the mouse.

The Rotate Around function rotates an object around another point, relative to its distance, while turning the object to face the pivot.

This makes it ideal for creating a mouse orbit camera, as it keeps the camera looking at the object.

Like this:

public class CameraRotateAround : MonoBehaviour
{
    public Transform objectToOrbit;
    public float radius;
    void Update()
    {
        transform.position = objectToOrbit.position - (transform.forward * radius);
        transform.RotateAround(objectToOrbit.position, Vector3.up, Input.GetAxis("Mouse X"));
        transform.RotateAround(objectToOrbit.position, transform.right, Input.GetAxis("Mouse Y"));
    }
}

This works, first, by moving the camera so that it faces the target object, but set back by a distance that’s equal to the radius variable.

Notice that I’m using the forward vector of the camera object that this script is attached to, not Vector3.forward, which is the world forward, to keep the camera in position.

Then, using the Rotate Around function, the horizontal input of the mouse (its X-Axis) rotates around the target object around the Y-Axis, which moves the camera left and right around the player.

While the vertical movement of the mouse moves the camera relative to its own X-Axis, moving it up and down.

Using Rotate Around, the object that’s being rotated will turn towards the point that it’s rotating around. For this particular use case, this is ideal, as it means that the camera will look towards the object it’s rotating around automatically, providing a simple method of rotating a camera around an object.

It works well and it’s straightforward.

However, it is also possible to rotate the camera around an object without using the Rotate Around function.

Here’s how to do that…

How to rotate the camera around an object without using Rotate Around

While the Rotate Around function is a straightforward way to rotate the camera around an object, it’s not the only method.

Just as it was possible to orbit an object around a single axis by rotating a direction vector, the same method can be used to create 360 spherical rotation around a player or object.

The benefit of using this method over Rotate Around is that the rotation is entirely position based. Neither the object or the pivot point will be rotated as a result, which can be useful if, for whatever reason, you want to move an object around another with the mouse, but don’t want the object itself to rotate.

Like before it works by defining a basic vector, such as the forward vector, and then rotating it into position using inputs from the mouse.

Like this:

public class Orbit3 : MonoBehaviour
{
    public GameObject player;
    public float angleX;
    public float angleY;
    public float radius = 10;
    private void Update()
    {
        angleX += Input.GetAxis("Mouse X");
        angleY = Mathf.Clamp(angleY -= Input.GetAxis("Mouse Y"), -89, 89);
        radius = Mathf.Clamp(radius -= Input.mouseScrollDelta.y, 1, 10);
        if (angleX > 360)
        {
            angleX -= 360;
        }
        else if (angleX < 0)
        {
            angleX += 360;
        }
        Vector3 orbit = Vector3.forward * radius;
        orbit = Quaternion.Euler(angleY, angleX, 0) * orbit;
        transform.position = player.transform.position + orbit;
        transform.LookAt(player.transform.position);
    }
}

In this example, the X and Y movements of the mouse are added to two angle variables, angle X and angle Y.

To limit vertical movement, the Y angle is clamped at 89 degrees in both directions, to stop the camera from going over the top of the player and round again.

The X angle is also checked to see if it has moved past 360 degrees, or has moved below 0 degrees, in order to keep the value within a normal range.

This check isn’t strictly necessary, as the rotation function will work just fine without it, however keeping the value within a typical rotation range prevents a potential, although highly unlikely, problem of reaching the limit of the value type, as well as making the value easy to understand at a glance.

Finally, a forward vector, multiplied by a distance that’s equal to the radius, is rotated by the two angles, and the position of the camera is then moved to match.

Because this method of moving a camera around an object doesn’t affect the object’s rotation, I’ve used the Transform Look At function, which turns an object to face the direction of a Transform.

In this case, the Look At function is helpful for making sure that the camera is actually facing the player way when it’s rotated.

However, it’s not the only option for turning one object towards another…

How to rotate an object towards another

There are several methods available for rotating one object towards another.

Which one you use depends on how you want the object to rotate towards its target.

How to use Look At

Transform Look At, which instantly snaps an object’s rotation to face the transform of another object, is probably the easiest method of rotating an object towards a specific point.

Like this:

public Transform objectToLookAt;
void Update()
{
    transform.LookAt(objectToLookAt);
}

It takes a single Transform parameter, or a world position as a Vector 3, and will turn the object towards the target as soon as it’s called.

Look At Object Unity

Look At is one of the easiest ways to make one object look at another.

Look At is great as a quick and easy way to snap an object’s rotation towards another object or towards another point in the world.

However, because it’s a function of an object’s Transform, it automatically rotates towards the object when you call it.

And while this can be extremely useful, there may be times when you want to calculate the rotation value required to look at an object, without actually looking at it.

The Quaternion Look Rotation function can help you do that.

How to use Look Rotation

Look Rotation basically turns a direction vector into a rotation value.

This can be useful for calculating the rotation value towards an object or point, but without actually turning the object to point at it.

For example, I could calculate the direction vector of two points by subtracting their positions.

Like this:

Vector3 direction = objectToLookAt.transform.position - transform.position;

I could then pass that direction vector into the Look Rotation function to get a matching Quaternion rotation value.

Like this:

Quaternion targetRotation = Quaternion.LookRotation(direction);

I now have the rotation required to look at an object as a Quaternion value.

Why would I want to do this?

Why wouldn’t I just use Look At to turn the object to its target?

While Look At can be used to instantly turn an object to face another object or point, depending on what you’re trying to do, you may not want the rotation to happen immediately.

Instead, you might want the object to rotate towards the direction of its target slowly and smoothly.

Following the direction of the target, instead of snapping to it.

And for that, Look Rotation can be used to give you a target value for an object to smoothly rotate towards.

So, now that you have a target, how can you smoothly rotate an object?

How to slowly rotate towards another object

Many examples of smoothly rotating an object towards another tend to use Lerp, which stands for linear interpolation, or Slerp, meaning spherical interpolation, to achieve this kind of eased movement.

However… this isn’t actually what interpolation functions such as Lerp and Slerp are used for.

Lerp and Slerp are typically used to carry out a single movement over a period of time, such as a rotation from one fixed position to another, or a movement between two points.

  • More info: The right way to use Lerp in Unity (with examples)

However, continuous movement, such as an arrow following the direction of a target, isn’t really what Lerp or Slerp are designed to do.

If using interpolation functions in this way gets you results that you like, then go ahead!

But… for continuously following the direction of a target, there’s a better function to use, Rotate Towards.

Here’s how…

How to use Rotate Towards

Rotate Towards is a Quaternion function that works in a similar way to Move Towards, which you may have used before to move an object closer to a target.

It looks like this:

Quaternion.RotateTowards(Quaternion startRotation, Quaternion targetRotation, float maxDegreesDelta);

In the same way that Move Towards moves an object towards a target position a little bit each frame, Rotate Towards turns an object towards a target rotation each frame, without overshooting when it gets there.

The result is a smoothed movement towards a target rotation.

Rotate an object towards another slowly in Unity

Rotate Towards turns an object towards a target each frame.

The target rotation is the direction vector of the object you want to rotate towards, which can be worked out by subtracting the target’s position from the object’s position.

The Look Rotation function then turns the direction vector into a Quaternion rotation.

Like this:

Vector3 direction = objectToLookAt.transform.position - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(direction);

How fast Rotate Towards works depends on the Max Degrees Delta of the function, which limits how much the object can rotate in a single step.

Passing a degree value that’s multiplied by Delta Time into the Max Degrees Delta parameter sets the speed of the rotation in degrees per second.

Like this:

public Transform objectToLookAt;
void Update()
{
    float degreesPerSecond = 90 * Time.deltaTime;
    Vector3 direction = objectToLookAt.transform.position - transform.position;
    Quaternion targetRotation = Quaternion.LookRotation(direction);
    transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, degreesPerSecond);
}

The Rotate Toward function is ideal for continuous movement, as it’s always rotating towards a target at a specific speed.

However, if you want to perform a single rotation movement over a fixed amount of time, for example, to rotate an object 90 degrees over two seconds, then Lerp and Slerp can help you to do exactly that.

How to rotate an object over time (Lerp & Slerp)

While Rotate Towards continuously rotates an object towards a target at a set speed, you can use Lerp or Slerp to rotate an object by a fixed amount over a set period of time.

This works by taking a start rotation, such as the object’s own rotation at the start of the movement, a target rotation, which is where you want the object to end up, and a time value.

The time value, when calculated as time elapsed divided by duration, defines where the object should be during the movement. So, for example, at the halfway point (when time elapsed divided by duration equals 0.5) the rotation will be in the middle between the start and target rotations.

Then, once the movement has finished and the time has elapsed, the object is snapped into its final rotation.

So when might you use this?

Quaternion Lerp and Slerp are useful for rotating an object to a new rotation over a fixed amount of time.

For example, rotating an object around 90 degrees taking half a second,

Like this:

public class RotateObject : MonoBehaviour
{
    float lerpDuration = 0.5f;
    bool rotating;
    void Update()
    {
        if (Input.GetMouseButtonDown(0) && !rotating)
        {
            StartCoroutine(Rotate90());
        }
    }
    IEnumerator Rotate90()
    {
        rotating = true;
        float timeElapsed = 0;
        Quaternion startRotation = transform.rotation;
        Quaternion targetRotation = transform.rotation * Quaternion.Euler(0, 90, 0);
        while (timeElapsed < lerpDuration)
        {
            transform.rotation = Quaternion.Slerp(startRotation, targetRotation, timeElapsed / lerpDuration);
            timeElapsed += Time.deltaTime;
            yield return null;
        }
        transform.rotation = targetRotation;
        rotating = false;
    }
}

Because the rotation movement has a start, an end, and is carried out over a number of frames, it works best when placed in a Coroutine.

  • More info: Coroutines in Unity, how and when to use them

You may have also noticed that, in this example, I used Quaternion Slerp, not Lerp.

While the two functions are easily interchangeable, as both accept the same parameters, there is a slight difference between the two methods.

The difference between Lerp and Slerp for Rotation

When interpolating rotation, you’ll have the option to interpolate linearly, using Lerp, or spherically using Slerp.

Most of the time you’ll notice very little difference between the two methods. The main difference is that the length of the directional vector remains constant during Slerp while Lerp, which is linear, can be more efficient to perform.

Lerp vs Slerp in Unity

Lerp (green) vs Slerp (red)

So which should you use?

Generally speaking, using Slerp will produce a more accurate path of rotation, particularly when the difference between angles is large.

However… you may want to balance this against performance, as Lerp, which can be more efficient, will produce similar results in most cases and, for small angles, will barely be noticeable at all.

Quaternion Lerp and Slerp are best used for smoothly moving an object from one rotation to another.

However, like all of the previous examples in this guide, they work by setting the rotation of the object directly, basically emulating smooth movement with calculated values.

But what if you don’t want to directly set the orientation of the object?

What if, instead of rotating an object in a measured way, you actually want to spin it round with energy?

While rotation, just like movement, can be calculated and applied exactly, it’s also possible to apply rotation to a Rigidbody as a physical force.

Here’s how it works…

How to Rotate a Rigidbody with the mouse

Physics-based rotation, which is created using angular force and drag, can be a great way to create natural object rotation.

It works by applying an amount of force, which causes an object to rotate, after which angular drag slows the object down bringing it to a stop.

This can be used for all kinds of mechanics; Spinning an inventory object by clicking and dragging the mouse, for example.

So how can you use it?

How to use the Add Torque function

The Add Torque function adds an amount of rotational force to a Rigidbody, taking a Vector 3 value to define the direction of the rotation in world space:

Rigidbody.AddTorque(Vector3 torque);

So how can you use it?

Let’s say I want to create a floating object that can be spun around by clicking and dragging the mouse, similar to how you might view and rotate an item in a game.

For this to work, I’ll need to attach a Rigidbody to the object I want to spin.

Rigidbody Settings in Unity

In this example, I’ve disabled gravity and increased the object’s angular drag.

I’ve turned off the Rigidbody’s gravity so that the object doesn’t fall out of the air, and I’ve given the object 5 units of angular drag so that it will stop fairly quickly after being rotated.

Then, to rotate the object using the mouse, all I need to do is pass in the Horizontal and Vertical axes of the mouse input into the Add Torque function whenever the mouse button is down.

Like this:

public class RotateRigidbody : MonoBehaviour
{
    public Rigidbody rb;
    public float strength = 100;
    public float rotX;
    public float rotY;
    bool rotate;
    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            rotate = true;
            rotX = Input.GetAxis("Mouse X") * strength;
            rotY = Input.GetAxis("Mouse Y") * strength;
        }
        else 
        {
            rotate = false;
        }
    }
    void FixedUpdate()
    {
        if (rotate)
        {
            rb.AddTorque(rotY, -rotX, 0);
        }
    }
}

When the mouse button is held down, I’m storing the directional movement values of the mouse in float variables and multiplying them by a strength value.

Then, in the Add Torque function, I’m applying the vertical mouse value to create rotational force around the X-Axis, while the horizontal mouse value creates force around the Y-Axis.

The end result is smooth, natural rotation, that’s applied when clicking and dragging the mouse.

Rotate Rigidbody with mouse drag Unity

The Add Torque function is great for moving Physics objects around naturally with the mouse.

You’ll notice that I’ve split the functionality of this script across both the Update and Fixed Update calls, connecting the two indirectly using variables.

This is because, while the physics-based Add Torque function should be in Fixed Update, so that the application of force is in sync with the physics steps of the game, the input checks, which are framerate dependent, need to be in Update to work properly.

Splitting the functions like this prevents the different frequencies of Update and Fixed Update from affecting each other.

How to Rotate objects in 2D

A lot of the techniques used for rotating objects in 3D in Unity also apply when rotating in 2D.

This is because, generally speaking, normal game objects in Unity are the same in both 2D and 3D, with the only difference being that the forward vector, Z, usually represents depth in 2D.

Because of this, in order to get the results you want, it helps to be mindful of which axis an object is being rotated around.

Luckily, however, most rotation functions in Unity allow you to specify which way is considered to be up, allowing you to change the orientation of the rotation if you need to.

Such as the Look At function which, in this example is set to face the player in 2D, with the forward axis set as up.

public Transform player;
void Update()
{
    transform.LookAt(player, Vector3.forward);
}

However, in some cases, when working with 2D objects, even changing the orientation of the rotation may not get you the results you want. In which case you may find it easier to simply rotate around the object’s Z-Axis using a single float value.

  • How to rotate a 2D object to look at the mouse

Which is, in fact, exactly how rotation works with 2D Rigidbody objects.

How to rotate a Rigidbody in 2D

While many objects rotate in similar ways in both 3D and 2D there are some specific differences when applying physics in 2D.

The 2D and 3D physics engines in Unity are separate. Which means that rotating a physics-based object in 2D can actually be much simpler than it is in 3D.

This is because true 2D rotation only occurs around a single axis. As a result, Rigidbody rotation is stored, and can be applied, using a single float value, which represents the amount of rotation in degrees clockwise or counter-clockwise.

Like this:

public Rigidbody2D rb;
void Update()
{
    // spins a 2D physics object clockwise at 10 degrees per second
    rb.AddTorque(10 * Time.deltaTime);
}

Now it’s your turn

Now I want to hear from you…

How have you dealt with rotation in Unity?

Have you found it easy, or has it given you constant headaches?

And what tips have you learned that you know others will find useful?

Whatever it is, let me know below by leaving a comment.

Get Game Development Tips, Straight to Your inbox

Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

My favourite time-saving Unity assets

Rewired (the best input management system)

Rewired is an input management asset that extends Unity’s default input system, the Input Manager, adding much needed improvements and support for modern devices. Put simply, it’s much more advanced than the default Input Manager and more reliable than Unity’s new Input System. When I tested both systems, I found Rewired to be surprisingly easy to use and fully featured, so I can understand why everyone loves it.

DOTween Pro (should be built into Unity)

An asset so useful, it should already be built into Unity. Except it’s not. DOTween Pro is an animation and timing tool that allows you to animate anything in Unity. You can move, fade, scale, rotate without writing Coroutines or Lerp functions.

Easy Save (there’s no reason not to use it)

Easy Save makes managing game saves and file serialization extremely easy in Unity. So much so that, for the time it would take to build a save system, vs the cost of buying Easy Save, I don’t recommend making your own save system since Easy Save already exists.

Понравилась статья? Поделить с друзьями:
  • Unitale error sans
  • Unit warning chk then reset магнитола jvc выдает ошибку
  • Unit file format error
  • Uninstallmonitor exe ошибка при запуске приложения
  • Unins000 msg is missing как исправить