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.

 

C++: Cargar y ejecutar Python (Scripting)

C++ es un lenguaje de programación muy poderoso, pero uno de sus ventajas es que una vez compilado, si necesitas hacer ciertos cambios se requiere de utilizar el código fuente,  por lo que si necesitamos que un usuario pueda hacer ciertos cambios sin darle el código fuente, podemos darle la oportunidad de generar scripting, en este articulo mencionare como cargar y ejecutar código de Python desde C++ y la comunicación en ambos sentidos. En videojuegos es una manera tradicional de permitir al usuario genere sus propios mods, entre otros usos.

Configuración básica:

  • Instalar Python (En este ejemplo yo utilize 3.6) de preferencia en “C:/Python36”.
  • Crear un proyecto de consola en C++.
  • Compilar el “hola mundo” para que genera la carpeta de .exe.
  • Copiar “python36_d.dll” donde esta el .exe.
  • Agregar al proyecto include de “C:\Python36\include” y Lib a  “C:\Python36\Lib”.

Read More

IA básico de un vehículo

En este articulo hablare un poco de como crear una inteligencia artificial para un vehículo para que pueda recorrer por si mismo, para este ejemplo me base en el proyecto de como crear una nave al estilo hoverboard en Unity. Es una demostración sencilla de como puede crearse uno, puede mejorarse, pero la intención era hacerlo lo más sencillo y funcional.

La inteligencia artificial de este ejemplo lleva acabo 3 tareas: primero si debe acelerar o frenar, si debe ir girando a la derecha o izquierda y esta frente a una pared, determinar en que sentido es más posible poder continuar su camino.

1°- Determinar si debe acelerar o frenar: Para esto simplemente se lanza un raycast hacía adelante del vehículo a 7 unidades de Unity, si este no impacta en nada entonces aceleramos, si impacta con algo dejamos de avanzar (la nave estilo hoverboard cuenta con inercia), esto para dejar que pueda llevar acabo mejor una vuelta.

2°- Determinar para donde debe girar: En este proceso se lanza 2 raycast hacía adelante pero en diagonal igual de 7 unidades, entonces en el caso del lado derecho, si este impacta, entonces indicamos que debe girar hacía la izquierda (para alejarnos de la pared) y sin importar si impacto o no, se hace lo mismo hacia el lado izquierdo, done si impacta con lago giramos hacía la derecha, ocasionando que en el caso que ambos hayan indicado que deben girar se anulen y simplemente siga hacía el adelante el vehículo.

3°- Estar frente a un pared, determinar si a la derecha o izquierda es más posible continuar con el camino: Existe un caso especial que puede ser que el paso 1 y 2 no fueron suficiente y termine el vehículo a frente de una pared y se debe determinar hacía donde es más posible continuar con nuestro camino, es aquí que se lanza un raycast totalmente hacía la derecha y otro hacía la izquierda, y si uno de estos raycast no impacto en nada, entonces le indicamos al vehículo  que gire hacía esa dirección hasta que el paso 1 y 2 vuelvan a permitir que pueda continuar con su camino.

En el gif solo se ven por muy pocos frames.

Aquí les dejo el enlace para descargar el proyecto completo: DESCARGAR

Notas para atender mejor el ejemplo:

  • transform.TransformDirection(Vector3.forward) : Para poder lanzar un raycast hacía adelante del vehículo uso la función TransformDirection de transform que me convierte el Vector3.forward en otro vector3 pero con lo que representa hacía adelante del vehículo, y así para todos los sentidos.
  • LayerMask: Este tipo de variable ayuda hacer que el raycast ignore el mismo vehículo (esto para poner muchos vehículos 😉  ).
  • horizontal = (AfrenteDer == false) ? 0f : -1.0f;   Este es una manera de implicar un if, donde si la variable ‘AfrenteDer’ es igual a falso, entonces ‘horizontal’ es igual a 0.0f, en caso contrario (else), ‘horizontal’ va ser igual a -1.0f.

Unity – Detectar mientras se deja presionado botón en UI

El sistema de UI de Unity cuenta con botones pero tienen el pequeño problema que solo activan el evento de presionado y no mientras se mantenga presionado, por eso les comparto aquí un pequeño script que solo deben agregar a su proyecto y con esto agregar a cualquier botón que necesiten que llame una función mientras se encuentre presionado y agregar en su eventos que función llamara como ya funciona el sistema de eventos de Unity.

 

Como funciona:

