Unity, editores y matemáticas Parte 1.

Llevas horas y horas perdiendo el tiempo haciendo niveles con Unity. Por cada pequeño trozo de nivel que hagas necesitas arrastrar más de 20 prefabs, clonarlos, cambiar sus posiciones, y cambiar sus valores dependiendo de las características. Es una perdida de tiempo y no un trabajo divertido.

Está claro que necesitas una herramienta específica para crear niveles. Aquí es donde entra la capacidad que tiene Unity para ser extensible.

En el proceso de creación de nuestro cuarto juego nos hemos topado con este mismo problema. Los mapas de nuestro juego se componen de “tiles” o piezas que se puede juntar para hacer pedazos de tierra más grande.

Hacer niveles era demasiado tedioso y además se perdía un montón de tiempo. Por esto nos vimos en la necesidad de crear un editor de niveles.

Pero, ¿Qué tiene que ver esto con las matemáticas? Por ahora no mucho, pero como veréis más adelante, se nos presentaron problemas que con un mayor conocimiento de matemáticas se podrían haber resuelto con mayor facilidad y menos quebraderos de cabeza.

Esta primera parte se centrará en explicar muy por encima como funciona el editor y presentaros el problema que nos surgió.

A la hora de crear un editor de niveles tenemos que tener muchas cosas en cuenta antes de empezar a escribir cualquier tipo de código. Por ejemplo:

  • ¿Necesitamos que el editor, cree cosas, las modifique, o ambas?.
  • Como representar nuestra “base” o lugar de trabajo: ¿en la escena (Gizmos, gameObjects)?, ¿en el Inspector?, ¿en ventanas emergentes? etc…
  • ¿Queremos que el editor sirva solo para este juego, o para varios del mismo estilo?
  • Si utilizamos la escena; ¿cómo detectamos los clicks del ratón o del teclado?.

En el escenario perfecto todas estas preguntas tendrían respuesta antes de empezar la creación del editor. Pero como todo desarrollo de videojuegos, hasta que no empezamos a realizar pruebas, es difícil predecir que herramientas son las que eliminaran cuellos de botella de producción y nos facilitarán el trabajo.

Nuestro objetivo principal con la creación del editor es doble.

Por un lado nos interesa reducir el tiempo de creación de los niveles y dedicar más tiempo a su diseño.

Por otro lado, necesitamos un sistema en donde los mapas se guardan como archivo texto para que ocupen menos espacio. Debido a que estamos creando juegos para móviles, tener más de 40 niveles ya cargados en memoria suponen un tamaño de juego demasiado grande para una app. (En entradas posteriores hablaremos de como guardamos y cargamos los niveles).

Después de darle muchas vueltas, quedamos en que el editor tenía que verse algo como así:

Mock up of EducaGames's tile editor tool for Unity

  • Tiene que tener celdas en donde, al pasar el ratón, se puede “pintar” un tile.
  • Debido a que solo se puede “pintar” en las celdas, se tiene que poder elegir el tamaño del mapa que se quiere crear.
  • Puede haber varios tipos de tiles (césped, tierra, agua, etc..) por lo que se tiene que poder escoger que tile se quiere pintar y guardar la posición y que tipo de sprite tiene cada tile.

Aspecto Técnico

Para cumplir los requisitos iniciales de nuestro editor, realizamos sus características de la siguiente manera:

  • Cada celda se compone de un collider y un script que detectan si el ratón está sobre él. Fig1
  • Si el ratón está sobre la celda se crea una imagen “fantasma” del tile que se va a crear. Fig2
  • Si el usuario presiona el botón de “pintar” se instancia un objeto, y ocultamos la celda. Fig3

 

Pasos de creación de un tile

 

Para facilitar la creación del grid se decidió crearlo simétrico, la cantidad de celdas de un lado a otro en una diagonal siempre son siempre iguales. Esto produce que la cantidad de celdas de la fila central sea igual al tamaño del mapa. 

 

Grid entero con indicación de tamaño Editor de tiles

