Quaterniones en Unity: Fundamentos y Aplicaciones Prácticas

Un cuaternión es una estructura matemática que representa rotaciones en el espacio 3D. Se define como q = {x, y, z, w}, donde:

  • Los componentes x, y, z definen el eje de rotación.
  • El componente w codifica el ángulo de rotación θ según θ = 2·arccos(w).

Los cuaterniones evitan el bloqueo de cardán (gimbal lock) y son más eficientes que las matrices de transformación. En Unity, son el método recomendado para manejar rotaciones.

Operaciones básicas con Quaternion

// Asignar rotación inicial (identidad)
transform.rotation = Quaternion.identity;

// Convertir ángulos de Euler a cuaternión
transform.rotation = Quaternion.Euler(30f, 45f, 0f);

// Rotar alrededor de un eje específico (eje Y, 90 grados)
transform.rotation = Quaternion.AngleAxis(90f, Vector3.up);

Interpolación suave de rotaciones

Lerp (lineal) – Útil para rotaciones pequeñas. La velocidad varía: más rápida al inicio y al final.

public Quaternion rotacionMeta;

void Update() {
    float velocidad = Time.deltaTime * 5f;
    transform.rotation = Quaternion.Lerp(transform.rotation, rotacionMeta, velocidad);
}

Slerp (esférica) – Mantiane velocidad angular constante, ideal para grandes ángulos.

transform.rotation = Quaternion.Slerp(rotacionActual, rotacionMeta, Time.deltaTime * 2f);

Orientación a un objetivo

// Hacer que el eje Z del objeto apunte hacia el objetivo
Vector3 direccion = objetivo.position - transform.position;
transform.rotation = Quaternion.LookRotation(direccion, Vector3.up);

// Rotación relativa entre dos vectores
Quaternion rotacionRelativa = Quaternion.FromToRotation(transform.forward, enemigo.position - transform.position);

Combinación de rotaciones

// Añadir rotación incremental sobre el eje Y
transform.rotation *= Quaternion.Euler(0f, 10f * Time.deltaTime, 0f);

Limitación de ángulos (ejemplo: cámara)

float cabeceoActual = transform.eulerAngles.x;
float cabeceoLimitado = Mathf.Clamp(cabeceoActual, -80f, 80f);
transform.rotation = Quaternion.Euler(cabeceoLimitado, transform.eulerAngles.y, 0f);

Rotar vectores con cuaterniones

Vector3 direccionMovimiento = transform.rotation * Vector3.forward;

Aplicaciones avanzadas

Rotación física (Rigidbody)

Rigidbody rb;
float velocidadRotacion = 10f;

void FixedUpdate() {
    Quaternion deltaRot = Quaternion.Euler(0f, velocidadRotacion * Time.fixedDeltaTime, 0f);
    rb.MoveRotation(rb.rotation * deltaRot);
}

Mezcla de animaciones

Quaternion rotacionMezclada = Quaternion.Lerp(
    animator.GetBoneTransform(HumanBodyBones.Head).rotation,
    rotacionCabezaObjetivo,
    0.5f
);

Buenas prácticas y rendimiento

  • Evitar conversiones frecuentes entre Euler y cuaternión. Trabaje siempre con Quaternion.
// Incorrecto (cada frame convierte)
transform.eulerAngles += new Vector3(0, velocidad, 0);

// Correcto (usa multiplicación de cuaterniones)
transform.rotation *= Quaternion.Euler(0, velocidad, 0);
  • Cachear rotaciones que se reutilicen.
private Quaternion rotacionInicial;

void Start() {
    rotacionInicial = transform.rotation;
}
  • Depuración visual: dibujar el eje forward.
void OnDrawGizmos() {
    Gizmos.color = Color.red;
    Gizmos.DrawRay(transform.position, transform.rotation * Vector3.forward * 2f);
}

Resumen de recomendaciones

  • Use Quaternion en lugar de eulerAngles para cualquier lógica de rotación.
  • Para interpolación de grandes ángulos, use Slerp; para pequeños, Lerp.
  • Combine rotaciones mediante multiplicación de cuaterniones (tenga en cuenta el orden).
  • En bucles físicos, utilice MoveRotation en vez de asignar directamente.

Etiquetas: cuaterniones Unity rotaciones 3D Quaternion.Lerp Quaternion.Slerp

Publicado el 7-8 19:27