jueves, 13 de septiembre de 2018

Siguiendo al personaje y detectando colisiones

Otro pequeño avance en el prototipo. En esta ocasión he configurado la cámara para que siga al personaje. También he configurado colisiones para que el jugador no traspase algunas paredes que he añadido a la escena.

La animación de correr también ha sido mejorada ligeramente para mostrar una mayor energía y que coincida mejor con la velocidad de desplazamiento.


domingo, 9 de septiembre de 2018

Controlando al personaje con movimientos relativos a la cámara

No estoy teniendo mucho tiempo últimamente, pero he avanzado en poder controlar al personaje. Ahora se puede utilizar un controlador o el teclado para mover al personaje en diferentes direcciones. Cuando se usa el teclado el personaje simplemente corre en la dirección deseada. En el caso del controlador, se utiliza la posición de los ejes para determinar la velocidad del personaje y la animación utilizada (andar o correr).



El movimiento del personaje en este ejemplo es relativo a la cámara. Es algo que me ha costado un poco hacer en Unity pese a que lo he hecho cien veces en Unreal Engine. Si bien es cierto que en general Unity es más sencillo que Unreal, en ocasiones creo que complica las cosas. Por si alguien está buscando hacer algo parecido, el código es el siguiente:

1:    /// <summary>  
2:    /// Método llamado para actualizar el estado cada frame.  
3:    /// </summary>  
4:    private void Update () {  
5:      // Calculamos el desplazamiento horizontal y vertical  
6:      float hoffset = Input.GetAxis(AXIS_HORIZONTAL);  
7:      float voffset = Input.GetAxis(AXIS_VERTICAL);  
8:      // Cambiamos la animación basándonos en los valores de los ejes  
9:      float hspeed = Math.Abs(hoffset);  
10:      float vspeed = Math.Abs(voffset);  
11:      if (hspeed > runningThreshold || vspeed > runningThreshold)  
12:      {  
13:        Run();  
14:      } else if (hspeed > 0.0f || vspeed > 0.0f)  
15:      {  
16:        Walk();  
17:      } else  
18:      {  
19:        Idle();  
20:        return;  
21:      }  
22:      // Calculamos el vector de desplazamiento del personaje proyectado sobre los ejes de la cámara  
23:      Transform cameraTransform = Camera.main.transform;  
24:      Vector3 forward = cameraTransform.forward;  
25:      forward.y = 0.0f;  
26:      forward.Normalize();  
27:      Vector3 right = cameraTransform.right;  
28:      right.y = 0.0f;  
29:      right.Normalize();  
30:      Vector3 offset = (forward * voffset + right * hoffset) * speedMultiplier * Time.deltaTime;  
31:      // Calculamos la rotación del personaje hacia la dirección correcta  
32:      Quaternion targetRotation = Quaternion.LookRotation(offset);  
33:      Quaternion smoothRotation = Quaternion.Slerp(gameObject.transform.rotation, targetRotation,  
34:        turnSpeed * Time.deltaTime);  
35:      // Giramos y movemos el personaje  
36:      gameObject.transform.rotation = smoothRotation;  
37:      gameObject.transform.position += offset;  
38:    }  

Nótese que la variable runningThreshold es un atributo público de la clase. Su valor define el umbral a partir del que cambio la animación de andar a correr. La variable speedMultiplier es otro atributo público que define la velocidad general del personaje. turnSpeed define la velocidad de giro. Cuando se cambia la orientación del personaje, no lo hago directamente, sino que interpolo la rotación para el cambio de orientación se haga suavemente.

