viernes, 26 de diciembre de 2014

Futuros Creadores: Inaugurando una nueva sección

Para terminar el año, y antes de hacer un resumen de lo más destacado en 2014 de este Blog (Cosa que viene muy bien para repasar todos los post habituales que me traigo entre manos), vamos a inaugurar una nueva sección llamada “Futuros Creadores” que van a protagonizar precisamente personas que están ahora aprendiendo todo lo necesario para convertirse en el futuro del desarrollo de videojuegos en España.

Hace tiempo que sueño con ser desarrollador de videojuegos y por tanto, he tenido que enfrentarme a ver como no existían unos estudios relacionados con el tema en mi país cuando llegó el momento de elegir mi camino. Con los años empezaron a aparecer Cursos, Masters e incluso carreras no oficiales, pero entonces me encontré con el problema de que no podía pagarlos. Hoy en día, por suerte, aparecen más y más Universidades y estudios, con precios y posibilidades muy variadas que dan la posibilidad a los nuevos futuros creadores de formarse con profesores que han sido y siguen siendo auténticos profesionales de la industria, aprendiendo todo lo necesario para llegar a dedicarse a aquello que soñaron o que simplemente les gusta . Por esto, en esta sección voy a tratar de entrevistar a esos estudiantes que en el futuro llegarán a ser grandes desarrolladores de videojuegos, tratando de cubrir todas las posibilidades que hay en España para estudiar esto que a muchos nos apasiona.

Quiero que nos cuenten cosas sobre ellos y también sobre los sitios que eligieron para formarse, así como que esperan conseguir dentro de unos años. Además, si seguimos en contacto, tal vez también puedan decirme que tal les fue el curso, para que sirva así de guía a aquellos que empiezan o quieran reorientar su carrera y necesitan conocer que opciones existen.

La nueva sección empezará a pronto, a principios del 2015, con una entrevista a un estudiante del Master de Videojuegos de la UPF (Universitat Pompeu Fabra), y con ella espero despertar un poco la curiosidad a much@s, informar a tod@s l@s que pueda y de paso, resolverme muchas dudas a mí mismo.

Al final me va a gustar esto de las entrevistas.

martes, 23 de diciembre de 2014

Aprendiendo videojuegos con la historia de las consolas: Atari (Continuación)

En el post anterior nos quedamos con nuestro tirador de penaltis apuntando mediante una flecha. Sin embargo, esta no tenía limitaciones a la hora de girar por lo que tendremos que editar el script PlayerControl para añadirle los límites que deseamos.

Dentro de la funcion RotateArrow (Es decir entre las dos llaves que indican su principio y fin) incluiremos unos condicionales con llamadas a una función que impide que la flecha continúe rotando.
// Limite de rotacion hacia la izquierda
// la flecha se para al entrar entre un rango de angulos dentro de la circunferencia

if(thisTransform.eulerAngles.z >= 40 && thisTransform.eulerAngles.z < 50)
{
 BlockRotation(-1);
}
  
// Limite de rotacion hacia la derecha
  
if(thisTransform.eulerAngles.z > 310 && thisTransform.eulerAngles.z <= 320)
{
 BlockRotation(1);
}
Como vemos tenemos que si el ángulo de rotación en el eje Z del Pivot Point en este caso, esta entre 40 y 50 grados, vamos a llamar a la función que limita dicha rotación pasándole un -1 para indicar que estamos girando a la izquierda y si por el contrario el ya citado ángulo esta entre 310 y 320 grados llamaremos a la función indicando un 1 positivo para decirle que la rotación está siendo a la derecha. De esta forma tendremos la función BlockRotation como sigue:

/*-----------------------------------------------------------------------
*  - BlockRotation() -
*
*  Impide a la flecha de apuntar superar el limite de rotacion a la derecha
* ----------------------------------------------------------------------*/

   
void BlockRotation(int rotationDir)
{
    if(rotationDir == -1)
        thisTransform.eulerAngles = new Vector3(0,0,40);
    else
        thisTransform.eulerAngles = new Vector3(0,0,320);
}


Recibe un entero que indica la dirección en la que está rotando la flecha para apuntar (-1 a la izquierda o 1 a la derecha). Dependiendo de hacia donde sea el giro, va a bloquear en un punto, no dejando pasar de 40 grados a la izquierda o 320 a la derecha. Ángulos que han sido elegidos para permitir tirar al palo o fuera de portería si hacemos un mal cálculo, pero para impedir que la flecha se coloque sobre el gráfico del jugador.

¿Qué hace la sintaxis eulerAngles? Como podemos ver es una función dentro de la clase Transform encargada de manejar la rotación a través de las componentes x,y,z de este en grados. Si queremos cambiar sus valores tendremos que pasarle un vector3 (de tres componentes) como vemos en la función BlockRotation.

Llega el momento por fin de manejar el tiro a puerta, para lo que vamos a necesitar añadir un par de componentes a nuestro balón. El primero será un Box Collider 2D al que aplicaremos un Physic Material para que pueda chocar con otros objetos en la escena y rebotar. El segundo será un Rigidbody 2D que nos permitirá aplicar fuerzas para lanzar la pelota a puerta.

