8 de enero de 2012

Controles de movimiento basico en Unity3D



Llevo unos días estudiando el engine Unity3D, que como muchos sabréis es un motor gráfico plataforma bastante potente que ha tenido un rápido crecimiento en los últimos años. A mi me resulta muy prometedor y he decidido dedicarles algunos ratillos para aprender a manejarlo.

Voy a intentar explicar algunas de las herramientas que nos ofrece unity3D para trabajar con los controles del jugador, en concreto, como podemos mover y girar objetos en el juego con unos sencillos script.

Parto de la idea de que conocéis al menos interfaz de unity3D.

  • Antes de empezar, necesitamos un terreno. Desplegamos la pestaña "Terrain" y elegimos "Create Terrain" le damos la forma que queramos y añadimos un nuevo objeto desde GameObject > Create Other y aqui elegimos un "sphere" "cube" "cylinder" o lo que queramos. Este sera el personaje que podremos mover. 
  • Busca entre sus opciones del menú Inspector y, entre las opciones del componente Rigibody, aplicarle gravedad (UseGravity)  una masa (mass) de 60, reducir el rozamiento (drag) y el rozamiento angular (AngularDrag). En el componente Box Collider aplicale un material, por ejemplo Bouncy o Metal. Desde aqui tambien podremos cambiar los valores de las variables que añadiremos mas adelante.
  • Antes de añadir los script vamos a incluir una luz direccional (GameObject > Create Other> Directional light) y la situamos para que nos ilumine bien la escena.
  • Por ultimo necesitamos una cámara que siga al objeto mientras se mueve. En Unity esto es tan sencillo como crearla a través del susodicho menú "Create Other" "Camera" y desde la "Hierarchy" añadir la cámara al objeto que creamos en el paso anterior pinchando y arrastrando.

Ahora vamos a lo que nos interesa. Voy a explicar 2 formas distintas de añadir control de movimiento a nuestro objeto. Creamos un nuevo archivo javascript desde el menú lateral "Project" y lo añadimos igual que la camara a nuestro objeto. Luego lo abrimos.

Como veréis el archivo (y todos los script que creemos en unity) empiezan por la función  update() esta función se encarga del dibujado de cada frame, así que todas las funciones que incorporemos dentro se ejecutaran mientras el juego este en ejecución y el objeto asociado estén en al escena.

La primera forma de controlar el movimiento es la forma "bruta" mediante la función transform.Translate(x,y,z)y transform.rotate(x,y,z)la primera mueve en los tres ejes y la otra rota el objeto, como ya habréis imaginado. Podríamos simplemente añadir estas funciones y ponerles un valor, pero el objeto saldría disparado sin mas en esa dirección, tenemos que condicionar estos movimientos a las teclas (inputs) y al tiempo.

Para ello vamos crear primero una variable velocidad a la que le daremos un valor 60 . Tambien crearemos una variable para la velocidad de la rotación, todo ello antes de la función update()

var velocidad=60;
var rot=30;

Ahora si, dentro del update añadimos

transform.Translate(0,0,velocidad*Time.deltaTime);
transform.Rotate(0,velocidad*Time.deltaTime,0);

La función Time.deltaTime sirve para condicionar este movimiento al tiempo, es decir, le estamos diciendo al objeto con esas lineas que se mueva en los ejes X y Z una distancia igual a "velocidad*tiempo" o mejor dicho "distancia*segundo" y rote en el eje Y al mismo ritmo.

¿y donde está el control? vamos a ello. Guardamos el script y desplegamos el menu "Edit" y elegimos Project Settings > Input. En el inspector nos aparecen todos estos Inputs que vienen por defecto. El valor "Size" indica el numero máximo que tendremos (si queréis añadir uno nuevo cambiad el valor por uno mayor) y como veréis, justo debajo tenemos los inputs "Horizontal" y "Vertical" que son para el control en los ejes X y Z. Podemos cambiarle el nombre, añadir descripciones y en "Negative button" y "Positive button" elegimos  S y A para el Negative y W y D para el Positive.

Vuelve al código, vamos a añadir la funcion Input.GetAxis() que devuelve un +1 si la tecla "w" esta pulsada y -1 esta pulsada la "s". El código nos quedaría así:

transform.Translate(0,0,Input.GetAxis("Horizontal")*vel*Time.deltaTime);

transform.Translate(0,Input.GetAxis("Vertical")*vel*Time.deltaTime,0);


Ya tenemos un movimiento, pero muy básico, la funcion transform.Translate es un poco tosca, no detecta correctamente las colisiones y en las direcciones mantiene un punto de referencia global.

Para mejorar este movimiento, en el siguiente parte utilizaremos las funciones constanceForce, que nos permiten aplicar fuerzas para un movimiento mucho mas realista

8 comentarios:

  1. Hola! Primero me presento, me llamo Oscar!

    Segundo...este tutorial es justo lo que buscaba...GENIAL!

    Empecé con el Unity hace poco y aunque ando agobiado con mis proyectos, cuando tengo hueco me pongo a investigar! Siempre me han gustado los juegos online...sus mundos, sus historias, personajes...etc.
    De hecho un amigo y yo...para cuando termine mis proyectos tenemos pensado hacer un manual para el Unity, deesde lo más básico a lo más complejo de la programación.

    Informaré por el blog de los avances del manual, por si resulta útil!

    Saludos!!!

    ResponderEliminar
  2. muuuchas gracias por la info, estarñe siguiendo tu blog de cerca me interesa bastante conocer unity

    ResponderEliminar
  3. no me sirve esta informacion

    ResponderEliminar
  4. #pragma strict

    var velocidad : float = 1.0;

    private var temp : Vector3;

    function Update () {

    temp = ( Vector3.up * Input.GetAxis("Mouse X") + Vector3.left * Input.GetAxis("Mouse Y") ) * velocidad * Time.deltaTime;
    transform.Rotate(0, temp.z, 0, Space.World);
    transform.Rotate(temp.z, 0, 0, Space.Self);

    }

    ResponderEliminar
  5. Gracias por la información, no sabía que necesitaría todos esas cosas para crear y mover mejor, lo probaré. Saludos

    ResponderEliminar
  6. Te debo la vida!!! llevo tres semanas buscando esto!

    ResponderEliminar