Mostrando entradas con la etiqueta tutorial. Mostrar todas las entradas
Mostrando entradas con la etiqueta tutorial. Mostrar todas las entradas

9 de enero de 2012

Controles de movimiento en Unity3D (2ª parte)

Continuando con el anterior post, voy a explicar como darle un control un poco mas realista al juego. Aunque con la función transform.Translate() podemos hacer movimientos básicos que nos valdría perfectamente para un shooter o un arcade, en este parte vamos a trabajar con la función constantForce() que permite ejercer fuerzas, condicionando de esta forma el movimiento al motor de físicas de unity3d. Este tipo de movimiento es mas adecuado para vehículos, por ejemplo.

Antes de nada, tenéis que añadir al objeto que queréis que se aplican estas fuerzas el componente "constant Force" desde el menú "component">"Physics" (este componente también añade el Rigidbody, si no estaba ya asociado al objeto).

Ahora, creamos un nuevo script y declaramos unas variables para controlar movimiento y rotación.

var velocidad = 0;
var rot = 0;
var maxVel = 10000;
var minVel = 0;
var maxRot = 100;

Ahora toca introducir las funciones para detectar los Input. En este caso vamos a utilizar otra función del objeto Input.

if(Input.GetKey(KeyCode.W))vel=vel+100;
if(Input.GetKey(KeyCode.S))vel=vel-100;

Con estas lineas tendremos una sensación mas realista de "aceleración", y para no llegar a velocidades absurdas, sentencias de control:

if(velocidad>=maxVel) vel=1000;
if(velocidad<=minVel) vel=0;;
if(rot>=maxRot)rot=100;
if(rot<=minVel)rot=0;

Añadiremos ahora estas funciones. En realidad, constantForce hace referencia a las variables de la componente que hemos añadido, y para especificar que tipo de fuerza y en que dirección queremos aplicarla utilizaremos:

constantForce.relativeForce.z=vel*Time.deltaTime;

Con esto obtenemos una aceleración algo mas escalada y limitada, todo es jugar con los números para encontrar los valores que se ajusten a lo que queremos.

Para terminar, añadiremos dos lineas que nos permitirán rotar el objeto con el ratón:

transform.Rotate(0,Input.GetAxis("Mouse X") *rot*Time.deltaTime,0);
transform.Rotate(Input.GetAxis("Mouse Y") *rot*Time.deltaTime,0,0);

Las características de estos "Mouse X" y "Mouse Y" podéis encontrarla en los Inputs preestablecidos (edit>project settings>Inputs)

Pero también podemos utilizar el Input.GetKey() para rotar el objeto de la misma forma que acelera, usando la variable que nos dejamos atrás (rot) y la función constantForce.relativeTorque:

if(Input.GetKey(KeyCode.D))rot=rot+10;
if(Input.GetKey(KeyCode.A))rot=rot-10;

constantForce.relativeTorque.y=rot*Time.deltaTime;

Dejando así el ratón únicamente para el giro en el eje X.

Con solo este puñado de funciones ya podemos hacer cosas interesantes, aunque no hay que olvidar que uno de los componentes que trae Unity por defecto es un controlador para FPS mucho mas refinado, al que podemos acceder desde component>character>FPS input controller y añadiéndolo al objeto que queramos.

Para el siguiente tutorial voy a seguir perfeccionando el control, ya que aunque ha mejorado, os habréis fijado que los variables del componente constantforce, que debería aumentar, se mantienen en unos valores pequeños, y es que esta es la variable que debería de aumentar de forma gradual. Ademas, quiero añadir un variable que reduzca la aceleración del objeto conforme la velocidad aumenta, para hacerlo mas realista.

Un saludo!

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