En la imagen anterior vemos que tenemos un mapa que consideramos de tamaño 7. Si contamos cuantas celdas tiene esta fila central, veremos que es 7. Recordad esto que luego nos será bastante útil.

Cada celda contiene un identificador (id) numérico que utilizamos para diferenciar unas celdas entre sí y darle una identificación al tile que se dibuja encima. De esta manera, si dibujamos un tile en la celda con id 43, crearemos un tile con id 43.

Para numerar cada celda empezamos por la celda más baja de todas y vamos asignando el id de izquierda a derecha y de abajo hacia arriba. Esto nos das un grid con estos id:

Teniendo todo lo mencionado en cuenta, podemos realizar mapas sencillos y de forma muy rápida.

Gif Editor de tiles en Unity en accion


Mapa 1 de muestra prueba de editor de tilesMapa 2 de muestra prueba de editor de tiles

Al principio esto nos valió para realizar los mapas, pero a medida que se fueron complicando nos dimos cuenta que surgía con mucha frecuencia la necesidad de agrandar el mapa un vez creado. Aunque preparemos el diseño del mapa en papel, hasta que no lo jugamos no sabemos, por ejemplo, si las distancias son las correctas.

Esto nos llevo a la necesidad de poder agrandar el grid una vez creado el mapa.

En principio parece una tarea fácil pero nos encontramos con el problema de renombrar los ids. Al aumentar el tamaño del grid, esto quiere decir que los tiles que tenían un id iban a tener que cambiarse ya que la celda que les correspondía en el nuevo tamaño no tenia el mismo ID que el tamaño anterior.

Grid entero de tamaño 5 con ids

Grid entero de tamaño 6 con ids

 

Si el mapa está vacío no hay ningún problema, pero si está completamente lleno, hay que cambiar el id de esos tiles para que se guarde la información de forma adecuada.

El aumento del mapa es progresivo, si el tamaño es 7, al agrandarlo quedará en 8, y luego en 9 y así sucesivamente.

Además también hay que destacar que los tiles no se mueven, por lo que al aumentar el tamaño veremos una expansión del grid solo hacia arriba, no en todas las direcciones.

Mapa tiles hecho con editor de Unity tamaño 4

Mapa tiles hecho con editor de Unity tamaño 5

 

Después de mucho tiempo estudiando como cambiaban los id:

 

pruebas de cambio de tamaño de mapa 2

pruebas de cambio de tamaño de mapa 1

 

Nos dimos cuenta que desde la primera celda (celda con id = 0) hasta el final de la antigua fila central, todos los id eran iguales. En la siguiente imagen se ve como todos los ids del grid de la izquierda, a partir de la linea para abajo, coinciden con los ids del grid de la derecha, a partir de la línea para abajo.

Lo que antes era la fila central, ahora en el nuevo mapa más grande es la fila anterior a la central.

Imagen del editor donde se ve que id son iguales en el editor de Unity

Como se ve en las siguientes imágenes, nos dimos cuenta que al agrandar el mapa, solo en la dirección de arriba, se creaban dos diagonales que estábamos seguro que no iban a tener tiles. Esto nos permite hacer una relación más visual de cuales ids antiguos corresponde a los nuevos ids de un mapa más grande.

En la siguiente tabla podemos ver que id del tamaño anterior corresponde al nuevo tamaño. Trata de buscar un id del tamaño 5 y ver a que id corresponde en un grid de tamaño 6.

Grid de tamaño 5 Grid de tamaño 6
ID: 0 ID: 0
ID: 6 ID: 6
ID: 14 (Final de la fila central) ID: 14 (Final de la fila anterior a la central)
ID: 15 ID: 16
ID: 20 ID: 23
ID: 24 ID: 31

Con todo esto sabemos que hay que cambiar los id de las celdas que están más arriba de la fila central.

Esta primera parte la acabamos aquí. En la siguiente parte veremos como resolver este dilema de convertir los id y explicaremos como las matemáticas nos ayudaron a resolverlo.