Menu
CoddyTech

Cuaterniones

Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 43 de 71.

Un Quaternion es el tipo de Unity para una rotación: transform.rotation es uno, y también lo es lo que devuelve Quaternion.Euler. Sus cuatro números x, y, z y w no son ángulos, y nunca necesitas establecerlos tú mismo. Lo que haces con las rotaciones es multiplicar. Una rotación multiplicada por un vector gira el 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);

La rotación va a la izquierda: Vector3.forward * transform.rotation no compila. La tercera línea gira un desplazamiento según la rotación propia del objeto, así que lamp es el punto situado 1 unidad por encima y 2 por delante del objeto, según sus propias direcciones, sea cual sea la orientación hacia la que mire.

Una rotación multiplicada por otra rotación combina ambos giros. transform.rotation * Quaternion.Euler(0, 90, 0) aplica la rotación del objeto y después un cuarto de giro alrededor de su propio eje y; si se invierte el orden, el cuarto de giro es alrededor del eje y del mundo. En un objeto vertical, ambos resultados son iguales. En un avión inclinado 30 grados, no lo son, porque su propio eje y se inclina con él:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // morro (0.87, 0.5, 0): asciende al girar
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // morro (1, 0, 0): se mantiene nivelado

Quaternion.identity representa no girar en absoluto; es el valor que has pasado a Instantiate. Multiplicar por él no cambia nada, y transform.rotation = Quaternion.identity; devuelve un objeto a su pose sin girar.

challenge icon

Desafío

Intermedio

Haz que la barra espaciadora dispare una ráfaga de tres balas que giren con el arma.

  1. Reemplaza la línea Instantiate por for (int i = -1; i <= 1; i++).
  2. Dentro, define Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);.
  3. Genera cada bala a 1 unidad de distancia en su dirección: Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.

Pulsa «Jugar», gira y dispara: las tres balas se abren en abanico, separadas por 20 grados. Después, pulsa «Comprobar».

Pruébalo tú mismo

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))
        {
            // Una bala, en línea recta hacia delante. Dispara tres: a -spread, 0 y spread grados.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}

Todas las lecciones de Física y jugabilidad

Practica por tu cuenta: Playground de Unity