Unity: Llamas funciones en Invoke de manera elegante.

Este post sera muy breve, solo es un pequeño tip al utilizar el ‘Invoke’ de Unity y deseamos llamar una función que se encuentra en en nuestro mismo script que llama el ‘Invoke’.

Cuando utilizamos el Invoke(«UnaFuncion», tiempo) tenemos que escribir entre comillas el nombre exacto de la función a la que deseamos llamar, sin embargo tiene 2 molestias que podemos encontrarnos. El primero escribir mal el nombre y el segundo es que si cambiamos nombre de la función o lo eliminamos hasta que se ejecute el invoke nos daremos cuenta que si la usabámos o tenemos que actualizar el nombre de la función.

Para solucionar esto, la manera elegante de usar ‘Invoke’ seria:

Invoke(nameof(UnaFuncion), tiempo);

Al usar la función ‘nameof’ de C#, nos ayudara autocompletar la función (así evitamos el primer problema) y si cambiamos el nombre de la función de manera inmediata nos marcaría un error y es más rápido actualizar.

Unity: Comprendiendo un poco los Quaterniones para las rotaciones.

Las rotaciones en entornos 3D se manejan en Quaterniones, no me voy a meter en como funcionan o como hacer operaciones a papel, pero si explicar de manera sencilla porque Quaterniones y como usarlos a nivel básico.

¿Porque no puedo rotar con grados de 0 a 360 grados?

Por como hemos sido educados, se nos hace muy fácil y natural manejar que una rotación esta compuesto por grados que van de 0 grados(0°) a 360 grados (360°). La forma de trabajar una rotación utilizando grados en las matemáticas de entornos 3D como videojuegos se les llama como grados Euler. Al trabajar con Euler se nos facilita mucho decir si tengo rotado algo 90° y quiero rotar otros  30° solo es 90° + 30° = 120°, fácil y es una simple suma, pero al combinar con 3 ejes, X, Y, Z, pasar de 350° y sumar 20°, no terminaríamos en 370°, terminaríamos en 10°, ya que lo máximo que existe en una rotación es 360°, al trabajar un angulo no es problema, pero al trabajar en 3 ejes, provoca un error matemático que se le conoce ‘gimbal lock’, que básicamente es que al trabajar con Eulers, si quieres trabajar con 3 ejes al mismo tiempo, un eje queda limitado su rotación para permitir que los 2 ejes funcionen correctamente.

Gimbal Lock / Bloqueo de cardán

¿Que son los Quaterniones?

Entonces sabiendo que hay un limitante al trabajar con las rotaciones en Euler, para solucionar este problema es trabajar con Quaterniones. Un Quaternion es manejar las rotaciones utilizando una matriz de 4 x 4 donde sus valores van de -1 a 1. Que básicamente lo que intenta hacer los Quaterniones es, okay si con 3 ejes, 1 eje queda limitado, agregamos un 4 eje, para que los 3 que nos importan tengan total libertad, es decir, fingir una cuarta dimensión. No tiene sentido pensar en una cuarta dimensión, cuando en nuestro mundo solo existen 3, pero entiendo que trampa esta detrás de esto es más sencillo. Entonces una recomendación es no tratar de imaginártelo ni entenderlos como funciona, solo enfocar en como usarlos. Se que matemáticamente ya hay mejores alternativas, pero fue demasiado tarde, por el momento todo software 3D, los utiliza, así que ni-modo.

Como rotar como dios en entornos 3D como Unity

Entonces al entender los Euler y Quaterniones, viene el como trabajar las rotaciones correctamente. Unity en el inspector te muestra las rotaciones en 3 ejes, que son en Euler, solo para que nosotros humanamente podamos entender mejor que rotación tiene el GameObject, pero sin embargo cuando trabajemos con ellos hay procurar al manipularlas hacerlo en Quaterniones y solo usar los Euler para leer y asignar de manera más cómodo para nosotros.

  • Siempre que quieras almacenar una rotación para usar hazlo en Quaternion, puedes usar Quaternion.Euler(x, y, z) para pasar de algo fácil de leer a como Unity le funciona mejor.
  • Multiplicar Quaterniones es sumar la rotación. Es decir Angulo1 + Angulo2 -> a Quaternion sería Quaternion1 * Quaternion2.
  • Si multiplicas una rotación de manera directa QuaternionFinal = QuaternionInicial * QuaternionAgregar  rotara tu GameObject de manera local.
  • Si multiplicas una rotación anulada primero y luego agregando lo que deseas rotar, es rotar respecto al mundo: QuaternionFinal = QuaternionInicial * Quaternion.Inverse(QuaternionInicial) * QuaternionAgregar * QuaternionInicial.  Aquí el truco que hace la diferencia para que la rotación sea respecto al mundo es ‘QuaternionInicial * Quaternion.Inverse(QuaternionInicial) ‘  que al * (sumar) la inversa a lo actual es como llevar la rotación a 0, 0, 0. Para entender mejor esto recomiendo dar repaso a rotaciones.
  • Cuando quieras interpolar rotaciones, usa Slerp no Lerp.