Para añadir tanto el Box Collider 2D como el RigidBody 2D, seleccionaremos nuestro objeto Ball (el balón) e iremos al menú Component/Physics2D/Box Collider 2D primero y luego a Component/Physics2D/RigidBody 2D (bueno, el orden da igual). Una vez aplicados al objeto podremos ver sus propiedades en el inspector mientras lo tengamos seleccionado.


El Box Collider 2D rodea el gráfico con un cuadrado que ayuda a detectar las colisiones a Unity y es el más sencillo de configurar de los dos nuevos componentes. Para empezar tenemos que saber que el tamaño de nuestro balón es demasiado pequeño y daría problemas de cálculo al motor, por lo que vamos a usar un Size o tamaño de 0.05 en X y 0.05 en Y que es el mínimo recomendado para evitar problemas y con él que no vamos a notar diferencia. Además hay que destacar que, aunque para un balón puede ser normalmente más apto un Circle Collider 2D (Con forma de círculo) como estamos manejando pixel art, el Box Collider 2D cumplirá muy bien su función y consume algunos recursos menos al tratar las colisiones.


Con lo hecho hasta ahora aun no hemos terminado con nuestro Box Collider 2D, y es que queremos que la pelota tenga un poco de rebote y no simplemente colisione y frene en seco. Para conseguir esto vamos a crear un Physic 2D Material haciendo clic con el botón derecho en la ventana Project y seleccionando Create/Physics 2D material, al cual vamos a llamar Bounce Material y a guardarlo en una carpeta llamada Physics Materials para tenerlo todo ordenado.

El material que acabamos de crear va a tener una Fricción (Friction) de 1 y un Bounciness (o rebote) de 0.1. Con esto hacemos que haya un cierto rebote pero que la fricción pare relativamente pronto la pelota y así no salga disparada fuera de la pantalla o haga alguna cosa rara. Vamos que queremos imitar un poco de realismo pero tampoco un comportamiento físico perfecto.

Como ya tenemos nuestro Bounce Material lo vamos a arrastrar a la ranura Material del Box Collider 2D de nuestro balón, con lo que este comportamiento se aplicará a la reacción que tendrá nuestro objeto ante una colisión. (¡El balón rebotará contra la portería y el portero!)



¿Cómo configuramos ahora el Rigidbody 2D de nuestro objeto Ball? Para empezar usaremos una masa (Mass) muy pequeña, para que el golpe no sea capaz de desplazar a nuestro portero y meterlo dentro de la portería. Aplicaremos un Linear Drag de 1.2 para ayudar al frenado de la pelota y un Angular Drag de 0, porque no queremos que haya rotación en nuestro gráfico durante su movimiento (básicamente por que es pixel art y la rotación no le va a sentar bien gráficamente hablando). Marcaremos la casilla Fixed Angle para remarcar el que no queremos que haya rotación y elegiremos en Interpolate el valor Extrapolate, en Sleeping Mode Start Awake y en Collision Detection el tipo Continuous, que aunque tiene mayor coste de recursos para realizar cálculos nos va a dar mejor resultado (y nuestro juego es pequeñito y podemos permitírnoslo).

¿Qué significa cada cosa? Interpolate es el metodo de cálculo para la interpolación, es decir, algo así como una previsión de donde estará nuestra pelota en el siguiente fotograma(Extrapolate) para que al motor no se le escape que vaya a haber contacto con otro GameObject. Por otro lado Collision Detection indica el método usado para calcular la colisión (Discrete o Continuous) que indica el tiempo que Unity va a estar "atento" para calcular choques con otros objetos (Explicaciones un poco "por encima". Para más info o más precisa, documentación de Unity).

¡Y hemos terminado de configurar nuestro balón! Sin embargo para que funcione tendremos que añadir la posibilidad de ejecutar un disparo desde el script PlayerControl. Es, por tanto, momento para volver a editarlo. (Ya estabais impacientes por picar más código, ¿eh?)

Tras abrir el Script lo primero que haremos será añadir una referencia pública al transform del balón (Ball), con esto seremos capaces de acceder a dicho transform desde el Script PlayerControl. Añadimos por tanto, la siguiente línea debajo de la variable rotationSpeed que es la única pública que teníamos hasta ahora:

public Transform ballTransform;                // Referencia al transform del balon

Al hacer esto, volver a Unity y seleccionar nuestro Pivot Point (Que es el que contiene el script PlayerControl y el encargado de rotar nuestra flecha para apuntar) vemos que se ha añadido una nueva casilla que espera un Transform. Arrastraremos hasta allí el Game Object Ball (El balón de futbol) indicando así al motor que es a de ese objeto del que necesitamos acceder a su componente transform.

Podemos por fin añadir el siguiente código dentro de una función especial llamada FixedUpdate()

void FixedUpdate()
{
    // Si pulsamos la tecla espacio
    if(Input.GetKeyDown(KeyCode.Space))
    {
        Shoot();
    }
}


Aquí de forma similar a como ya hicimos anteriormente llamaremos a una función Shoot() que crearemos después, cuando se reciba el evento de pulsar la tecla Espacio. Esta vez estamos usando Input.GetKeyDown, que detecta una pulsación de tecla (presionar hacia abajo) pero no que la tecla se quede pulsada (Que sería GeKey) o se suelte (GetKeyUp). Respecto al KeyCode, este toma las teclas a partir de un nombre clave que en este caso es Space para el espacio. Pero vamos a ver también como sería la función Shoot()

