Programación: Tutorial desarrollo videojuegos con Unity 2D en español (Parte 1 Gráficos)

Tutorial Unity 2D

Si has llegado a este tutorial desde google, tal vez prefieras ver la introduccion a nuestro tutorial de Unity 2D en español. Si vienes ya de leer la introducción al tutorial sigue leyendo y comienza nuestro tutorial de desarrollo de videojuegos con Unity en 2D

Recursos gráficos para nuestro videojuego

Hoy seguimos el tutorial de desarrollo de videojuegos con Unity 2D con la parte de los gráficos. Los gráficos en los videojuegos son bastante importantes porque son los que llaman la atención de nuestros potenciales clientes para descargarse nuestro juego. Si ponemos uns gráficos pobres o feos nadie querrá probar nuestro juego aunque tenga una jugabilidad increíble.

Descarga de sprites y demás recursos para el juego en Unity 2D

Tras escoger la temática necesitamos los gráficos de los personajes (sprites) y los de los fondos. Podemos hacerlos nosotros mismos o comenzar descargándolos de páginas de internet. Yo para descargar recursos gráficos uso the spriter resource, vxresource, opengameart, GameDev y algunas más que iré detallando más adelante. En la web de Unity hay también una sección para comprar y descargar gratis recursos de videojuegos, creo que incluso se permiten vender imágenes para videojuegos. Aunque podéis buscar en google y encontrar las que tengan imágenes gratis para videojuegos. Para descargar sonidos uso Freesound y busco en google sonidos y música gratis. 

Para el personaje principal del juego en Unity he escogido estos sprites, si os fijáis son 12 imágenes dentro de un mismo archivo en lugar de 1 sola. Cada fila representa la animación del personaje en una dirección: abajo, izquierda, derecha y arriba. Con este Atlas realizaremos más adelante las animaciones del personaje cuando se mueve en una dirección o en otra de forma bastante sencilla. En esta imagen sprite el tener 3 columnas implica que cada animación constará de 3 frames. Cuantos más frames tenga una animación más fluida será ésta. Para juegos estilo "ochenteros" y retro como el que quiero hacer, con 3 frames es suficiente, si queréis hacer un juego más moderno deberéis tener mas frames

Para la nave espacial he escogido esta imagen de un cohete. La voy a trocear en varias partes, ya que el juego consistirá en recoger trozos de la nave, juntarlos en una posición de la pantalla y luego escapar dentro de la nave. Al menos este creo que será el funcionamiento del juego, veré si no me arrepiento...

Os pongo la nave entera para que os hagáis una idea pero luego recortaré la imagen en tres o más trozos con photoshop para después en Unity añadir los trozos como sprites independientes, de esta forma cada uno tendrá su posición en la pantalla del juego. Además al ser independientes el muñeco podrá interactuar con ellos por separado.

En ambos casos, si os fijáis las imágenes están muy pixeladas, es algo premeditado ya que quiero darle al juego un estilo "retro". Para hacer imágenes pixeladas podéis hacerlo con photoshop (buscad en google como hacerlo ya que sale fuera del alcance de este tutorial).

Sprites: breve explicación para novatos

sprite playerComo hemos visto antes, muchas imágenes de sprites están formadas por columnas y filas de la misma imagen repetida pero con leves cambios, normalmente cada fila es un conjunto de imágenes que realizan una animación específica del sprite, por ejemplo, en este caso, la fila 1 seria el muñeco moviendose a abajo, la fila 2 a la izquierda, la 3 a la derecha y la 4 hacia arriba. De esta forma en una sola imagen tendremos todas las animaciones de un personaje. En este ejemplo que he puesto cada movimiento (arriba, abajo, izquierda y derecha) constará de 8 frames (superior a los 3 del ejemplo de antes) ya que la imagen tiene 8 columnas. Cuantos más frames tenga una animación más fluida será. Más adelante os enseñaré como se transforma esto en animación dentro de Unity. En otras plataformas de videojuegos es importante que cada celda de la imagen tenga el mismo tamaño si no, la animación no será buena, en Unity no es necesario ya que el propio motor los recortará

Un videojuego sencillo en 2D consta básicamente de sprites animados (muñecos que se mueven), objetos (imágenes fijas con los que se puede interactuar y que pueden o no estar animadas),  plataformas (objetos sólidos con los que se interactúan pero no son móviles como paredes) y fondos (decorados que hacen que sea un poco más bonito).

Los fondos pueden ser estáticos o móviles para dar dinamismo y belleza visual.

