Menu
CoddyTech

Quaternions

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 41 of 63.

A Quaternion is Unity's type for a rotation: transform.rotation is one, and so is what Quaternion.Euler returns. Its four numbers x, y, z and w are not angles, and you never need to set them yourself. What you do with rotations is multiply. A rotation times a vector turns the vector:

Vector3 a = Quaternion.Euler(0, 90, 0) * Vector3.forward;       // (1, 0, 0)
Vector3 b = Quaternion.Euler(0, 0, 45) * new Vector3(2, 0, 0);  // (1.41, 1.41, 0)
Vector3 lamp = transform.position + transform.rotation * new Vector3(0, 1, 2);

The rotation goes on the left: Vector3.forward * transform.rotation does not compile. The third line turns an offset by the object's own rotation, so lamp is the point 1 unit above and 2 in front of the object in its own directions, whichever way it faces.

A rotation times a rotation combines the two turns. transform.rotation * Quaternion.Euler(0, 90, 0) is the object's rotation followed by a quarter turn around its own y axis; with the order swapped, the quarter turn is around the world's y axis. For an upright object both give the same result. For a plane banked 30 degrees they do not, because its own y axis leans with it:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // nose (0.87, 0.5, 0): it climbs as it turns
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // nose (1, 0, 0): it stays level

Quaternion.identity is no turn at all, the one you have passed to Instantiate. Multiplying by it changes nothing, and transform.rotation = Quaternion.identity; puts an object back to its unturned pose.

challenge icon

Challenge

Medium

The gun turns with the left and right arrows, and Space fires one bullet straight ahead. Make Space fire a spread of three bullets instead: one straight ahead, one turned spread (20) degrees to the right of the gun's facing and one 20 degrees to the left. The spread must turn with the gun.

  • Each bullet faces its own direction (the ready-made Bullet script flies it along its forward).
  • Each bullet starts 1 unit from the gun's center, out along its own direction.

Press Play, turn and fire, then Check.

Try it yourself

using UnityEngine;

public class Gun : MonoBehaviour
{
    public GameObject bulletPrefab;
    public float turnSpeed = 90f;
    public float spread = 20f;

    void Update()
    {
        if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(0, turnSpeed * Time.deltaTime, 0);
        if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(0, -turnSpeed * Time.deltaTime, 0);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            // One bullet, straight ahead. Fire three: -spread, 0 and spread degrees.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Physics and Gameplay