/*-----------------------------------------------------------------------
*  - Shoot() -
*
*  Funcion encargada de las acciones para tirar a porteria
* ----------------------------------------------------------------------*/

   
void Shoot()
{
    // añadimos fuerza al balon
    ballTransform.rigidbody2D.AddForce( thisTransform.up * Time.deltaTime * 800 );
}


Esta función añadirá al rigidbody 2D del transform de nuestro balón (mediante AddForce) una fuerza hacia "arriba" haciendo que salga disparado hacia portería en la dirección indicada por la flecha. Para saber qué dirección debe seguir, tomamos la del Pivot Point (thisTransform) y lo multiplicamos por una fuerza de 800 que es aceptable y por Time.deltaTime, para ayudar a que su desplazamiento sea similar aunque varíe el rendimiento del dispositivo. Tenemos por fin una explicación de por qué llamamos a la función Shoot anteriormente desde FixedUpdate y no desde Update. El motivo es que Unity tiene FixedUpdate como recomendación para llamadas a procesos que involucren físicas, como es el caso de añadir fuerza al RigidBody2D en la función Shoot(). Su utilidad es la misma que Update pero se ejecuta a intervalos constantes y no depende del tiempo que se tarde en cargar el fotograma como pasaba con Update. Esto lo hace más apto para cálculos que tengan que ser más precisos. (Como siempre en la documentación de Unity encontrareis una mejor y más acertada explicación de la mano de sus creadores).


Si ejecutamos ahora el juego y probamos a pulsar la tecla espacio nos encontraremos tres problemas. El primero es que el balón sale disparado y se pierde por el fondo de la pantalla atravesando todos los objetos. El segundo es que si pulsamos repetidamente la tecla espacio añadimos más fuerza y mandamos la pelota muy lejos (Es posible que no os deis cuenta de esto porque la pelota ya se habrá salido de la pantalla). Por último, está el tercer problema que es que la pelota no vuelve a su sitio para que podamos volver a tirar a puerta, por lo que hay que parar el juego y volver a ejecutarlo si queremos tirar otra vez. Vamos a trabajar por solucionarlos todos, pero como no nos dará tiempo a algunos en este post, empezaremos por el más simple. Que la pelota choque con la portería.

Para añadir una colisión con la portería vamos a añadir un componente Collider a la misma, pero como esta vez no nos vale una caja, porque la pelota tiene que meterse dentro y eso lo impediría, usaremos un Poligon Collider 2D. Este en un principio puede parecer la misma caja que el Box Collider, pero si en la ventana Scene vamos a esta caja que rodea el gráfico de nuestra portería y pulsamos Mayusculas mientras hacemos clic y luego arrastramos sobre una linea, añadiremos un punto que podremos colocar. Así, daremos forma a los palos de nuestra meta para permitir colisión con ellos (Para borrar usamos control y hacemos clic en alguno de los puntos). Una vez lista la forma si ejecutamos el juego, podemos ver como la pelota se detiene al tocar alguno de los palos.



Y aquí nos vamos a quedar por ahora. A ver si en próximos post podemos hacer que nuestro muñequito de madera se haga alguna paradita y podamos volver a intentar meter gol después de tirar sin tener que detener el juego. Hasta la próxima.

lunes, 22 de diciembre de 2014

Aprendiendo de los maestros

Dedicar de vez en cuando algo de nuestro tiempo a copiar a los profesionales puede enseñarnos como resolvieron muchos problemas que nos encontraremos a lo largo de nuestra vida como artistas, especialmente cuando estamos empezando y necesitamos mejorar. Copiar no es malo si lo hacemos para aprender (Pero por supuesto no se debe hacer para ganar dinero con algo que no es nuestro). Resulta bastante útil, por ejemplo observar el modelado de personajes, escenarios, vehículos u objetos de profesionales de la industria del videojuego, especialmente si tenemos acceso a versiones Wireframe donde vemos como ordenó el artista los polígonos para dar la forma deseada.

En mi caso suelo practicar a veces observando detenidamente ilustraciones de otros artistas como pueden ser dibujantes de Anime y tratando de imitar su trabajo con las técnicas que están a mi alcance. En el caso de la imagen 2D que acompaña el post me encantaría decir a que serie y artista pertenece, pero no ha habido manera de encontrarlo. (Si alguien lo sabe y es tan amable de guiarme corregiré esta injusta situación). Con esto puedo fijarme en la forma de colorear, sombrear o iluminar una escena o dibujo y tomar nota como inspiración para futuros trabajos.


En el caso del modelado 3D, tener a veces acceso a arte conceptual de profesionales que ya han trabajado en videojuegos nos puede ayudar a entender cómo será nuestro trabajo cuando tengamos que convertir en un objeto 3D esas ilustraciones. Así lo hago en ocasiones y lo he hecho esta vez con un diseño de tren descartado para un juego de Zelda que he sacado del libro Hyrule Historia. (De momento solo publico el modelado, el mapeado y la textura quedan pendientes).


