How can I set the rotation of an object in Unity?

Guía Completa para Rotar Objetos en Unity

19/09/2008

Valoración: 4.05 (9594 votos)

Rotar un objeto en Unity puede parecer una tarea sencilla a primera vista. Sin embargo, al igual que existen múltiples formas de mover un objeto, también hay una gran variedad de métodos para rotarlo. Esto puede generar confusión al principio, ya que elegir la técnica adecuada para lograr el efecto deseado es crucial. Pero no te preocupes, en esta guía detallada te mostraremos todos los métodos para rotar un objeto en Unity, explicando cuál es el mejor para cada situación, paso a paso.

How can I set the rotation of an object in Unity?
In Unity, you can set the object's transform->forward, right, or up to orient it, but you cannot control the rotation around that axis using a second vector. Unity decides the angle for that. Is there a way to construct a transform from two vectors or to set an object's rotation based on two vectors?
Índice de Contenido

Conceptos Básicos de la Rotación en Unity

La mayoría de las formas de rotar un objeto en Unity se basan en especificar una cantidad de rotación en grados alrededor de los ejes X, Y o Z de un objeto. Si observas el componente Transform de un GameObject en el Inspector, verás su rotación representada como un valor Vector3.

De la misma manera que puedes establecer la posición de un objeto a través de su componente transform, también puedes establecer directamente su rotación. Sin embargo, hay un matiz importante.

Mientras que para la posición usarías:

Vector3 nuevaPosicion = new Vector3(0, 10, 0); transform.position = nuevaPosicion;

Para la rotación, la forma más intuitiva es usando la propiedad eulerAngles:

Vector3 nuevaRotacion = new Vector3(0, 90, 0); transform.eulerAngles = nuevaRotacion;

En este ejemplo, hemos establecido la rotación del objeto a 90 grados alrededor del eje Y. Pero, ¿por qué usamos eulerAngles y no directamente transform.rotation? La razón es fundamental para entender cómo funciona Unity internamente.

Quaternions vs. Ángulos de Euler: La Batalla Interna

Unity no utiliza vectores de tres ejes (Ángulos de Euler) para calcular y almacenar las rotaciones. En su lugar, utiliza un concepto matemático más complejo y eficiente llamado Quaternion. La propiedad transform.rotation es, de hecho, un valor Quaternion, no un Vector3.

Los Ángulos de Euler (el valor X, Y, Z que vemos en el Inspector) son una representación más legible para los humanos de esa rotación Quaternion. Son más fáciles de entender y manipular, pero tienen problemas inherentes, como el infame "Gimbal Lock" (bloqueo del cardán), que ocurre cuando dos ejes se alinean, causando la pérdida de un grado de libertad en la rotación.

Los Quaternions evitan este problema y son más eficientes computacionalmente. Por eso Unity los prefiere.

How do I change the orientation of a rotation in Unity?
Luckily, however, most rotation functions in Unity allow you to specify which way is considered to be up, allowing you to change the orientation of the rotation if you need to. Such as the Look At function which, in this example is set to face the player in 2D, with the forward axis set as up. transform.LookAt(player, Vector3.forward); }

Entonces, ¿cuál deberías usar?

  • Ángulos de Euler: Úsalos cuando necesites establecer una rotación específica en grados de forma manual o leer la rotación en un formato comprensible. La propiedad transform.eulerAngles es tu aliada para esto.
  • Quaternions: Úsalos para operaciones de rotación más complejas, cálculos y para evitar problemas como el Gimbal Lock. Aunque no los manipules directamente con frecuencia, entenderás que funciones como Quaternion.LookRotation o Quaternion.Slerp son increíblemente potentes.

Puedes convertir un ángulo de Euler a Quaternion fácilmente:

transform.rotation = Quaternion.Euler(0, 90, 0);

A continuación, una tabla comparativa para aclarar las diferencias:

