Manipular el componente transform desde código es la base para mover, rotar y escalar objetos en Unity. Aquí verás cómo controlar position, rotation y scale con C#, entender la diferencia entre Start y Update, y descubrir por qué la escala solo existe en versión local.
¿Por qué Start y Update se comportan distinto al mover un objeto?
La diferencia está en el ciclo de vida de cada componente. Si asignas transform.position = new Vector3(1, 2, 3) dentro de Start, el cubo viaja a esa posición una sola vez al iniciar el juego y después puedes moverlo libremente desde el editor.
Si pones esa misma línea en Update, el cubo se queda clavado. Cada frame Unity vuelve a ejecutar la instrucción y reescribe la posición, así que aunque lo arrastres, regresa al instante [02:10].
¿Cuándo se ejecuta Update en Unity? Una vez antes de que se pinte cada frame. Puedes pensarlo como un for infinito o un while true que corre mientras el juego está activo.
¿Cómo se crea un Vector3 en C#?
El tipo de dato de la posición es Vector3, así que para asignarlo necesitas construir uno con la sintaxis new Vector3(x, y, z). El primer valor es el eje X (derecha), el segundo Y (arriba) y el tercero Z (frente).
¿Cómo rotar un objeto desde script si rotation pide un Quaternion?
Al cambiar transform.position por transform.rotation y pasarle un Vector3, Unity lanza un error: no puede convertir implícitamente un Vector3 a un Quaternion. La rotación se guarda como quaternion, una representación matemática que evita problemas como el gimbal lock [04:30].
En lugar de construir un quaternion con sus cuatro componentes, lo recomendable es usar Euler angles con el método estático Quaternion.Euler(x, y, z). Por ejemplo:
csharp
transform.rotation = Quaternion.Euler(10f, 45f, 20f);
Esto rota el cubo 10 grados en X, 45 en Y y 20 en Z.
¿Cómo mover un objeto sumando vectores cada frame?
Para trasladar el cubo en el eje Z global puedes sumar un vector pequeño a la posición actual:
csharp
transform.position += new Vector3(0f, 0f, 0.05f);
El valor es chiquito porque Update puede ejecutarse hasta 200 veces por segundo. Si pones un número grande, el cubo sale volando. La F al final del número le indica a Unity que es un float y no un double.
Un detalle importante: aunque el cubo esté rotado, esta suma lo mueve hacia el Z global, no hacia su frente, porque el vector vive en el espacio global [07:15].
¿Cómo mover y rotar en espacio local con Translate y Rotate?
Cuando quieres que el objeto avance hacia su propio frente, usa el método transform.Translate(x, y, z). Estos valores sí se interpretan en espacio local:
csharp
transform.Translate(0f, 0f, 0.05f);
Ahora, si rotas el cubo en tiempo real, su movimiento sigue la dirección a la que apunta. Para girarlo continuamente existe transform.Rotate(x, y, z):
csharp
transform.Rotate(0f, 5f, 0f);
Esto suma 5 grados en Y cada frame. Recuerda la convención: rotar en X es asentir, en Y es negar y en Z es inclinar la cabeza como un perrito confundido.
¿Cuál es la diferencia entre transform.position y transform.Translate? position asigna o suma en coordenadas globales. Translate mueve en coordenadas locales relativas a la rotación del objeto.
¿Por qué scale solo existe como localScale en Unity?
Al intentar transform.scale aparece un error: el transform no contiene esa definición. Si revisas la scripting API en la documentación oficial, solo encontrarás localScale, no una versión global [10:40].
El tamaño global es complicado de interpretar cuando un objeto está anidado dentro de otros con escalas distintas, así que Unity expone únicamente la escala local:
csharp
transform.localScale += new Vector3(0f, 0f, 0.05f);
Esto hace crecer el cubo 5% en Z cada frame, sin importar su rotación.
¿Qué diferencia hay entre position y localPosition?
La propiedad localPosition describe la ubicación del objeto dentro del espacio de su padre. Si metes un cubo dentro de un GameObject vacío escalado a 0.1 y le asignas localPosition con Z igual a 2, el cubo se moverá apenas 0.2 metros en el mundo, porque hereda la escala del padre.
En cambio, position trabaja en coordenadas globales: dos metros siempre son dos metros, sin importar el padre. Lo mismo aplica a localRotation frente a rotation.
Esta distinción es clave cuando construyes jerarquías: modificar localPosition acomoda al hijo dentro del padre, mientras que position lo posiciona en el mundo sin importar dónde esté anidado.
¿Cómo resolverías el movimiento relativo usando álgebra vectorial en lugar de Translate? Déjamelo en los comentarios.