Recomiendo por tanto la copia para el aprendizaje (y también lo hacen en el Anime Shiro Bako de la que ya hablé en un post anterior), por supuesto respetando siempre los derechos de autor y tomando el ejercicio como un análisis minucioso de las técnicas, las formas y la sabiduría de personas que nos llevan años de ventaja en su experiencia con el mundillo.

La propia figura del asistente que aprende del profesional dibujante de comic para el que trabaja y acaba recibiendo su influencia, o del novato que empieza en un estudio y absorbe los conocimientos de los compañeros más veteranos que le rodean, nos da una pista de lo beneficioso que puede ser el estudio y aprendizaje de los maestros. Y por cierto que, aunque en este post me he centrado en ilustradores y modeladores, esto también es aplicable a todos los demás roles dentro del desarrollo. Programadores copiando código (pero entendiéndolo), animadores imitando a sus héroes de la animación, músicos tocando las canciones de su grupo favorito…

miércoles, 17 de diciembre de 2014

Aprendiendo a hacer juegos con la historia de las consolas: Atari

Bienvenidos de nuevo a nuestra aventura de imitar un juego de Atari 2600 usando Unity. En el post anterior di algunas explicaciones para cargar los gráficos necesarios para nuestra primera escena de un juego muy sencillo de lanzamiento de penaltis y sugerí a los lectores de esta sección que trataran de crear su propio pixel art. Como ya habéis tenido algún tiempo para “cacharrear” e intentarlo vosotros mismos hoy voy a traer la solución para los\las mas perezosos\as. En este enlace se puede descargar los primeros sprites necesarios para montar nuestra escena principal de juego en Unity.

Como vemos disponemos de una series de archivos png que van a hacer las funciones de campo de futbol (campo.png), balón (balon.png), flecha que usaremos para apuntar (flecha.png), portería (porteria.png), un lanzador de penaltis en dos estados (jugador.png y jugador_shoot.png) y para terminar un portero de madera que se va a mover de lado a lado para que el entrenamiento sea sencillo pero un poco más entretenido (portero_madera.png)

Ya vimos en el post anterior como introducir los gráficos ya mencionados en Unity, pero para dejarlo más claro lo vemos en la animación. Hay que arrastrar el archivo de nuestro navegador del sistema operativo a la ventana Project.


Una vez con todo cargado en nuestra escena lo configuraremos y colocaremos cada cosa en su sitio, primero arrastrando de la ventana Project a Hierarchy para poner los objetos en la escena y después ajustando su posición moviéndolos con el ratón en la ventana Scene o introduciendo números en los transform de cada objeto a través del Inspector.

