[Unity] Como mover un objeto.

marod

Hola a todos.

Vamos a ver, que yo me estoy haciendo un cacao en la cabeza bonito bonito, y necesito que alguien experto en Unity me ilumine el movimiento de los objetos porque yo no se la diferencia entre:

  • Usar Rigidbody.Velocity para mover algo
  • Usar Rigidbody.MoveToPosition para mover algo
  • Usar Transform.Translate para mover algo
  • Usar Rigidbody.Addforce para mover algo

Da igual el tutorial que me vea de Unity, que cada uno lo hace de una forma diferente, al final el resultado es el mismo, que ese objeto se mueva... pero yo no entiendo las diferencias entre esas cuatro cosas, sin pensar si aún se me escapa alguna que desconozca..

Según mi criterio cada cosa sirve (Corregidme si me equivoco) para:

  • Rigidbody.velocity mueve el objeto según las direciones de los ejes del Vector dado, alterando su velocidad y haciendo que el objeto se mueva. Se usa en FixedUpdate()

  • Rigidbody.MoveToPosition mueve el objeto a una posicion dada por un Vector, es decir, lo mueve directamente a esa posición. Se usa en FixedUpdate()

  • Transform.Translate no tengo ni puta idea, pero creo pensar que se mueve en un vector dado. Se usa en Update()

  • Rigidbody.Addforce le aplica una fuerza que hace mover a un objeto con físicas en direccion donde se ha aplicado la fuerza. Se usa en FixedUpdate()

Un saludo y gracias.

YaW

Vamos a ver, primero decirte que aparte de los tutoriales que estés mirando deberías revisar de vez en cuando la documentación de Unity.

http://docs.unity3d.com/ScriptReference/Rigidbody.html
http://docs.unity3d.com/ScriptReference/Transform.html

Lo primero entender la diferencia entre el Transform y el Rigidbody. El Transform es la clase que usa Unity para designar la posición, rotación y escala de un objeto cualquiera, todos los objetos siempre tienen un transform que designa donde está posicionado ese objeto básicamente, es el componente que ves arriba del todo en el inspector cuando seleccionas cualquier objeto o prefab.

Por otro lado el Rigidbody controla el movimiento de un objeto mediante físicas. Los objetos pueden tener o no Rigidbody (según quieras que se vean afectados por físicas o no), pero el Transform siempre lo tendrán. Cuando las físicas interactuan en un objeto con Rigidbody lo que se está modificando son los valores del Transform (entre otras cosas) para representar ese movimiento lo que sea que estés haciendo con el objeto.

Ahora bien, sobre tu duda.