En muchos videojuegos se usan fondos Parallax, los fondos tipo parallax son fondos dispuestos en varias capas que se mueven a distintas velocidades unos respecto de otros para dar sensación de profundidad al moverse el personaje. Dan bastante belleza y dinamismo al juego.

Unity: Animaciones

Si en el layout de Assets pulsamos sobre cualquier recurso veremos que en la parte de la derecha de la pantalla nos aparece una ventana llamada Inspector. En nuestro caso, vamos a configurar el sprite animado para que Unity sepa que es un sprite múltiple, es decir, que tiene animaciones. Para ello seleccionamos la imagen y en la ventana de Inspector escogemos en Sprite Mode: Multiple y pinchamos además en Sprite editor porque necesitamos indicarle a Unity cuales son las animaciones dentro de esta imagen. Nos saldrá una ventana con nuestro sprite y debemos pinchar en Slice y luego dejando marcado Automatic pulsamos en el otro boton Slice de esta forma le indicamos a Unity que queremos que de forma automática seleccione los Frames de la animación. Esto funcionará la mayoría de las veces, cuando falla es porque los sprites están pegados unos a otros. Se recomienda que al menos haya un pixel de separación entre un frame y otro. A mi cuando me ha fallado me ha sido más fácil editar la imagen con photoshop y separar los frames.

Una vez hecho esto, unity rodeará cada imagen de un recuadro blanco. Cerramos esta ventana y aplicamos los cambios con Apply.

Ahora en la ventana de Assets veremos que no sólo tenemos la imagen original sino que tenemos muchas más. Si queremos ver no sólo el listado de imágenes sino las imágenes en miniaturas podemos hacerlo moviendo la barrita de desplazamiento hasta obtener la visualización que más nos guste:

Otra forma de añadir animación a un Sprite es seleccionarlo y en la ventana del Inspector->Add Component->Miscelaneous->Animator. De esta forma tendremos un component Anomator en ese sprite.

Ahora debemos abrir las ventanas de Animation y Animator. Estas dos ventanas puede que no estén abiertas, asi que vamos a Window->Animation y Window->Animator. Ambas puede que nos salgan desancladas así que lo mejor es arrastrarlas pinchando en su titulo hasta la ventana inferior donde esta el Project. Deberíamos obtener algo como la imagen de la izquierda. Si nuestra pantalla aparece con clips de animación (rombos con lineas verticales) es porque ya tenemos creada la animación al haberlo importado de un Atlas con animación. Pero en este caso es mejor borrarlo pulsando en el boton -

Si no lo tuviéramos (o después de borrar el clip) hay que pinchar en el desplegable que está al lado del nombre de nuestro objeto y pulsar en Create new clip. Le damos un nombre de la animación (caminando_derecha por ejemplo).

Ahora debemos añadir los frames que correspondan con la acción. Si mantenemos la pestaña Animation en la misma ventana que Project no podremos arrastrar los frames, así que nos interesa coger la pestaña Animation y arrastrarla fuera. Ahora podremos añadir arrastrando desde la pestaña Project los frames que queramos a la pestaña Animation.

Si le diéramos al play para simular la animación veríamos cómo el sprite se anima. Si la velocidad de la animación fuera excesiva podemos cambiarla dentro de la pestaña de Animation ->Samples. Samples es el número de muestras por segundo, lo podríamos bajar o subir.

Ahora deberemos hacer lo mismo para el resto de animaciones del personaje. Para ello crearemos tantos clips como animaciones nos quedan: caminando_izquierda, caminando_arriba, caminando_abajo y parado (para este último usaremos una sola imagen aunque idealmente podríamos escoger una que tuviese una animacion del astronauta esperando)

Pestaña Animator:

Esta pestaña es muy útil para definir los diagramas de estados de las animaciones, o dicho de otra manera, las posibles transiciones entre una animación y otra. En nuestro ejemplo queremos hacer que cuando se empieza el muñeco lo haga en estado Parado y que desde cualquier estado pueda irse a cualquiera de los demás. Por tanto deberemos borrar transiciones en esta ventana y realizar otras hasta que obtengamos algo como la imagen de la izquierda. Para cambiar la flecha de Entry se hace pinchando con el boton derecho encima del estado Entry y pulsando Set stateMachine default state.