Nótese también que el formateo de código que proporciona Blogger es bastante cutre :-( Ya buscaré otro.

Todavía queda mucho trabajo en cuanto a la animación del personaje y la transición entre animaciones como se puede observar en el video, pero como primera aproximación no está mal.

miércoles, 5 de septiembre de 2018

Secuencia de logotipo de Bytecode Bits

Para variar un poco de lo que he estado haciendo últimamente y seguir aprendiendo, he estado dedicando tiempo a hacer un pequeña secuencia de video para poner en la presentación de mis juegos y experimentos con Unity.


El logo está modelado en Qubicle y la secuencia se ha renderizado y post-procesado en Blender. El sonido de ruido blanco lo he generado con Audacity. Realmente es todo muy sencillo. Curiosamente lo que más problemas me ha dado ha sido la exportación del video desde Blender porque creaba el video sin el sonido, o no conseguía que Unity se lo tragase. Parece ser cosa de los codecs, así que por si alguien está interesado, he acabado utilizando la siguiente configuración:

domingo, 2 de septiembre de 2018

Añadiendo sonido y nuevas animaciones

En esta ocasión, hemos añadido sonido a los pasos mediante eventos de animación y además hemos incluido una nueva animación para correr. También he mejorado algo la animación de espera (idle) haciendo que el personaje mire hacia los lados. No es gran cosa, pero le da algo más de vida.

Decir que me sorprende lo malo que es el soporte en Unity para eventos de animación sobre animaciones importadas desde otros programas. Básicamente se deben incluir los eventos en las opciones de importación de la animación con un interfaz de usuario bastante lamentable. En este caso eran animaciones sencillas, pero no quiero ni pensar el infierno que puede llegar a ser hacerlo con animaciones medianamente complejas.

En fin, os dejo el video con los avances.


jueves, 30 de agosto de 2018

Mejorando el personaje

Seguimos mejorando el personaje. En este caso le he aplicado un modificador Subsurface desde Blender para suavizar las esquinas de los voxels. También he mejorado ligeramente el esqueleto y las animaciones.

En el video se puede observar el personaje inicial a la izquierda y el personaje mejorado a la derecha.



Por cierto, gran trabajo por parte de la gente de Unity mejorando los tiempos de compilación. Actualicé a la última versión y se nota muchísimo.

viernes, 24 de agosto de 2018

Importación del personaje en Unity

En estos días he estado importando el modelo de personaje animado en Blender a Unity, por lo que voy a resumir la experiencia.

En primer lugar, traté de utilizar directamente el fichero con el modelo en formato .blend, copiándolo dentro de un subdirectorio de la carpeta Assets de mi proyecto en Unity. Sin embargo, la cosa no fue bien. Por algún motivo, Unity no era capaz de reconocer mis ficheros.

Así que opté por exportar un fichero .fbx desde Blender. En este caso Unity lo gestionó sin mayor problema. Todo el modelo con sus huesos, material y animaciones estaba ahí. Sí que tuve que copiar manualmente la textura del modelo en un subdirectorio a partir del directorio en el que coloqué el modelo del personaje para que se visualizace correctamente, pero por lo demás, todo fue rápido e indoloro.

Mi modelo actualmente tiene dos animaciones: idle (que por el momento solamente tiene un frame) y walk. Como es lógico, ambas animaciones deben "loopearse" en Unity desde las opciones de importación del modelo. Luego añadí al modelo el componente Animator correspondiente, junto a un script que gestiona los estados basándose en la pulsación de las teclas del cursor. Con esto ya tengo mi modelo respondiendo a algunas de mis órdenes en un escena de Unity. En realidad, todo muy sencillo.

Sin embargo, hay un problema. Cuando ejecuto el juego el modelo aparece correctamente, pero de alguna manera se pueden observar sus aristas. Al principio pensé que podía ser un problema con el sombreado flat de Blender, pero no fue así. Reimporté el modelo con un shading smooth con los mismos resultados. Luego probé a triangular el modelo con el plugin "Triangulate", pero tampoco solventó el problema. En el siguiente video se puede observar el efecto, sobre todo en los momentos que el personaje está parado:



Por el momento no he sido capaz de dar con la solución. Veremos si en próximos días acierto con la tecla.

EDIT: he conseguido identificar el problema. Al exportar el modelo desde Qubicle sin optimizar y con un tamaño de texel diferente de uno, la textura producida no es cuadrada. El problema se soluciona exportando con un tamaño de texel igual a 1. Sin embargo, tener que volver a exportar desde Qubicle me obliga a tener que retocar de nuevo los pesos de los vértices en Blender :-(

viernes, 17 de agosto de 2018

Animación del personaje

Comenté en un post anterior que el paso siguiente para animar nuestro personaje sería configurar la cinemática inversa. Tras realizar diferentes pruebas he decidido no utilizarla. El motivo es que en mi modelo basado en voxels, las deformaciones que producía la cinemática inversa eran completamente antinaturales. Posiblemente se puede llegar a controlar, pero el coste-beneficio de hacerlo no me compensa, al menos de momento.

Así que hemos procedido a crear una primera animación sin cinemática inversa. En este caso ha sido la de caminar y el resultado es el siguiente:


Como se puede observar, hay cosas mejorables. La secuencia no es del todo natural y algunas deformaciones pueden mejorarse tocando los pesos de los vértices. No obstante, como primera aproximación no es del todo mala.

Los siguientes pasos serán terminar de mejorar la animación e importar nuestro modelo en Unity. Tengo una primera idea para un minijuego con el que probarla, pero eso lo dejo para siguientes posts.

martes, 14 de agosto de 2018

La armadura del personaje base

Vamos a proceder a crear la armadura para el personaje base. La intención es reutilizar la misma armadura y animaciones para posteriores personajes con forma humanoide.

Tras una revisión del modelo importado en Blender, mi previsión es que la armadura no va a deformar la malla del todo bien por falta de aristas en ciertas partes del cuerpo, principalmente en las rodillas, pero como ya he comentado, esto es ensayo y error.

Pasamos a crear la armadura y nombrar todos sus huesos. La armadura creada se puede apreciar en la siguiente imagen:


El paso siguiente es establecer la armadura como padre de todos las partes del modelo. Hay que tener mucho cuidado con que la armadura esté perfectamente alineada con el modelo. En caso contrario se producirán deformaciones no deseadas al realizar esta operación.

Como primera aproximación, una manera rápida de asignar todas las partes a la armadura es seleccionarlas todas, seleccionar la armadura (siempre en último lugar) y utilizar la combinación de teclas Ctrl+P. De entre las diferentes opciones que Blender nos ofrece, se puede utilizar With Automatic Weights. No obstante, los pesos habrá que retocarlos posteriormente. Si nos equivocamos en algún momento, pulsando Alt+P con una parte seleccionada podemos usar la opción Clear Parent y volver a empezar.

Una vez realizado el "parenting" con la armadura, podemos pasar al modo Pose para empezar a probar la armadura y hacer los retoques pertinentes. En un primer momento, se puede observar claramente que los resultados son bastante malos, por lo que hace falta asignar mejor los pesos de cada vértice respecto a cada uno de los huesos. Para ello, seleccionaremos cada una de las partes y pasaremos al modo de pintado de pesos (Ctrl+Tab). En este modo podemos ir seleccionando los diferentes huesos y pintando los pesos que indican la influencia del hueso en cada vértice.

Durante todo este proceso, me doy cuenta de varias cosas. Por un lado, acaba siendo más correcto trabajar con una malla única en lugar de con las partes individuales. Si no se hace de esa manera, las partes se separan al deformarse, que es un comportamiento que no deseo. Por otra parte, el modelo, como era de esperar, tiene un número de polígonos demasiado bajo como para producir deformaciones naturales. El problema se agrava debido a que fue exportado desde Qubicle con la optimización activada, lo que provoca que se exporten triángulos en lugar de quads.


Para solucionar ambos problemas, lo que hago es volver a exportar el modelo desde Qubicle. Previamente he juntado todas las partes en un único Compound, de forma que la exportación produzca un único objeto. También desactivo la optimización (ya optimizaré en Blender). Vuelvo a importar el modelo en Blender y asigno su origen al centro de su geometría. Por último alineo el modelo con la armadura, la establezco como padre del personaje.

Volvemos a probar con el modo Pose y... el resultado es mucho mejor que en la primera prueba. No obstante, todavía hace falta trabajar en los pesos de los vértices para evitar artefactos.


Lo siguiente que pienso hacer es configurar la cinemática inversa del modelo para poder animarlo de forma más sencilla. Pero eso lo dejo para otro post.

Exportando de Qubicle a Blender

Siguiendo con mi "diario" para crear un juego basado en voxels, vamos a exportar el modelo expuesto en el post anterior desde Qubicle a Blender. El formato que utilizaremos para ello será FXB.

En Qubicle previamente hemos dividido el modelo en diferentes partes que deseamos conservar (al menos de momento) en Blender. También hemos hecho que los pivots de cada una de las partes se encuentren en el centro de su matriz.

Qubicle permite exportar dichas partes como ficheros distintos, o como diferentes objetos dentro de un mismo fichero. Para nuestros propósitos vamos a utilizar la segunda opción. También exportaremos texturas en un fichero único.

Lo primero que hay que hacer notar es que si se exporta a FBX con las opciones que Qubicle proporciona por defecto, el modelo importado en Blender será bastante pequeño. Para solucionar esto, vamos a aumentar el tamaño del voxel durante la exportación a 4.

El segundo punto con el que hay que tener cuidado es con la resolución de las texturas (si es que se van a utilizar). Por defecto, la resolución de dichas texturas es baja, por lo que conviene aumentar el tamaño del texel durante la exportación.

Yo estoy utilizando las siguientes opciones de exportación.


Tras guardar en la ruta que consideremos oportuna, importaremos el modelo en Blender. El primer problema que nos encontramos es que Blender no importa correctamente los pivot points que he colocado en Qubicle. He probado con diferentes opciones de exportación en Qubicle sin éxito. No me queda claro si es un problema de Qubicle o de Blender. En cualquier caso, es bastante sencillo establecer los pivot points de nuevo en Blender seleccionando todos los objetos y utilizando la combinación de teclas Ctrl+Alt+Shift+C (Set Origin). La opción a seleccionar de entre todas las que Blender nos ofrece es Origin to Geometry.

Tras recolocar la cámara a mi gusto, lo suyo es hacer un render rápido para ver que toda la geometría se ha importado bien. Yo he usado Blender Render para no perder demasiado tiempo creando materiales en Cycles. También he activado la iluminación global (Environment Lightning). El resultado es el siguiente:


Lo siguiente será crear el esqueleto y ver qué tal funciona con el modelo.

lunes, 13 de agosto de 2018

Personaje base con voxel art

Otro ejemplo más de voxel art creado con Qubicle. En esta ocasión se trata de una figura humana que me dispongo a exportar a Blender. Sobre Blender crearé su esqueleto y animaciones para posteriormente utilizarlos en Unity.

Este primer personaje será el modelo que utilizaré como base para crear otros personajes más complejos. Actualmente está dividido en las siguientes partes:

  • Pecho.
  • Brazo derecho y brazo izquierdo.
  • Mano derecha y mano izquierda.
  • Cadera.
  • Pierna derecha y pierna izquierda.
  • Cabeza.
  • Pelo.

Veremos si estas partes son suficientes a la hora de crear buenas animaciones, o por el contrario tengo que subdividir más el modelo. Por el momento, todo es ensayo y error.

La moneda a los pies del personaje simplemente sirve como referencia a la hora de crear el modelo del personaje con dimensiones adecuadas. La postura en "T" es la típica que se utilizar para hacer el esqueleto en Blender.


viernes, 10 de agosto de 2018

Más voxel art

Siguiendo con los experimentos en voxel art. Esta vez utilizando Qubicle para diseñar, y Blender para renderizar. No he empleado más de tres horas para hacerlo todo, así que que nadie espere ninguna genialidad.

Lo que pretendo es probar un pipeline para hacer un pequeño juego utilizando gráficos basados en voxels. Este pipeline estaría basado en Qubicle + Blender + Unity. En otras palabras, no esperéis mucho del diseño en cuestión.

Aquí la imagen tal y como fue concebida en Qubicle.
Y este es el render rápido hecho con Blender.



Mi primer voxel art

Haciendo experimentos con MagicaVoxel...