CaracterísticaÁngulos de EulerQuaternions
RepresentaciónVector3 (X, Y, Z) en gradosEstructura de 4 componentes (x, y, z, w)
Facilidad de usoMuy fácil de leer y establecer manualmenteComplejo de manipular directamente
Problema principalSusceptible al Gimbal LockEvita el Gimbal Lock
Uso comúnEstablecer rotaciones absolutas en el Inspector o por códigoCálculos internos de Unity, interpolaciones, rotaciones complejas

Añadiendo Rotación con la Función `Rotate`

Establecer una rotación absoluta es útil, pero a menudo querrás añadir rotación a un objeto, es decir, rotarlo una cierta cantidad desde su orientación actual. Para esto, la función `Rotate` es perfecta.

Por ejemplo, para girar un objeto 90 grados en el eje Y cada vez que se llama a una función:

void Girar90Grados() { Vector3 rotacionAAgregar = new Vector3(0, 90, 0); transform.Rotate(rotacionAAgregar); }

Esta función es ideal para acciones como girar un personaje o abrir una puerta con un solo pulso. Si quieres crear un movimiento continuo, como hacer que un objeto gire sin parar, debes llamarla en el método `Update`.

Cómo Hacer que un Objeto Gire Continuamente

Para lograr un giro suave y constante, es crucial usar Time.deltaTime. Este valor representa el tiempo que tardó en completarse el último fotograma, lo que independiza tu lógica de la tasa de fotogramas (framerate) del juego.