Rigidbody.velocity ( http://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html ). Como su propio nombre indica es la propia velocidad del objeto, NO es recomendable tocarla a mano, debería de ser solo de lectura para comprobar sus valores. La velocidad de un cuerpo físico viene determinada por el movimiento que tenga, pero no se debería de modificar para moverlo (aunque funcione no es recomendable porque no estás siguiendo las leyes de la física por decirlo de algún modo y por lo tanto puede haber resultados no reales).

Rigidbody.MovePosition ( http://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html ). Esto se usa para mover el objeto a una posición determinada, si sabes la posición de destino a la que va a parar el objeto y quieres que llegue hasta allí usando el motor de físicas y de manera interpolada (es decir, suave) este es el método a usar.

Rigidbody.AddForce ( http://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html ). Como su propio nombre indica, añade una fuerza al objeto, imaginate que tienes una canica encima de la mesa y la empujas con el dedo, estás añadiendole fuerza (con tu dedo) para moverla. El vector que se usa cómo parámetro decide la dirección.

Transform.Translate ( http://docs.unity3d.com/ScriptReference/Transform.Translate.html ). Mueve el objeto hacia el punto destino, al igual que el Rigidbody.MovePosition pero sin usar el motor de físicas, lo hace "a pelo". Si tienes un objeto que viene determinado por físicas NO debes de usar este método porque te causará problemas a la hora de calcular las físicas, deberías usar el del Rigidbody.

tl;dr: leete la documentación de Unity.

1 respuesta
marod

#2

¡WoW! Gracias por tu tiempo y tu respuesta.

Soy asiduo a leerme la documentación, no suelo programar a pelo, más que nada porque como estoy empezando, no tengo ni zorra del código que pongo. Y más que nada posteo mis dudas por aquí, para que alguien me las explique si no me quedan claras con la documentación.

La diferencia entre Transform y Rigidbody ya la tengo más que aprendida, ahora bien, respecto a tus respuestas hay algunas cosas que todavía no me han quedado muy claras. Por ejemplo:

  • Rigidbody.velocity dicen tanto tú como la documentación que no es recomendable tocarla a mano, que debería ser de lectura. Me encuentro siguiendo un tutorial ahora mismo de un Space Shooter y el movimiento de la nave lo hace tal que así:
Dentro de FixedUpdate.

float movementHorizontal = Input.GetAxis ("Horizontal");
float movementVertical = Input.GetAxis ("Vertical");

Vector3 movement = new Vector3 (movementHorizontal, movementVertical, 0.0f);
rigidBody.velocity = movement * shipSpeed;

Coge los Axis y crea un nuevo Vector3 que modifican tanto la X como la Y y luego lo asigna en cada frame a la velocidad. Estaría mal hecho ¿Verdad?

  • Lo de MovePosition me ha quedado bastante claro. Tengo dos puntos y quiero que se mueva de A a B de una forma interpolada.

  • Addforce está claro también.

  • Transform.Translate lo veo un poco tontería debido a que en en el componente Rigidbody puedes poner que sea kinematico, entonces tampoco sería afectado por las físicas. ¿No?

Siguiendo con el ejemplo del Space Shooter y pensando en tu respuesta, creo pensar que la opción más viable para mover un objeto con físicas, es MovePosition ¿no?

Muchas gracias

YaW

Lo del velocity esta mal hecho si. Lo del transform translate se usa si tu objeto no tiene físicas y simplemente quieres moverlo, si tiene físicas es mejor usar el rigidbody.

Para mover una nave pues depende, primero de todo realmente necesitas un rigid body? Porque no es obligatorio. Si lo quieres hacer todo con físicas pues depende del comportamiento de la nave y del control que quieras tener, de si es un movimiento constante, si es algo momentáneo, si quieres que sea suave, si quieres que sea directo, etc.

Siempre hay varias soluciones para todo lo que quieras hacer, al final da igual lo que uses, lo importante es que sepas porque estas usando lo que hayas elegido y no otro.

1 respuesta
marod

#4

Por eso mismo pregunto las cosas, porque quiero saber como funcionan, más que nada para aprender y saber en cada situación qué debería usar.

Estuve haciendo pruebas con el movimiento de la nave, en el tutorial te enseñan a como jugar con la rotación y hacer que cuando se mueva en un eje, la nave haga como si se balanceara hacia la dirección.

Esto debajo del codigo de movimiento.

rigidbody.rotation = Quaternion.Euler(0.0f, 0.0f, rigidbody.velocity.x * -balanceo)

Probe a mover la nave con Addforce usando este codigo:

Vector3 movement = new Vector3 (movementHorizontal, movementVertical, 0.0f);
rigidbody.Addforce(movement * speed)

Y la verdad es que el movimiento de la nave se dejaba llevar, intente toquetear el drag y el angular drag para que hubiera más resistencia a la fuerza dada, pero no acababa de quedarme realista.

Después toquetee con MovePosition con este codgio:

Vector3 movement = new Vector3 (movementHorizontal, movementVertical, 0.0f);
rigidbody.MovePosition(transform.position + movement)

Pese a que se movía bien, no me realizaba la rotación que he dicho al principio. No sé si es por culpa de mi código o es porque me faltaba algo.

Transform.Translate no lo he probado porque la nave precisa de un rigidbody.

Al final, me he decantado por seguir utilizando la velocidad del rigidbody porque es la que mejor me funciona por ahora, y pese que sea a una mala praxis según dices, no se me ocurre otra cosa...

Muchas gracias por tu respuesta YaW

Usuarios habituales

  • marod
  • YaW