Como guía puedo decir que tengo la cámara configurada en ortográfico con un tamaño de 0.8 y los objetos en las siguientes posiciones: campo (0, 0, 0), balón (0,-0.47,-0.1), jugador (0, -0.49, -0.2), portería (0,0.49, -0.03), flecha (0, 0.1, -0.5). Debemos saber que cuando manejamos el eje Z en el modo 2D de Unity podemos conseguir que unos objetos estén por delante de otros. Por eso estamos usando valores negativos, para colocar objetos delante del campo que está en Z=0. También hay que mencionar que vamos a reducir un poco el tamaño de la flecha introduciendo en sus casillas Scale correspondientes a X e Y el valor 0.95 sin preocuparnos de la Z, ya que al ser un objeto en dos dimensiones, por lo que no tiene profundidad y no nos importa. (El único motivo por el que hago esto es para que aprendáis a re-escalar desde el transform, pero si tenemos los objetos desde el principio a su tamaño original será mejor.


Ahora empezamos a ver cosas nuevas después del repaso. Además traigo buenas noticias. Empezaremos a programar un script en C# para que nuestro personajillo de uniforme azul pueda disparar a puerta.

Para empezar hay un objeto que necesitamos colocar de un modo especial, la flecha. Crearemos un objeto vacio mediante Create/Empty Object y lo arrastraremos sobre el jugador. Después arrastraremos la flecha sobre el objeto vacio (al que debemos dar un nombre, por ejemplo en mi caso lo he llamado Pivot Point). De este modo el objeto Pivot Point es hijo del jugador y la flecha es hija de Pivot Point, creándose así una relación de herencia que hace que si movemos al jugador sus hijos se muevan con él.




Crearemos por fin un Script en C# al que yo he llamado PlayerControl. (Es importante saber que se distingue entre mayúsculas y minúsculas y que el nombre de archivo del Script debe coincidir con el nombre de la clase principal, aunque Unity ya se encarga de nombrarlo todo). Lo arrastraremos sobre el objeto Pivot Point de la escena y dentro de él vamos a introducir el siguiente código (observad que hay una parte que escribe Unity al crear cualquier Script).



using UnityEngine;
using System.Collections;

public class PlayerControl : MonoBehaviour 
{

    // Public variables
 
    public float rotationSpeed; 
        // velocidad de rotacion para apuntar (90 esta bien)
 
    // Private variables

   private Transform thisTransform;  // Referencia al transform 
    private float horAxis;    // Eje horizontal 
 
    // Use this for initialization
    void Start () 
    {
        // Inicializamos las referencias a los transform
        thisTransform = transform;
    }
 
    // Update is called once per frame
    void Update () 
    {
       horAxis = Input.GetAxis("Horizontal");
  
    RotateArrow();
    }

    /*-----------------------------------------------------
     *  - RotateArrow() -
     * 
     *  Rota la flecha para apuntar desde un punto de pivote
     *  (En dicho punto esta este Script)
     * ---------------------------------------------------*/
 
    void RotateArrow()
    {

       thisTransform.Rotate(0, 0, - horAxis * rotationSpeed * Time.deltaTime); 
        // rotamos la flecha
} 

Con este código inicial vamos a hacer que nuestro tirador a portería pueda apuntar. Con flecha derecha rotaremos la flecha a la derecha y con flecha izquierda lo haremos a la izquierda. Pero, ¿Por qué?

Tenemos una variable pública llamada rotationSpeed de tipo float (public float rotationSpeed) Al ser pública Unity la va a mostrar en el Inspector si seleccionamos el objeto jugador, por lo que podremos darle un valor desde allí y testear sus efectos en tiempo real para hacer ajustes. Eso sí, hay que saber que el juego debe estar parado para que los ajustes sean permanentes. Si estamos ejecutándolo y cambiamos algún valor, recuperará los números anteriores que tenía cuando volvamos a pulsar el stop.

Las siguientes variables son privadas, es decir no se verán desde el Inspector ni serán accesibles desde otro Script o clase. Con private Transform thisTransform estamos declarando un objeto de tipo Transform en el que guardaremos una referencia al componente transform del objeto que contiene el Script (En este caso Pivot Point). Hacemos esto para optimizar el rendimiento y que Unity no tenga que buscarlo cada vez que lo vamos a utilizar gracias a que ya lo tenemos referenciado.

Después tenemos private float horAxis, que es una declaración de una variable en el que vamos a recoger el eje horizontal que Unity tiene asociado a una serie de teclas. Para saber cuáles son, solo tendremos que ir a Edit/Project Settings/Input. Allí, en el Inspector, vemos que aparecen los axes y en el horizontal el botón izquierdo lo identifica como negativo y el derecho como positivo. (Las teclas son los cursores y las teclas alternativas la A y la D). Con esto cuando pulsemos la tecla izquierda (aunque aún tenemos que hacer algo de trabajo) la variable horAxis tomará un valor negativo y cuando pulsemos la derecha, lo tomará positivo.


Llegamos ahora a la función Start(). Una función que Unity tiene predefinida y que usa normalmente para inicializar variables. Esta se va a ejecutar una sola vez al iniciarse la escena. Así dentro de ella guardamos la referencia del transform del objeto en thisTransform como ya habíamos dicho anteriormente, escribiendo la sencilla orden thisTransform = transform.

En la función siguiente, es decir Update(), vemos que tenemos otra que está predefinida y que Unity ejecuta cada fotograma. Es decir, es como un bucle principal de juego que se repetirá hasta que lo paremos. Dentro usaremos la sentencia horAxis = Input.GetAxis("Horizontal"). Para guardar el valor de las teclas del Axis horizontal en la variable horAxis. (recordemos, negativo izquierda, positivo derecha). Por último llamaremos a la función RotateArrow().

La función RotateArrow la creamos nosotros después y la usamos básicamente para tenerlo todo ordenadito. Esta función se va a ocupar de rotar la flecha al pulsar las teclas. Así, dentro encontramos un código thisTransform.Rotate(0, 0, - horAxis * rotationSpeed * Time.deltaTime) que se encarga de dejar la X e Y fijas de nuestro transform, mientras rota mediante la función Rotate a una velocidad rotationSpeed, el eje Z. Como se multiplica por el horAxis será negativo cuando pulsemos la izquierda y positivo cuando pulsemos la derecha. Pero la rotación sale al revés, por lo que pondremos un menos delante de horAxis. Respecto a Time.deltaTime,a grosso modo es una función de Unity que se encarga de mantener una velocidad constante sin importar el rendimiento del dispositivo en el que estemos ejecutando el juego. Si queréis saber más os recomiendo bucear en la documentación de Unity y tratar de entenderlo, aunque puede que lo explique más adelante porque soy un buen chico pero tengo poco espacio para escribir. :P

El fallo de este código es que permite rotar indefinidamente nuestra flecha. (En el inspector no olvidéis dar un valor a rotationSpeed o no rotará) Nosotros queremos añadirle un bloqueo para que solo pueda girar dentro de un rango, pero como se ha hecho muy largo el post lo vamos a dejar aquí por hoy. Así además, no se puede quejar nadie de que le hago copiar mucho código.


La historia de las consolas es larga y esto nos va a llevar bastante tiempo, así que tener paciencia (y tener paciencia conmigo porque es mi primer tutorial en detalle y estoy aprendiendo). Ánimo y a seguir aprendiendo. Hasta el próximo

domingo, 14 de diciembre de 2014

Aprendiendo a hacer juegos con la historia de las consolas: Atari - Preparando Unity

Unity generalmente se abre con un proyecto anterior o uno de ejemplo, a partir de aquí hay que crear un proyecto nuevo usando el menú File/New Project…


Se abre una ventana donde debemos elegir una carpeta para nuestro nuevo proyecto y luego en el desplegable marcar la opción 2D, ya que nuestro juego va a ser 2D y nos vamos a beneficiar del nuevo sistema de Unity para este tipo de proyectos.


La zona donde aparecen checkboxes para importar packages no nos interesa ya que no usaremos ninguno de los packages que trae Unity y vamos a hacer todo nosotros

Si quisiéramos abrir un proyecto en vez de crear uno nuevo nos iríamos, en la misma ventana llamada Project Wizard, a la pestaña de Open Project, donde elegiríamos uno de los proyectos anteriormente abiertos o pulsaríamos sobre el botón Open Other, para buscar entre nuestras carpetas un proyecto que no aparezca en la lista por no haber sido cargado en otra ocasión.


Configuraremos ahora el tamaño de pantalla eligiendo, en el menú que hay justo debajo de la pestaña Game, el icono del “+” que nos permite añadir una resolución personalizada. Pondremos aquí 190x160 que es el tamaño que buscamos (Aunque se verá muy pequeño y tendremos que verlo ampliado o a pantalla completa para nuestras partidas). En Label escribimos lo que queramos para identificar nuestra resolución personalizada (por ejemplo yo he puesto Atari2600) y pulsamos OK para elegirla como resolución del proyecto actual.


Llega el momento de insertar los recursos necesarios para nuestro juego. Desde nuestro navegador del sistema operativo arrastramos los archivos a la ventana Project de Unity. Aquí, para tenerlos ordenados crearemos carpetas. Por ejemplo una para las animaciones, otra para los Scripts en C#, otra para los Sprites, otra para las escenas, etc. Para hacer esto pulsamos con el botón derecho del ratón en la ventana de Project y elegimos Create/Folder.



Como vemos este también será el método habitual de crear nuevos recursos en Unity, ya que en este desplegable encontramos la posibilidad de crear Scripts en los diferentes lenguajes, Shaders, Prefabs (Que veremos en su momento lo que son), Materiales y un largo etc.

Una vez insertados todos los Sprites que vamos a usar tenemos que configurarlos. Para empezar, debemos saber que Unity normalmente detecta automáticamente el tipo de de recurso que hemos introducido en el entorno, pero no es infalible, así que deberíamos revisarlo. En este caso elegiremos el tipo Sprite(2D\uGUI) en Texture Type. Después, como son Sprites simples y no mapas de Sprites (Que manejaremos en otra ocasión), elegiremos Simple en vez de Multiple; nos fijaremos en que el Filter Mode sea Point, para que no nos suavice los bordes de nuestro amado arte creado en Pixel Art y usaremos el tipo Compressed (porque no necesitamos muchos colores).




Hay una parte que hay que explicar más para este caso y es Max Size. En esta parte elegimos el tamaño máximo de la textura, como por ejemplo 1024. Unity se maneja mucho mejor con texturas cuadradas, pero para este caso estamos usando Sprites y lo vamos a pasar un poco por alto, pero además, nuestros gráficos son muy pequeños. Cuando Unity los guarde no necesitamos que genere una textura de 1024x1024 de un Sprite que mide 20x20, por lo que elegiremos un tamaño máximo que se adapte a nuestro tamaño, que en este caso sería el mínimo de 32x32. Con esto, nuestro querido motor generará texturas de ese tamaño como máximo para nuestro arte y estaremos ahorrando recursos. Al terminar pulsamos Apply para aplicar los cambios al gráfico elegido. Debemos saber que no tenemos que ir uno por uno, si no que podemos seleccionar todos los que queramos en la ventana Project y aplicar los cambios juntos. Pero eso sí, hay que tener en cuenta que el tamaño de textura puede necesitar variación, porque habrá Sprites entre los que hemos creado que serán mayores de 32 de ancho o de alto, por lo que tendremos que elegir un Max Size más adecuado como 64, 128 o el que sea ligeramente más grande, es decir, por poner un ejemplo: Si el campo de juego mide 190x160, el tamaño de textura de 128x128 se le queda pequeño, por lo que elegiremos 256 que es el siguiente.


Una vez configurado todo nuestro arte lo colocamos en la escena. Para hacer esto o arrastramos el Sprite a la ventana Scene donde podremos moverlo con el ratón, o lo arrastramos a la ventana Hierarchy, donde aparecerá escrito su nombre. Cualquiera de las dos formas es válida y generará tanto el nombre en Hierarchy, como el objeto en Scene.


Si pulsamos en la ventana Hierarchy la tecla F2 mientras tenemos seleccionado un objeto podemos cambiar su nombre. Por ejemplo prefiero tener las cosas en inglés y con la primera letra en mayúscula para recordarme a mí mismo que es un GameObject, es decir, un objeto del juego. Por eso he cambiado campo por Field.


Ahora tenemos que aprender alguna cosilla más, el uso del Inspector. En esta ventana aparecen las propiedades del objeto seleccionado, tanto si lo está en la ventana Hierarchy como si lo está en el Project Window. Cada objeto tendrá determinados componentes y podremos añadirle más para que tenga nuevas funcionalidades usando el botón Add Component o desde el menú Component de la parte superior de la interfaz. En el caso del campo, vemos que como es un Sprite2D, tiene el Sprite Renderer, que se encargará de dibujar el gráfico en pantalla (Ya explicaremos más de este componente si es necesario). El otro que podemos ver es el componente Transform, que tienen todos los objetos en Unity, incluidos los objetos vacíos, y es que este se encarga de definir su posición en el espacio, su rotación y su escala a partir de su X, su Y, y su Z. Podemos así variar numéricamente esta componente del objeto seleccionando e introduciendo números en estas casillas y sabiendo que, la escala normal de un objeto es (1,1,1) su rotación “en reposo” es (0,0,0) y, teniendo el punto de pivote en el centro, la posición central en la pantalla se define con (0,0,0).


Y nos vamos a ir despidiendo por ahora con lo poquito que hemos aprendido, prometiendo mucho más (como se puede ver en las imágenes yo llevo el proyecto mucho más avanzado, jajaja - ejem, no vale reírse -), pero antes veamos una cosa importante, la cámara. Si seleccionamos la cámara en el Hierarchy pulsando sobre Main Camera que ya aparece automáticamente en la escena, vemos que tiene algunos componentes ya añadidos. El componente Camera es importante porque en él definimos como va a mostrarse la escena. Como he dicho en muchas ocasiones para juegos 2D nos interesa una cámara Ortográfica, por lo que elegimos Orthographic en Projection y definimos un tamaño que nos enfoque todo nuestro campo de futbol. En mi caso ha funcionado un Size o tamaño de 0.8. Respecto a los Clipping Planes indica los planos de recorte o distancias a los que la cámara dejará de pintar los objetos cercanos (Near) o lejanos (Far).


Como veis son demasiadas cosas las que hay que tratar para entender cómo funciona todo y el espacio aquí es limitado, por lo que si hay dudas lo mejor será investigar un poco por la red o preguntarme (Si tenéis suerte conoceré la respuesta, porque tampoco es que sea un experto). Ahora, eso sí, antes de irme debería deciros como guardar una escena, algo diferente al proyecto, que contiene los recursos que incluisteis en la carpeta de proyecto a través de la ventana Project y por lo tanto ya está guardado. Las escenas son como los niveles de juego, es decir, donde vamos a colocar los objetos. Para guardarlas elegimos en el menú superior File/Save Scene y a continuación navegaremos a la carpeta deseada dentro de nuestro proyecto (generalmente Scenes) escribiremos el nombre deseado (En mi caso GameScene) y guardamos. Al abrir de nuevo el proyecto en un futuro, si queremos recuperar esa escena solo tendremos que usar Open Scene para cargarla o hacer doble click en su nombre en la ventana Project.



Si estáis pensando que soy una mala persona por no colgar el proyecto en algún sitio para descargarlo y tener todos los recursos necesarios, debéis saber que lo hago por vuestro bien y porque quiero que practiquéis y curioseéis todo lo posible, además de que ya expliqué en el post anterior, los Sprites que necesitaremos y como crearlos. ¡Así que a trabajar sin excusas!

jueves, 11 de diciembre de 2014

Juegos que me influyeron como desarrollador: SteamWorld Dig

Nunca había hablado de un juego Indie en esta sección, y me sorprende, porque yo soy muy de este tipo de juego más creativo y “sencillo”. Así que hoy, para solucionarlo, toca hablar de uno que descubrí en la eShop de Nintendo 3DS (aunque está disponible en muchas más plataformas) y que me causó una muy buena impresión como desarrollador: SteamWorld Dig.

El estilo gráfico elegido me resulta muy atractivo. Además, el protagonista es un robot y habitualmente me suelen gustar, junto con las historias que tienen que ver con ellos. En este caso la trama nos traslada a un ficticio Oeste donde un robot minero llamado Rusty tiene que explorar el subsuelo en busca de minerales para obtener mejoras. Y es que al principio las habilidades de Rusty están limitadas, por lo que necesita evolucionar para seguir avanzando y llegar a lugares más profundos de la mina con capacidad para enfrentarse a enemigos cada vez más complicados.



Este diseño sencillo de mejorar a base de explorar y derrotar enemigos para poder avanzar más fácilmente por un mundo cada vez más difícil, es algo en lo que se basan muchos juegos. Una nueva arma puede abrirte nuevos caminos o permitirte enfrentarte con éxito al enemigo que siempre te hacía morder el polvo, por ejemplo.

En este caso, en SteamWorld Dig, el mundo es continuo y no hay pantallas de carga, si no que siempre está ahí. Cada vez vas llegando más profundo en la mina, mezclando así las plataformas con una mecánica sencilla que podría tener un juego como Boulder Dash de cavar y cavar evitando que te pueda caer algo encima (Aunque en este caso no hay prácticamente mecánica de puzles como si lo hay en Boulder Dash).

Según vayamos consiguiendo minerales podremos comprar un pico más duro, un taladro, un salto que nos permita llegar más lejos… Así, lograremos llegar al fondo de la mina donde nos espera una dura batalla para desvelar el final del juego. 



El título tiene algunas pegas, como puede ser la poca re-jugabilidad (Una vez lo terminas no hay mucho más que hacer). Pero es inspirador, entretenido y está muy cuidado, lo que lo convierte en una buena inversión.


Además de todo lo comentado, lo que lo hizo interesante para mí fue que ya había pensado alguna vez en la posibilidad de desarrollar (cuando tenga los medios y el tiempo) un juego que parta de esta base sencilla de poder avanzar hacia una meta, pero tener que volver atrás constantemente para mejorar y reponer fuerzas cuando la cosa se ponga muy complicada. Una aventura que permita disfrutar de la ventaja de nuevas armas e ítems aparecidos en el momento oportuno, cuando el jugador empieza a sentirse en serios problemas, y sobre todo de divertirnos usando las evoluciones obtenidas para luchar contra viejos enemigos de nuevas formas o descubrir caminos ocultos que tuvimos que dejar por imposibles en un primer momento.


lunes, 8 de diciembre de 2014

Modelado Low Poly desde nivel básico: Pistola - Textura

El proceso para pintar la textura de este objeto es similar al de siempre. Partimos de una base, añadimos colores, detalles, arañazos, suciedad, marcas, Ambient Oclussion y detalles de sombra que queramos y listo. Vamos a verlo un poco paso por paso.


Para empezar como ya dije en el anterior post donde terminamos el mapeado, partiremos de una textura que es una fotografía de un trozo de metal. Suele ser habitual que pueda tener algún brillo y lo que nosotros buscamos es una iluminación bastante uniforme, así que podemos retocar la imagen añadiendo algún gris a las zonas brillantes o modificando los niveles de luces y sombras y su brillo y contraste.


Tenemos la capa de líneas del mapeado encima que podemos apagar y encender cuando queramos para guiarnos y saber dónde estamos pintando. Así, damos colores planos, en este caso a las zonas que estarán hechas de un material plástico en vez del metal de la pistola. Yo he usado tonos negros y grises.


Seguiremos pintando algunos detalles. Añadimos en este caso unas letras que van grabadas en el metal. Como tenemos solo media textura y aplicaremos simetría tendremos un problema con esto al aplicar el material al objeto final.


Como vemos, la textura final saldía invertida por el lado opuesto, por lo que las letras se ven como en un espejo, al revés. Para arreglar esto, he hecho la pequeña “chapuza” de usar letras que reflejadas se leen igual porque quiero mantener este ejemplo para ilustrar el uso de la simetría y la media textura. Realmente la solución pasaría por eliminar esta simetría y colocar ese fragmento en otro punto de la textura. (Al menos no conozco otra solución, si alguien sabe una mejor, le agradecería que me ilustrara un poco).


Para grabar las letras en el metal he usado un efecto de capa del software de retoque que permite esto. Si nuestro programa no dispone de esta ventaja podemos darle volumen a mano con un sombreado que le proporcione esa apariencia. Así, siguiendo este mismo método, iremos creando hendiduras y marcas.


Para destacar un poco más las hendiduras añadiremos suciedad dentro y alrededor de ellas, eso sí, de forma sutil. Son zonas de los objetos que tienden a acumular impurezas porque no tienen fácil acceso para su limpieza a fondo.


Llega el momento de dar volumen al seguro del arma y añadir botones y tornillos. Una buena forma de hacerlos es pintar un círculo y añadir un efecto de capa que le proporcione volumen (o pintar ese volumen a mano). Si hacemos esto en otra capa encima y borramos la zona donde estaría el “dibujo” del tornillo (me refiero a donde insertaríamos el destornillador), conseguimos el aspecto deseado. Con algunos brillos además, les daremos aspecto metálico.


Empezamos a trabajar en la culata y la empuñadura pintando algún pequeño dibujo y dándole volumen y un poco de textura respectivamente.


Ahora, además de añadir quemaduras y zonas gastadas gracias a un poco de negro semi-trasparente y desenfoques de movimiento, continuamos haciendo más interesante la empuñadura con un motivo de cuadros al que aplicamos un efecto de capa para que tenga relieve. (En este caso hacerlo a mano sería un poco trabajoso, por lo que para ser rápidos, habría que hacerlo en un cuadro y duplicarlo, lo que restaría un poco de realismo al ser todos iguales).


Pintaremos la parte superior del arma con un color más oscuro y añadimos manchas junto con una segunda forma a la empuñadura para hacerla más atractiva, por supuesto con un poco de volumen gracias a máscaras de capa.


Llega el momento de desgastar los bordes y esquinas del objeto para que tengan aspecto de haber sufrido golpes o roces. Para hacerlo más realista pondremos también algún relieve irregular para los ya comentados golpes que hayan dejado pequeñas marcas y arañazos sutiles.


Manchamos la textura en conjunto y añadimos algunas sombras extra al Ambient Occlusion que ya nos acompañaba desde el principio. Con esto terminaremos nuestra textura con unos resultados bastante aceptables.


Del propio Diffuse de la textura, a partir de ajustes en su contraste y brillo podemos obtener el material Specular. Las zonas más oscuras al ser plástico queremos que no sean muy brillantes, mientras que el metal va a destacar un poco más.



Y el resultado final al aplicar nuestro material con Diffuse y Specular es el que puede verse en la imagen. Podíamos añadir también un Normal Map para darle algo de relieve, para ello recordamos en este post, que hay utilidades y plugins para obtener este material a partir de nuestra textura 2D. Sin embargo, en este caso no quiero meterme de momento en este tipo de materiales. Ya los veremos en futuros post de modelado.