Ahora tenemos que añadir las condiciones (parámetros) que hace que se pasen de un estado a otro, es decir, qué hará que si estamos caminando hacia la derecha se vaya a la izquierda por ejemplo. Estos parámetros se pueden definir dependiendo de diversos valores: int, boolean, float o triggers. Los Trigger son "disparadores", acciones que ocurren que hacen que se dispare un evento. En nuestro caso usaremos triggers. Para añadir un trigger, pulsaremos en la pestaña parameters dentro de Animator, nos encontraremos que la lista está vacia y simplemente deberemos ir añadiendo triggers de uno en uno.

Para añadir deberemos pulsar en el "+"->Trigger y le damos un nombre hasta que tengamos todos los triggers creados:

Ahora hay que asociar a cada uno de los cambios de estados (las flechas del diagrama) un trigger. Para ello pinchamos en cada una de las flechas y en la derecha de la pantalla en conditions nos aparecera  List is empty. Pulsamos en el + y añadimos el triger que corresponda

Actualmente los triggers no hacen nada porque no los hemos activado, para activarlos lo haremos más tarde con un script que será el que bajo determinadas condiciones dispare un trigger u otro (Por ejemplo, si se pulsa un botón se moverá en una dirección, si se pulsa otro se moverá en otra)

Formatos de las imágenes 

A veces, cuando nos descargamos imágenes para objetos no animados, fondos o imágenes en general vienen todas dentro de una misma imagen, es decir, vienen mezcladas imágenes dentro de un archivo png. Esta forma de trabajar se le llama Atlas y es más eficiente en cuanto a memoria debido a que las imágenes se guardan en tamaños de potencias de 2 y se desperdicia espacio si no se llega a una potencia de dos. Por ejemplo, si tenemos una imagen única de 90 pixeles, ocupará en memoria igual que una de 128 que es una potencia de 2. Pero si juntamos muchas imágenes en una sola, aprovecharemos los huecos para no desperdiciar tanta memoria. Unity admite imágenes tanto en formato Atlas como en formato independiente. Recordad que Atlas es mejor!

Por otro lado, podremos usar imágenes png o jpg, cada una tiene sus ventajas y desventajas:

Comparativa imágenes JPG vs PNG

PNGJPG
  • Admite transparencia
  • Se usa principalmente para sprites
  • Ocupa mucho
  • No se puede reducir su tamaño (normalmente)
  • No tiene pérdida de calidad
  • No admite transparencia
  • Se usa básicamente en fondos que ocupen la pantalla completamente
  • Ocupa poco
  • Podemos elegir el % de calidad para que ocupe menos
  • Pierde calidad (si abrimos y guardamos la imagen en photoshop varias veces, la pérdida será notable)

Añadir recursos gráficos a nuestra escena del juego

Esto es bastance fácil, simplemente tenemos que arrastrar el recurso que queramos desde la ventana Assets hasta la de Scene, en mi caso he arrastrado un sprite del muñeco y un pajaro que he imprortado de la tienda de Unity y unas montañas. En la ventana de Hierarchy (Jerarquía) de la parte izquierda nos aparecen todos los recursos que hemos añadido, así podremos seleccionarlos desde Hierarchy. Una vez seleccionado, en la ventana del Inspector podremos ampliar su tamaño, moverlos, cambiarle la profundidad, etc. Algunos de los recursos son compuestos (formados por varias partes independientes pero unidas), en mi caso, las montañas son compuestas.

Algunas de las características de los recursos en Unity:

  • Position (Posición): La posición  puede cambiarse tanto desde el inspector como desde la escena. Tenemos coordenadas X, Y y Z. Esta última en juegos 2D no nos será de utilidad
  • Rotation (Rotación): El ángulo de giro con el que mostramos el sprite
  • Scale (Escala): La escala puede cambiarse tanto desde el inspector como desde la escena. Si tiene valor 1 es el tamaño normal, si es 2 es el doble
  • Order in Layar: Esta es muy importante ya que es la que indica el orden en que se pintarán los objetos. En una escena lo normal es que unos sprites se vean delante de otros, esto se hace con el Order in Layar. Por ejemplo si tenemos un pájaro con order in layar = 0 y otro con order in layar=1 el que tenga mayor orden se pintará encima del otro, digamos que se van poniendo unos encima de otros en el orden que tengan en este campo.

Recordad que como dijimos antes, cada recurso (Asset) puede añadirse varias veces a la escena siendo cada una de estas instancias independiente de las demás. Es decir, si tenemos un recurso que es un enemigo, si lo añadimos 100 veces tendremos un ejercito de enemigos cada uno con sus características propias (posicion, tamaño, etc)