public float gradosPorSegundo = 45f; void Update() { // Gira el objeto 45 grados por segundo alrededor del eje Y mundial transform.Rotate(new Vector3(0, gradosPorSegundo, 0) * Time.deltaTime, Space.World); }

Fíjate en el segundo parámetro, Space.World. Esto nos lleva a otro concepto importante.

Rotación Local vs. Rotación Mundial (World)

La rotación de un objeto puede ser relativa a dos sistemas de coordenadas:

  • Espacio Mundial (World Space): Los ejes X, Y y Z son fijos y universales en toda la escena. El eje Y siempre apunta hacia arriba.
  • Espacio Local (Local Space / Self Space): Los ejes X, Y y Z son relativos a la propia rotación del objeto. El eje Y local de un objeto inclinado no apuntará hacia el "arriba" del mundo.

Por defecto, la función `Rotate` opera en el espacio local del objeto. Si quieres girar una silla inclinada sobre su propio eje vertical, usarías el espacio local. Si quieres que orbite alrededor del eje Y del mundo, independientemente de su inclinación, usarías el espacio mundial.

Para acceder a estas rotaciones por código, tienes:

// Rotación absoluta en el espacio mundial Vector3 rotacionMundial = transform.eulerAngles; // Rotación relativa a su padre en la jerarquía Vector3 rotacionLocal = transform.localEulerAngles;

La distinción es vital cuando trabajas con objetos anidados (padres e hijos). La rotación mundial de un hijo es la suma de su rotación local más la rotación mundial de su padre.

Cambiando el Punto de Pivote para la Rotación

Un problema común, especialmente para principiantes, es que los objetos no rotan como se espera. Un ejemplo clásico es una puerta. El pivote de un cubo o un quad por defecto está en su centro. Si intentas rotar una puerta así, girará sobre su centro, lo cual es incorrecto. Las puertas giran sobre sus bisagras.

Does the x axis work on a joystick?
Yeah I want it to work exactly as you pointed out, I just did not even try to map the vertical axis on the joystick because I never found a way to match my joystick position so I ended up only using the X axis of my joystick. We can think of the x, y input on the joystick as just another vector in our game world.

La solución más sencilla y efectiva es la técnica del "pivote padre":

  1. Crea un objeto vacío (Empty GameObject). Llamémoslo "PivotePuerta".
  2. Coloca este objeto vacío exactamente donde deberían estar las bisagras de la puerta.
  3. En la jerarquía, arrastra el objeto de la puerta para que sea hijo del objeto "PivotePuerta".
  4. Ahora, en lugar de rotar la puerta directamente, rota el objeto padre "PivotePuerta". La puerta girará perfectamente alrededor de las bisagras.

Esta técnica es increíblemente versátil para controlar puntos de rotación complejos sin necesidad de modelado 3D avanzado.

Rotando Alrededor de un Punto con `RotateAround`

Una alternativa a la técnica del pivote padre es la función `RotateAround`. Esta función te permite rotar un objeto alrededor de un punto específico en el espacio mundial.

Su firma es:

transform.RotateAround(Vector3 point, Vector3 axis, float angle);
  • point: El punto en el espacio mundial alrededor del cual se rotará.
  • axis: El eje sobre el cual se realizará la rotación (ej. `Vector3.up` para el eje Y).
  • angle: La cantidad de grados a rotar.

Esto es perfecto para crear órbitas, como un planeta girando alrededor del sol, o una cámara de seguridad que gira alrededor de un pilar.

public Transform sol; public float velocidadOrbita = 20f; void Update() { // El planeta (este objeto) rota alrededor de la posición del sol transform.RotateAround(sol.position, Vector3.up, velocidadOrbita * Time.deltaTime); }

Una característica de `RotateAround` es que el objeto que rota también orientará su "adelante" (eje Z) hacia el punto de pivote. Esto es ideal para una cámara que orbita a un jugador, ya que siempre lo estará mirando.

Rotación Hacia un Objetivo

Hacer que un objeto mire hacia otro es una necesidad común en los juegos, ya sea una torreta apuntando a un enemigo o una cámara siguiendo al jugador.

`transform.LookAt`

Es la forma más simple y directa. Rota instantáneamente el objeto para que su eje Z positivo (adelante) apunte hacia la posición de un objetivo.

How do you rotate a quaternion in Unity?
See the Unity documentation on rigidbody.velocity to learn why. There are several ways to do rotate. One method is to get the existing rotation and apply the new rotation to it. In vectors, to move one vector by another vector you add them. In Quaternions, you multiply them, but note that Quaternion rotations are not associative.
public Transform objetivo; void Update() { transform.LookAt(objetivo); }

Aunque es fácil, el movimiento es instantáneo. Para un giro más suave y natural, necesitamos otras herramientas.

Rotación Suave con `Quaternion.RotateTowards`

Para una rotación continua y a una velocidad controlada, `RotateTowards` es la mejor opción. Mueve una rotación actual hacia una rotación objetivo, sin exceder una velocidad angular máxima.

public Transform objetivo; public float velocidadGiro = 90f; // Grados por segundo void Update() { // 1. Calcular la dirección hacia el objetivo Vector3 direccion = objetivo.position - transform.position; // 2. Crear la rotación que mira en esa dirección Quaternion rotacionObjetivo = Quaternion.LookRotation(direccion); // 3. Mover la rotación actual hacia la rotación objetivo transform.rotation = Quaternion.RotateTowards(transform.rotation, rotacionObjetivo, velocidadGiro * Time.deltaTime); }

Este método es robusto y perfecto para comportamientos de seguimiento que deben sentirse fluidos y no instantáneos.

Rotación en un Tiempo Fijo con `Slerp`

A veces, no quieres una velocidad constante, sino una rotación que se complete en un período de tiempo específico (por ejemplo, "gira 90 grados en exactamente 2 segundos"). Para esto, la interpolación es la clave, y en rotaciones, usamos `Slerp` (Spherical Linear Interpolation).

`Slerp` calcula un punto intermedio en la rotación entre un punto A y un punto B, basado en un valor `t` que va de 0 a 1. Generalmente se usa dentro de una Coroutine.

IEnumerator RotarEnTiempo(Quaternion rotacionFinal, float duracion) { float tiempoTranscurrido = 0f; Quaternion rotacionInicial = transform.rotation; while (tiempoTranscurrido < duracion) { tiempoTranscurrido += Time.deltaTime; float t = tiempoTranscurrido / duracion; transform.rotation = Quaternion.Slerp(rotacionInicial, rotacionFinal, t); yield return null; // Esperar al siguiente frame } transform.rotation = rotacionFinal; // Asegurar la rotación final exacta }

Rotación Basada en Físicas con `Rigidbody.AddTorque`

Todos los métodos anteriores manipulan directamente el componente Transform. Sin embargo, si tu objeto utiliza físicas (tiene un componente `Rigidbody`), deberías aplicar rotaciones a través de fuerzas para obtener resultados realistas. La función para esto es `AddTorque`.

`AddTorque` aplica un par de torsión (una fuerza rotacional) al `Rigidbody`. Esta lógica debe ir en `FixedUpdate`, que es el ciclo de actualización de físicas.

How to smooth a car rotation?
I recommend you to keep track of the last 4, 8 or 16 rotations in an array and use Quaternion.Lerp to set the rotation to the average of those 4, 8 or 16 rotations. Here is an example that smoothes between 16 rotations (which is extreme smoothing): And apply "quatABCDEFGHIJKLMNOP" to the rotation of your car.
public Rigidbody rb; public float fuerzaGiro = 10f; void FixedUpdate() { float entradaHorizontal = Input.GetAxis("Horizontal"); rb.AddTorque(transform.up * fuerzaGiro * entradaHorizontal); }

Este código aplicaría una torsión alrededor del eje Y local del objeto basado en la entrada del jugador, haciendo que gire. El `Rigidbody` también tiene una propiedad `angularDrag` (resistencia angular) que puedes ajustar para que el objeto deje de girar por sí solo con el tiempo.

Rotación en 2D

En un proyecto 2D, la rotación es generalmente más simple, ya que casi siempre ocurre en un solo eje: el eje Z. El componente `Rigidbody2D` tiene una función análoga a `AddTorque`, pero funciona con un simple valor `float`.

public Rigidbody2D rb2d; public float torque = 5f; void FixedUpdate() { // Aplica un torque que causa una rotación en sentido antihorario rb2d.AddTorque(torque); }

Para manipular la rotación directamente, puedes usar `transform.eulerAngles` o `transform.Rotate` como en 3D, pero asegurándote de modificar solo el componente Z.

Preguntas Frecuentes (FAQ)

¿Cómo puedo rotar un objeto con un joystick?

Es muy similar a rotar con el teclado. Debes leer los ejes del joystick usando el Input Manager de Unity (`Input.GetAxis("HorizontalJoystick")` y `Input.GetAxis("VerticalJoystick")`). Luego, puedes usar estos valores para construir un vector de dirección y usar `Quaternion.LookRotation` para que tu objeto mire en esa dirección. Para un movimiento suave, puedes usar `Quaternion.RotateTowards` o `Slerp` para transicionar a la nueva rotación.

Mi coche 2D no rota suavemente, ¿cómo lo arreglo?

La rotación brusca suele ocurrir cuando estableces la rotación directamente a un valor final en cada fotograma. Para suavizarla, necesitas interpolar. Si estás usando físicas (`Rigidbody2D`), ajusta los valores de `angularDrag` y la fuerza de `AddTorque` para encontrar un equilibrio que se sienta bien. Si no usas físicas, usa `Quaternion.RotateTowards` o `Slerp` para mover gradualmente la rotación actual del coche hacia la rotación deseada (determinada por la entrada del joystick o teclado).

¿Por qué los valores de rotación en el Inspector cambian solos o son extraños?

Esto sucede porque el Inspector muestra los Ángulos de Euler, que son una conversión del Quaternion interno. Una misma rotación Quaternion puede ser representada por múltiples combinaciones de Ángulos de Euler. Por ejemplo, una rotación en Y de 270 grados es lo mismo que -90 grados. Unity puede elegir la representación que considere más eficiente, lo que puede parecer confuso en el Inspector. Es por eso que no es recomendable leer, modificar y luego reasignar `transform.eulerAngles` en el mismo fotograma, ya que puedes obtener resultados inesperados. En su lugar, almacena la rotación que deseas en una variable local.

Si quieres conocer otros artículos parecidos a Guía Completa para Rotar Objetos en Unity puedes visitar la categoría Juegos.

Subir