Esta guía esta basado en cosas que generalmente mis alumnos me preguntan y como surgen nuevas dudas iré mejorando el articulo.

Unity: Debugear más sencillo con Multiplayer

Este articulo no es como hacer un juego en Multiplayer con Unity, es más como mejorar el flujo de trabajo al desarrollar un juego en Multiplayer.

Cuando trabajas con Multiplayer en Unity, lo que genera que sea lento el proceso de desarrollar es que cualquier cambio debemos generar un nuevo build para probar más de un jugador. Que cuando estas en etapa de probar código, aunque solo cambien un int, tenemos que buildear de nuevo. Algo tedioso. Agregando que no tenemos la consola de Unity para ver errores. (que podemos solucionar con agregar consola para builds).

Tener 2 editores de Unity con el mismo proyecto:

Una solución que podría llegar a la mente es abrir el proyecto en 2 editores al mismo tiempo, pero por defecto Unity no permite esto. Copiar todo el proyecto en otra carpeta no sería eficiente y sería más eficiente generar un build.

La solución es utilizar las carpetas ligadas de los sistemas operativos (Windows, Mac y Linux) lo tienen. Una carpeta ligada es un como acceso directo de una carpeta, la diferencia es que un acceso es un archivo con extensión .lnk y una carpeta ligada el sistema operativo lo toma como si fuera una copia de la carpeta, pero sin necesidad de crear toda la copia.

Usando una carpeta ligada creamos un nuevo proyecto en Unity, pero sus carpetas de «Assets», «ProjectSettings» y «Packages» son carpetas ligadas a nuestro proyecto original, esto permitirá tener sincronizado nuestro proyecto de manera inmediata y al hacer otro «proyecto» (Realmente otra carpeta), Unity nos permite abrir en otro editor al mismo tiempo, así no ocuparemos buildear por cambio y podremos ver los objetos en escena y visualizar los mensajes de la consola. Buscando un poco encontré un proyecto con la idea ya aplicada:

Unity Project Cloner:

Para hacer esto lo mejor es utilizar el paquete de hwaet que solo debemos los archivos al proyecto y en Editor tendremos un nuevo menú llamado «tools» donde podemos generar la copia, eliminar y abrir otro Editor de Unity con el proyecto clon.

Al trabajar con el UnityProjectCloner hay unas pocas reglas que seguir:

  • Cada vez que sufre un cambio un script, solo debemos darle clic al otro Editor para que refresque.
  • Al cambiar algunos archivos, como escenas, tenemos que forzar el guardado en «File -> Save Project».
  • Otros archivos como prefabs, tenemos que abrir el editor con nuestro proyecto copia, seleccionar el archivo, clic derecho y «reimport».

Como vaya utilizando iré actualizando esto con mejores reglas.

Descargar proyecto

Unity: Agua 2D con olas

Para el juego de Villa Sancho prototipe un agua para el mundo de la playa el cual tuviera olas, pudiera tener splash cuando objetos entraran y salieran del agua y distorsionara un poco detrás de el. El prototipo es la imagen de cabecera de este articulo.

Mesh

Todo lo que vemos en nuestro mundo de Unity es un mesh con una textura, entonces para crear el agua se genera un mesh de manera procedural, para eso primero hay que saber que un mesh tiene 3 datos importantes:

  1. Los mesh están  contienen unos puntos llamados vértices que definen las coordenadas de cada parte de los modelos en el mundo.
  2. Todos los mesh están formados por triángulos que solo pueden utilizar los vértices.
  3.  Cada poligono para determinar como van a utilizar las texturas con ayuda de los uv, que van de 0.0f a 1.0f, entonces por ejemplo si solo quieres mostrar la 1/4 de la imagen, solo pones uv(0.5f, 0.5f), cada vértice que usa el polígono debe tener indicado esta parte

A partir de esto basándome en código de tutplus hice la primera versión, la cual recomiendo leer. Esta base tenia 2 problemas. El primero es que sus UV no permitían trabajar con texturas que no fueran un solo color y limitara el uso de shaders; y tiene demasiados polígonos.

El problema de los polígonos surge porque para crear el agua, esta formado por cuadrados que son los que mueves para crear efecto de olas, pero en la versión de tutplus cada cuadro que uno junto al otro, aunque tengan su pared exactamente igual, son 2 paredes en la misma posición, así que busco todos cuadros que tienen paredes similares y hago que compartan el mismo con un MeshWeld.

