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 levelQuaternion.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
MediumThe 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);
}
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Physics and Gameplay
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable Wall