🎮 UnityDocs

Transform: mover, rotar y escalar

El componente que tiene todo GameObject: posición, rotación y escala, además de la jerarquía padre-hijo. Cómo moverlo por código, la diferencia entre espacio local y global, y por qué la rotación usa Quaternion.

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

Qué es#

Todo GameObject tiene siempre un componente Transform (no se puede quitar). Guarda tres cosas:

  • Posición (position): dónde está, como un Vector3 (x, y, z).
  • Rotación (rotation): hacia dónde mira, como un Quaternion.
  • Escala (localScale): su tamaño.

Y además define la jerarquía: quién es hijo de quién. Es el componente que más vas a tocar por código.

La Y es la altura

En Unity, el eje Y apunta hacia arriba (no la Z). El suelo se extiende en X (derecha/izquierda) y Z (adelante/atrás). Vienes de otro motor, es el despiste número uno.

Vectores: Vector3 y Vector2#

Las posiciones y direcciones son vectores. En 3D usas Vector3, en 2D Vector2. Unity ofrece atajos muy cómodos:

C#
Vector3 a = new Vector3(1f, 2f, 0f);
Vector3 arriba = Vector3.up;        // (0, 1, 0)
Vector3 derecha = Vector3.right;    // (1, 0, 0)
Vector3 adelante = Vector3.forward; // (0, 0, 1)
Vector3 cero = Vector3.zero;        // (0, 0, 0)

float distancia = Vector3.Distance(a, cero);
Vector3 medio = Vector3.Lerp(a, cero, 0.5f);  // punto intermedio

Mover un objeto#

C#
void Update()
{
    // Fijar la posición directamente
    transform.position = new Vector3(0f, 2f, 0f);

    // Moverse en una dirección (respeta Time.deltaTime)
    transform.Translate(Vector3.up * 3f * Time.deltaTime);

    // Rotar 90 grados por segundo sobre el eje Y
    transform.Rotate(0f, 90f * Time.deltaTime, 0f);

    // Mirar hacia otro objeto
    transform.LookAt(objetivo);
}
Si tiene Rigidbody, no muevas el Transform a mano

Mover transform.position en un objeto con Rigidbody "teletransporta" el objeto y rompe la física (atraviesa paredes, colisiones raras). Para objetos físicos usa fuerzas o Rigidbody.MovePosition en FixedUpdate. Ver Update vs FixedUpdate.

Espacio local vs global#

Aquí está el concepto que confunde al principio. Cada propiedad tiene dos versiones:

Global (mundo)Local (respecto al padre)
positionlocalPosition
rotationlocalRotation
lossyScale (solo lectura)localScale
  • position: la posición en el mundo, absoluta.
  • localPosition: la posición relativa al padre. Si el objeto no tiene padre, coinciden.

Ejemplo: si una "mano" es hija de un "brazo", su localPosition es su posición respecto al brazo. Mueves el brazo y la mano lo sigue, pero su localPosition no cambia.

Jerarquía (parenting)#

C#
// Hacer que 'this' sea hijo de otro objeto
transform.SetParent(nuevoPadre);

// Recorrer los hijos
foreach (Transform hijo in transform)
    Debug.Log(hijo.name);

// Acceder al padre
Transform padre = transform.parent;

Agrupar objetos bajo un padre sirve para moverlos juntos, organizar la escena y construir objetos complejos (un coche con sus 4 ruedas como hijas).

Rotación: por qué Quaternion#

La rotación se guarda como Quaternion, no como tres ángulos. Los quaternions evitan un problema llamado gimbal lock y permiten interpolar rotaciones de forma suave. No hace falta entender sus matemáticas para usarlos:

C#
// Crear una rotación desde ángulos de Euler (los que ves en el Inspector)
transform.rotation = Quaternion.Euler(0f, 90f, 0f);

// Interpolar suavemente hacia una rotación objetivo
transform.rotation = Quaternion.Slerp(transform.rotation, objetivo.rotation, Time.deltaTime * 5f);

// Leer los ángulos como Euler (para depurar)
Vector3 angulos = transform.eulerAngles;
No sumes eulerAngles a mano

Modificar transform.eulerAngles.x += 1f puede dar saltos raros por cómo se convierten los quaternions a Euler. Para rotaciones incrementales usa transform.Rotate(...); para fijar una rotación concreta, Quaternion.Euler(...).

Rendimiento#

Cachea transform si lo usas mucho

Cada acceso a transform es una pequeña llamada a GetComponent interna. En bucles muy calientes con miles de objetos, guardarlo en un campo (private Transform _t; en Awake) ahorra algo. Para la mayoría de casos, transform directo está perfectamente bien: no optimices esto sin medir.

Errores frecuentes#

  • Confundir position (mundo) con localPosition (relativa al padre).
  • Mover el Transform de un objeto con Rigidbody en vez de usar física.
  • Sumar a eulerAngles esperando una rotación limpia.
  • Olvidar Time.deltaTime al mover en Update.

Ponte a prueba#

📝 Pon a prueba lo aprendido

Resumen#

El Transform guarda posición, rotación y escala de todo GameObject, y define la jerarquía. Muévelo con position/Translate, rótalo con Rotate/Quaternion.Euler, y ten claro cuándo usas espacio local (relativo al padre) o global. Si el objeto tiene Rigidbody, deja que lo mueva la física.

Fuentes y para profundizar