🎮 UnityDocs

Rotaciones 3D y Quaternions

Por qué rotar en 3D es engañoso: el gimbal lock, la diferencia entre ángulos de Euler y Quaternions, y cómo hacer las tareas reales (mirar a un objetivo, girar suave, rotar sobre un eje) con LookRotation, Slerp y RotateTowards sin volverte loco.

📄 ArtículoAvanzado✅ RevisadoUnity 6.0 LTSActualizado 2026-07-17
DificultadConceptual Código Matemáticas
Tiempo📖 Lectura 9 min · ⌨️ Práctica 20 min

Rotar en 3D no es sumar grados#

En 2D rotar es un número (grados en Z). En 3D es engañoso: rotar sobre tres ejes no es conmutativo (girar X y luego Y ≠ girar Y y luego X) y aparece el temido gimbal lock. Por eso Unity guarda las rotaciones internamente como Quaternions, no como ángulos.

El gimbal lock#

Con ángulos de Euler (X, Y, Z), en ciertas orientaciones dos ejes se alinean y pierdes un grado de libertad: la rotación "se atasca". Es un problema real que sufre cualquier cámara o nave controlada solo con Euler.

Por eso existen los Quaternions

Un Quaternion representa una orientación con cuatro componentes (x, y, z, w) sin sufrir gimbal lock y permitiendo interpolar suave entre dos rotaciones. No se entienden "mirándolos" (no son grados), pero no hace falta: usas los métodos de ayuda de Unity y ya.

La regla de oro#

No modifiques Quaternions a mano ni sumes eulerAngles

Nunca hagas transform.rotation.x += 1 (rompe el Quaternion) ni acumules en transform.eulerAngles (puede dar saltos por el gimbal lock). Usa siempre los helpers: Quaternion.Euler, LookRotation, Slerp, RotateTowards, AngleAxis o transform.Rotate.

Las tareas reales#

Fijar una rotación por grados#

C#
// Grados legibles -> Quaternion, la forma correcta de "poner" una rotación
transform.rotation = Quaternion.Euler(0f, 90f, 0f);

Girar sobre un eje cada fotograma#

C#
// Rota 90°/segundo sobre Y (independiente de FPS con deltaTime)
transform.Rotate(0f, 90f * Time.deltaTime, 0f);

Mirar hacia un objetivo#

C#
Vector3 dir = objetivo.position - transform.position;
Quaternion mirar = Quaternion.LookRotation(dir);   // orientación que "mira" a dir
transform.rotation = mirar;

Girar SUAVE hacia el objetivo#

Casi nunca quieres el giro instantáneo, sino uno progresivo:

C#
void Update()
{
    Vector3 dir = objetivo.position - transform.position;
    Quaternion objetivoRot = Quaternion.LookRotation(dir);

    // Slerp: interpola suave entre la rotación actual y la deseada
    transform.rotation = Quaternion.Slerp(transform.rotation, objetivoRot, 5f * Time.deltaTime);

    // Alternativa a velocidad constante (grados/seg): RotateTowards
    // transform.rotation = Quaternion.RotateTowards(transform.rotation, objetivoRot, 180f * Time.deltaTime);
}
Slerp vs RotateTowards

Slerp con t = velocidad * deltaTime da un giro que frena al acercarse (suave, tipo cámara). RotateTowards gira a velocidad constante en grados/segundo y no se pasa del objetivo (ideal para torretas o naves). Elige según la sensación que busques.

Combinar y deshacer rotaciones#

C#
Quaternion a = Quaternion.Euler(0, 45, 0);
Quaternion combinada = a * Quaternion.Euler(0, 0, 30); // multiplicar = aplicar una tras otra (¡el orden importa!)
Quaternion inversa = Quaternion.Inverse(a);            // deshacer una rotación

Espacio local vs mundo#

transform.rotation es la rotación en el mundo; transform.localRotation, relativa al padre. Y transform.Rotate(..., Space.Self/World) elige sobre qué ejes giras. Confundirlos es causa típica de "gira raro". Ver Transform.

Errores frecuentes#

  • Sumar a transform.eulerAngles o tocar rotation.x a mano (saltos, gimbal lock, Quaternion roto).
  • Usar LookRotation con una dirección de longitud 0 (objetivo y objeto en el mismo punto) → warning y rotación indefinida.
  • Olvidar Time.deltaTime en Rotate/Slerp (velocidad dependiente de FPS).
  • Mezclar espacio local y mundo sin querer.
  • Interpolar rotaciones con Lerp de vectores de Euler en vez de Slerp de Quaternions (da giros feos).

Ponte a prueba#

📝 Pon a prueba lo aprendido

Resumen#

Rotar en 3D es traicionero (no conmuta, hay gimbal lock), por eso Unity usa Quaternions. No los toques a mano ni sumes eulerAngles: usa los helpers. Fija con Quaternion.Euler, gira sobre un eje con transform.Rotate, mira a algo con LookRotation, y hazlo suave con Slerp (frena al llegar) o RotateTowards (velocidad constante), siempre con Time.deltaTime. Y ten claro el espacio local vs mundo del Transform.

Fuentes y para profundizar