Tutsplus tiene asignado los UV de cada poligono de 0.0f a 1.0f, es decir cada poligono dibuja toda la textura en el, así que solo es dividir 1.0f/cantidadPolignos(o cuadros), esto permite que la textura funcione mejor y podamos utilizar shaders.

El shader lo tenia guardado de hace mucho, así que no tengo la referencia de quien es 🙁

Es un prototipo, se podria mejorar, pero quise optimizar la versión de tutsplus que esta bastante bueno.

Unity: Inicializar un script automaticamente sin importar escena ni gameobject

En unity existe la posibilidad de llamar una función de un script automaticamente al iniciar el juego sin importar la escena y sin necesidad que el script se encuentre en un GameObject.

El auto ejecutar una función siempre al iniciar el juego es perfecto para inicializar y cargar objetos que siempre necesitamos y evitar el problema de necesidad de pasar siempre por una escena para que las demás escenas funcionen o instanciar un Prefab para asegurar que siempre exista en nuestro juego, esta es la utilidad principal que utilizo.


[RuntimeInitializeOnLoadMethod]

public static void OnLoad()

{

//CODIGO

}

Esta técnica lo utilizo en mi Framework 2D para auto inicializar el manejador de audio. AUDIOMANAGER  (Hasta al final del script)

Unity: Enviar Logs a un email desde un build.

Cuando uno trabaja en Unity es de muy mucha utilidad la consola donde se muestra errores o mensajes de Debug.Log y Print que ayudan averiguar que pasa, al crear un ejecutable para PC en la carpeta del juego genera un log donde podemos visualizar estos mensajes, pero en caso de moviles se complica poder visualizar estos mensajes.

Existen diversos opciones por Internet para visualizar estos mensajes en runtime, pero aveces se necesitamos respaldarlos o sería más cómodo visualizar desde nuestra computadora. Con este script puedes obtener los mensajes de Unity y poder enviarlos a un email.

Para esto Unity cuenta con ‘Application.logMessageReceived’ que permite recibir los mensajes de la consola y los almacenamos en un string. Después enviamos este mensaje a un php almacenado en un servidor y este se encargara de enviar a nuestro email. Existen diferentes maneras, pero deje lo más básico el script para que funcione y si alguien necesita adaptar, sea lo más sencillo posible.

Unity: Combinar 2 textures por código

Una pregunta frecuente por alumnos en la clase de Unity es como combinar 2 texturas / imagenes en una sola sin usar un shader.

Esto se logra creando una copia de la TexturaA y sobre esta copiamos los pixeles de TexturaB, con 2 for anidados y solo debemos verificar que si el pixel a copiar no es completamente transparente (color.a > 0.0f) pasamos a copiar el pixel, en caso contrario lo ignoramos.

Dejo aquí un link de descarga del projecto del gif: DESCARGAR

Unity – Simple-Controller-Input uso de control en Unity

Simple-Controller-Input es un script para Unity que permite trabajar con control de Xbox de una manera sencilla. Solo basta agregar el script “GameControllerInputs.cs” a tu proyecto y podemos utilizar el control como: if( controllerInput.DPad_Left ) { acción }.

Como empezar a utilizar:
  1. Remplazar el archivo “InputManager.asset” de la carpeta del proyecto.
  2. Agregar el script “GameControllerInputs.cs” al proyecto.

Ejemplo de uso:

1°- Creamos una variable del tipo GameControllerInputs y en el Start lo igualamos a GameControllerInputs.GetIstance();


private GameControllerInputs controllerInput;

void Start ()

{

controllerInput = GameControllerInputs.GetIstance();

}

2°- Con esto podremos preguntar como controllerInput.DPad_Left , RightDirectional_Horizontal, etc. En la parte inferior de la página de github viene todos los inputs disponibles.

El proyecto fue iniciado por andre-lima y actualmente me fue transferido el proyecto para darle mantenimiento, así que cualquier problema o duda aquí me encuentro ?

Ir a Simple-Controller-Input

Unity – Como debugear en un build de manera sencilla

La consola de Unity es una gran utilidad que ayuda a encontrar y poder resolver problemas dentro de Unity de una manera sencilla ya que indica cual es el error, el script que lo ocasiono e incluso en que linea de código esta sucediendo el problema.

Este paquete de Unity permite tener la consola en cualquier ejecutable desde escritorio o movil solo agregando un pequeño prefab.

Consola en juego

El paquete le pertence a Yasirkula que es gratuito y de código abierto. Link de proyecto.

Unity – Generar Normalmap de textura en runtime

Script para obtener la textura de NormalMap de un Texture2D en runtime, el cual fue una pregunta de una alumna que se hizo interesante compartir su solución.

Nota: El proceso es algo lento, pero logra su cometido.