Tips and Tricks: Unity Quaternion
Introduction
Turning and rotating are pretty common aspects in a game. Players will rotate to look at things, enemies will turn to attack the player, and sometimes things will spin around when launched through the air. Knowing how to rotate things when making games in Unity is key to creating an immersive gaming experience. Rotation is done through the use of a Unity Quaternion.
To use a Quaternion in Unity you will need to provide it with an X, Y, Z, and W value. This can be provided through shortcuts like Quaternion.identity, grabbing the Transform rotation from another GameObject, or supplying the values through Vector3 and scalar values. In this Tips and Tricks: Unity Quaternion we are going to show you exactly how to use a Quaternion, rotate objects with a Quaternion, randomize Unity Quaternions, and rotate towards a Quaternion.
Getting Started
What is Unity’s Quaternion
Quaternions represent rotation in three dimensions of space, X, Y, and Z. A major issue with representing rotation in physics simulation software, is the problem of gimbal lock. This is where an object, while rotating in all three axes, will freeze or lock on one of the rotations. The locked axis causes the rotation to appear off and breaks the immersion into your game. The use of Quaternions in Unity solves this issue because they are immune to gimbal lock.
Due to the complex nature of calculating rotations, you do not need to access or modify any of the components of a Quaternion manually. Unity gives you access to public and static methods that take simple parameters and do the difficult task of calculating the output for you.
How to Use a Unity Quaternion
You have a few options for using Quaternions. First, if you want to use the rotation of the parent object or the game world, then you can call Quaternion.identity. Quaternion.identity will essentially apply no rotation to the Quaternion or GameObject.
Next, you could construct a new Quaternion by passing in rotations for X, Y, Z and W, which is a scalar value. The new Quaternion values are used to set the rotation on each axis. You can then apply the new Quaternion to any GameObject you want to change the rotation for.
To demonstrate how Quaternions work in each example we have set up a sample scene containing two Cylinders which will manipulate through our Quaternion Rotation Script.
Unity Quaternion Rotation
First, we can bring our quaternion constructor into the Unity editor by creating a Quaternion field in our script. We have set this to private and serialized it so that the data is protected from outside scripts but still editable in the inspector.
[SerializeField] private Quaternion thatRotation;
Now inside of our update function we can assign the Quaternion set in the inspector to our cylinder’s rotation.
transform.rotation = thatRotation;
Inside the Unity editor, attach the Quaternion Rotation script to the Cylinder. Now, set the X, Y, Z, and W values in the inspector. Press play and the Cylinder will rotate the Quaternion values you assigned.
Unity Quaternion Random Rotation
We can randomize the Quaternion value being set to the rotation by creating a Boolean in the top of our Quaternion Rotation script. Again, we have set the field to private and serialized it to protect the data but still have it available to edit in the inspector.
[SerializeField] private bool isRandomRotation;
We will use the Boolean value inside of our update method. If the Boolean is true then we will call a method to set a random Quaternion rotation and if false it will use the values we assigned above.
Next, we need to create the random rotation method that executes inside of our Update method. The Update method is one of Unity’s lifecycle methods that fires every frame. We do not want our object to rotate every frame because it will be extremely hard to decipher what is going on and, to be honest, we can do better than that. Create a private field for an integer that will contain the number of seconds we want to wait before randomly rotating.
private int timePassed = 2;
Additionally, we will want to create our RandomRotation method with an if statement that checks the newly created integer to see if Time.time is greater than our set value. If the statement returns true then we will set our rotation to the built-in method Random.rotation. Random rotation returns a random Quaternion, so we do not have to do any type casting or manipulation of the value to use it. We then increment our timePassed integer by 2 so it will be ready for the next frame update.
private void RandomRotation()
{
if(Time.time>=timePassed){
transform.rotation = Random.rotation;
timePassed += 2;
}
Now, return to the editor and select the isRandomRotation box on the Cylinder and play the game. You will notice that every 2 seconds the Cylinder will rotate as expected.
Unity Quaternion RotateTowards
Similarly, we can have one of our Cylinders rotate to match the other. The first thing we need to do is get a reference to the Cylinder we want to mimic. Then, we want to use a Boolean to tell our script when we want to apply the mimicry. Create two serialized private fields to hold each of these.
[SerializeField] private GameObject rotationMimc;
[SerializeField] private bool isMimicRotation;
We will once again use the Boolean inside of our update function to check if isMimicRotation enabled before applying our MimicRotation method.
If we set the rotation directly by using transform.rotation equals the cylinder would snap to the position of the mimicked object. We instead want a smooth transition rotating towards the Quaternion of the mimicked object.
To do this we will call Quaternion.RotateTowards. The RotateTowards method uses the object’s current rotation to rotate towards the new Quaternion rotation at a set interval of degrees. Think of the degrees as a “speed” of sorts. If the value is high the rotation will be faster.
private void MimicRotation()
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,rotationMimc.transform.rotation, 1f);
}
For the final time, return to the editor and select isRandomRotation on one Cylinder and isMimicRotation on the other. The first Cylinder will rotate, and the second Cylinder will rotate smoothly to match the position of the first.
Unity Rotation Script
Here is the full Quaternion Rotation script. You can clone a full copy of this demonstration, as well as others in our Tips and Tricks 3D series, from the MonkeyKidGC GitHub page.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class QuaternionRotation : MonoBehaviour
{
[SerializeField] private GameObject rotationMimc;
[SerializeField] private bool isMimicRotation;
[SerializeField] private bool isRandomRotation;
[SerializeField] private Quaternion thatRotation;
private int timePassed = 2;
void Update()
{
if(isMimicRotation)
{
MimicRotation();
}
else if (isRandomRotation)
{
RandomRotation();
}
else
{
transform.rotation = thatRotation;
}
}
private void MimicRotation()
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,rotationMimc.transform.rotation, 1f);
}
private void RandomRotation()
{
if(Time.time>=timePassed){
transform.rotation = Random.rotation;
timePassed += 2;
}
}
}
And now you are ready to use Quaternion to rotate GameObjects in your own games mad in Unity. Thank you for stopping by. Stick around and check out more of our tutorials or posts like our piece on Tips and Tricks: Unity Transparent Material. Also, leave a comment telling us what you liked or did not like about the tutorial. Was it easy to follow along? What do you want to learn next? As always check out some of our published apps below.