Unity aparte de agregar eventos desde el inspector puedes recibirlos directamente por script usando el EventSystem y así poder detectar cuando es presionado y cuando se deja de presionar, y mientras se encuentre presionado, se llama la función que ah sido agregado como a una variable del tipo UnityEvent.

Guardar todos los sprites de un atlas como png independientes (Solo Editor)

Este script permite convertir todos los sprites de un atlas o textura que hayan sido recortado con la herramienta de Unity en imágenes independientes png y almacenarlas en el disco duro, y poder usarlo fuera de Unity (Que fue el motivo real por el que lo cree).

Campus Party México 2017 Workshop Pacman

Aquí les dejo el proyecto completo hasta donde se llego en el workshop que impartí en el campus party méxico 2017.

La carpeta comprimida también incluye la diapositiva que se presento.

Proyecto Pacman

PARCHE: Hay un pequeño problema con los fantasmas que cuando tiene que usar los nodos del centro que teletransportan de un lado a otro, estos solo atraviesan todo el nivel, por lo que este código al inicio de “ActualizarLerp” en los fantasmas podría solucionarlo (Lo hice al aire, si alguien lo prueba y verifica se agradecería)

//Son casos especiales en nodos especiales que teletransprotan al fantasma 
if (Camino[IndexInResult] == new Vector3(35f, 0f, -2.3f)) //Es nodo de hasta la derecha especial?
 {
      transform.position = Camino[IndexInResult]; // 3 Es es nodo derecho
      IndexInResult++;
 }
 else if(Camino[IndexInResult] == new Vector3(-35f, 0f, -2.3f)) //Es el nodo de la izquierda
 {
       transform.position = Camino[IndexInResult]; //2 es nodo izquierdo
       IndexInResult++;
 }

 

Unity- Manejar los Tag y los Layers de manera facil en scripts

Los Tag y los Layers son muy usados en Unity, pero también muy factibles a que nos generen problemas. De manera básica los Tags permite comparar GameObject por tag para si tienes muchos tipos de enemigo, pero solo quieres saber si es enemigo y no de su tipo, solo puedo preguntar por su tag (Uso común en los Collision y Trigger) y los Layers funcionan para indicarle a la camara que GameObjects puede ver y cuales no, en las luces sobre que GameObject puede iluminar y cuales no y por ultimo en las físicas para hacer que por ejemplo las balas no puedan colisionar entre ellos (Matrix de colisión) o que un Raycast ignore ciertos objetos, entre sus principales usos.

Ambos presentan algunos problemas al trabajar con ellos dentro de un script:

  1. En caso de Tag podemos escribir “player” y este no va funcionar porque es con ‘P’ mayúscula y esto no hay manera hasta el ya probar si estamos en lo correcto o no.
  2. Si en un script comparamos con el Tag de “Pared” y pasa el tiempo y según nosotros no se utiliza y lo eliminamos de la lista de Tags, Unity no te notificara si hay un script que lo este utilizando o no, solo dejaran de hacer lo que esperamos estos scritps, en pocas palabras no sabemos si se utiliza o no en scripts un Tag.
  3. En Layers las operaciones o suelen ser ‘ 1 << NumeroLayer ‘  o ‘ 1 << LayerMask.NameToLayer (“MiLayer”) ‘ donde o no sabemos bien que numero es cada layer o en el caso dos, el mismo problema con los Tags no sabemos si esta bien escrito o en caso de eliminarlo no saber de manera inmediata si lo esta utilizando o no un script.

Una solución aparte de ser cuidadoso, es crear un script que tenga puras constantes con los nombres de los Tags y Layers para tenerlos en un lugar y actualizarlos de manera manual cualquier cambio. Entonces se puede generar un script que genere este script de manera automática con el fin que sea más rápido y estar 100% que se escribe de manera correcta.

Al final pongo el código del script que solo debes agregar a tu proyecto y debe estar dentro de una carpeta llamada ‘Editor’ y en ‘Edit / Generate Constants Classes’  y se auto generan los scripts. Con esto ya en cualquier script en vez de compara el Tag de “Player”, solo debes usar ‘ k.Tags.PLAYER’ el cual es un string constante, esto asegura que el string esta correctamente escrito y si se llegara eliminar el Tag al actualizar los archivos,  como los scripts hacen referencia a una variable, marcaría un error en todos los scripts que necesitan ese Tag y se aplica lo mismo con los Layers. De esta manera resolvemos los problemas mencionados anteriormente.