En este ejemplo podéis ver que el muñeco y el pájaro se pintan por encima de las montañas, eso es debido al orden de pintado en las capas (order in layar)

Además hay algunos objetos por defecto en Unity (3D y 2D) que pueden añadirse desde GameObject->2D->Sprite para objetos 2D y desde GameObject->3D->EL_QUE_SEA para objetos 3D (fuera del alcance de este tutorial). En el caso de crear un objeto por defecto de tipo sprite nos creará un sprite vacío que será util más adelante

Añadir componentes a nuestros sprites del juego

Los componentes nos servirán para añadir a nuestros personajes y objetos físicas para que se comporten como en el mundo real. Antes de añadírselos, si ejecutamos la simulación con el botón play, los objetos estarán flotando en la pantalla. Si les añadimos físicas los sprites se verán afectados por la gravedad si le añadimos el componente (component) adecuado.

Para añadir un componente tenemos que seleccionar un objeto de nuestra escena y en la ventana del Inspector pulsar en Add component -> Physics 2D -> Rigid Body. Este componente hace que nuestro objeto se comporte como un cuerpo rígido con gravedad. Si simulamos la escena con el botón play ocurrirá que el objeto caerá hacia abajo saliendo fuera de la escena ya que no hay nada que lo detenga (no hemo puesto suelo...) Si nos equivocamos y metemos física a alguna imagen por error (a un fondo por ejemplo, veremos que se cae). Desde el inspector veremos que en el componente que hemos agregado tiene diversos atributos que iremos viendo poco a poco, pero por daros una pincelada deciros que podemos dar más masa a un objeto (de esta forma es más denso y dificil de mover) .

Como hemos visto, nuestro sprite al simular cae hacia abajo y se sale de la pantalla. Para evitar esto dijimos que necesitábamos añadir un suelo. Vamos a añadir una imagen de un suelo y le daremos consistencia. Cogemos una imagen de un suelo y la añadimos a la escena. Hacemos como antes Add compontent->Physics 2D-> pero ahora en lugar de Rigid Body lo que haremos es añadirle un detector de colisiones, escogemos el más sencillo Box Collider. Este detector de colisiones detectará las colisiones muy bien con formas cuadradas, aunque es menos preciso si un sprite no es cuadrado, pero por ahora nos servirá y además es el que mejor rendimiento tiene. Es importante escoger colliders con buen rendimiento si tenemos muchos objetos en pantalla ya que si no el rendimiento del juego caerá. A veces podemos necesitar colliders más precisos así que se pueden combinar varios colliders sencillos sin que decaiga mucho el rendimiento. Por ejemplo podemos añadir un círculo para la cabeza y un rectángulo para el cuerpo. 

Añadimos el mismo  componente a nuestro sprite del muñeco. Es decir, nuestro muñeco tendrá dos componentes: Rigid Body + Box Collider y nuestro suelo tendrá solo Box Collider.

Si ahora le damos a simular veremos que el muñeco caerá hasta chocar con el suelo. ¡Suponiendo que hayamos puesto el suelo debajo del muñeco!

Con todo esto estaremos añadiendo colisiones a los sprites del juego. Las colisiones de los sprites pueden ser de dos tipos principalmente:

  1. Bloqueantes: Un sprite choca con otro y no puede atravesarlo. Ejemplo: Un muro o el suelo
  2. No bloqueantes: Un sprite choca con toro pero lo atraviesa y lo único que hará es disparar por ejemplo un trigger para cambiar el estado de algo y hacer una acción. ejemplo: un objeto que se coge.

Deberemos hacer lo mismo con los demás personajes del juego y objetos que queramos que caigan hacia abajo.

A veces, si nuestro sprite esta compuesto de partes (los descargados de la asset shop de unity suelen ser así) cuando añadimos el component de collision nos coge el tamaño de una de las partes, lo cual no es deseable. Lo que se hace en estos casos es ampliar el cuadrado de la colisión y recolocarlo para que cubra todo el sprite.

Hay multitud de componentes, algunos de los cuales iremos viendo a lo largo del tutorial. Podéis investigar algunos si queréis, hay desde emisores de partículas hasta halos para hacer brillar los sprites pasando por detectores de colisiones más complejos.

Hasta aquí la primera parte de nuestro tutorial, podéis seguir con la segunda parte del tutorial de Unity 2D

Ir a la segunda parte del tutorial de videojuegos con Unity en 2D

 

 

Votos totales: 396