Publicat per

PEC 05 – Media para videojuegos

Publicat per

PEC 05 – Media para videojuegos

Introducción al juego de pelea Robotic Fighters Después de realizar las anteriores prácticas, he aprendido a modelar mis robots en 3D con…
Introducción al juego de pelea Robotic Fighters Después de realizar las anteriores prácticas, he aprendido a modelar mis robots…

Introducción al juego de pelea Robotic Fighters

Después de realizar las anteriores prácticas, he aprendido a modelar mis robots en 3D con Maya, texturizarlos, darles color y detalles, realizar su rigging y, finalmente, animarlos con diferentes secuencias como ataque, idle, muerte, movimiento y defensa. En esta última práctica, he creado una breve demostración de lo que sería un juego de lucha llamado Robotic Fighters, utilizando todos los elementos creados durante estas prácticas, es decir, tanto los robots como sus animaciones.

Cabe mencionar que ya tenía bastante experiencia previa con el programa Unity, tanto en 2D como en 3D, por lo que la implementación de un juego en dicho programa no me planteaba un reto extremadamente complicado a priori, pero sí desafiante y atractivo, ya que nunca había realizado un juego de lucha ni nada parecido.

La saga de videojuegos de lucha Tekken siempre ha sido un referente para mí en cuanto a juegos de este género, por lo que ha sido mi principal fuente de inspiración durante el proceso de desarrollo de Robotic Fighters, especialmente en lo relacionado con la cámara, el escenario y el HUD.

Creación del entorno del juego, cámaras y personajes

Lo primero que realicé en Unity fue importar los assets que iba a utilizar como escenario para el juego. En la Unity Store conseguí unos assets muy adecuados para mi juego, con unos escenarios futuristas y decadentes, perfectos para el estilo visual de mis personajes, alejados del estilo cartoon y más orientados a una estética futurista y sombría.

Así, creé una escena en la que arrastré diferentes assets para poco a poco ir formando el escenario, lleno de contenedores, bunkers y coches destruidos, lo que le da un toque de abandono y desolación al mundo del juego. Una vez que conseguí el resultado deseado, importé mis personajes de Maya: Robotydus y Archie. Los coloqué mirándose uno al otro con una distancia determinada y les apliqué a cada uno dos componentes: un Box Collider y un Rigidbody.

Hice lo mismo con el suelo, añadiendo un Collider para que los personajes se mantuvieran de pie al iniciar el juego. Para finalizar los preparativos, creé una cámara estática que enfocara a los dos personajes, colocando uno a la derecha y el otro a la izquierda. También añadí un Collider invisible detrás de cada robot para delimitar el espacio en el que se moverían durante el combate. Así conseguí preparar el entorno de mi juego de lucha y dejarlo listo para comenzar a implementar las funcionalidades jugables.

Lo primero que implementé en el juego Robotic Fighters fue el escenario mediante un Asset gratuito descargado desde la Unity Asset Store llamado RPG_FPS_Industrial Game.

Una vez creado el escenario implementé una cámara que enfocara a ambos robots en posición lateral mirándose el uno al otro.

Creación de las animaciones y el movimiento en cada robot

Este fue uno de los pasos más largos, aunque no el más difícil. Lo primero que hice fue crear un Animator para cada personaje y añadir allí los 5 clips de cada animación. Como ya había creado los clips en el proyecto anterior, pude acortar mucho trabajo.

Lo más desafiante fue crear las transiciones y conexiones entre cada animación, siendo Idle la animación central a la que derivaban todas las demás animaciones como muerte, movimiento, defensa y ataque. Para controlar estas animaciones, creé triggers como ataque, muerte y defensa, y un booleano para calcular la velocidad y activar la animación de movimiento.

Todo esto lo conecté con cada robot mediante un script llamado PlayerMovement. En este script, hice que, con el input de las teclas deseadas, se activara un trigger determinado. Además, al mover el robot, se modificaba el booleano del Animator para reproducir la animación de movimiento. Tuve que realizar algunos ajustes en la configuración del Animator para conseguir el resultado deseado en cuanto a los tiempos y las velocidades de las animaciones.

Todas las animaciones son controladas desde el Animator de cada robot. Cada animación cuenta con su propio trigger de activación y una transición con la animación siguiente.

HUD, menú y pausa

Una vez realizado el movimiento de los robots, me puse a crear las interfaces y los menús del juego, tanto el principal como el de pausa. Para ello, creé un Canvas en el que añadí tres paneles: el de la vida de los robots, el del menú de pausa y el del menú principal.

Para las vidas, creé un Slider para cada robot y ajusté algunos parámetros para conseguir el color y estilo visual deseado. Para los menús, importé un asset de UI Sci-Fi, que era muy acorde al estilo del juego. Creé dos paneles sencillos, cada uno con sus opciones. En el menú principal tenemos la opción de empezar el juego o salir. En el menú de pausa, las opciones son reiniciar el juego, continuar o salir.

Para configurar estos menús, creé un script con variables públicas para cada panel. La idea es que, al iniciar el juego, se muestra el menú principal, pero no se inicia el juego hasta que el jugador pulse los botones (a los que asigné métodos públicos). Al pulsar el botón Start, el movimiento de los robots y el juego en sí se inician. Con el botón Exit, se sale del juego. Durante la partida, si se pulsa la tecla espacio, el juego se pausa, y si se vuelve a pulsar, se retoma (con un margen de 1 segundo). En la pausa, podemos reiniciar, retomar el juego o salir.

Menú principal de juego y menú final que aparece cuando uno de los robots derrota al otro, y se muestra su nombre como el vencedor del combate.

Sistema de juego

El sistema de juego de Robotic Fighters está diseñado para ofrecer una experiencia fluida y dinámica en el combate entre los robots. Cada personaje comienza con 100 puntos de vida, representados visualmente mediante barras en el HUD. Cada golpe acertado por parte de un robot reduce la vida del oponente en 10 puntos, añadiendo un componente estratégico a los ataques y defensas.

El sistema de combate se basa en colisiones, habilitadas mediante colliders asignados a los modelos de los robots. Estos colliders permiten detectar los golpes en tiempo real. La gestión de los golpes se realiza a través de un script llamado AttackManager, que coordina los estados de ataque y defensa de ambos robots.

Cuando un robot ejecuta un ataque, su collider entra en trigger con el del oponente. El AttackManager verifica dos condiciones importantes:

  1. El robot atacante debe estar en estado de ataque, definido mediante un booleano en el script PlayerMovement.
  2. El robot oponente no debe estar en estado de defensa, lo cual también se controla mediante un booleano.

Si ambas condiciones se cumplen, el AttackManager llama a la función TakeDamage del script LifeManager. Este último es responsable de reducir la variable de vida del robot impactado y actualizar en tiempo real su barra de vida en el HUD.

Cada robot tiene un collider y un script llamado AttackManager que gestionan el impacto entre los robots. Cuando un robot ataca y el otro no está defendiendo, el AttackManager activa la función TakeDamage, lo que reduce la vida del robot afectado en 10 puntos y actualiza la barra de vida correspondiente.

Cuando se reinicia el juego, el LifeManager restablece todas las variables de vida a su estado inicial (100 puntos). Este proceso asegura que las barras de vida se reinicien adecuadamente al comenzar una nueva ronda.

En cuanto a la sonorización, el juego está completamente sonorizado: desde los movimientos de los robots hasta los botones de la interfaz de usuario. Estos sonidos se reproducen a través de Audio Sources, y son gestionados desde el script PlayerMovement, que controla la reproducción de los efectos de sonido durante las interacciones y acciones en el juego.

Script RobotFightController, que gestiona la mayoria de funciones del juego, como las animaciones de los personajes y sus movimientos, el reinicio del juego, el menú de pausa…

Script AttackController que gestiona el ataque de cada personaje al entrar en contacto con el otro y llama al método deseado del script LifeManager para reducir la vida del robot enemigo.

Script LifeManager, que gestiona la inicialización de las barras de vida de cada robot ( empezando con 100 en cada partida ) y la reducción de dichas barras cada vez que un robot golpea al otro.

Conclusiones y puntos de mejora

Así pues, ha sido un proceso muy dinámico y enriquecedor. Más que encontrarme con obstáculos o picos de dificultad, he tenido que dedicar bastante tiempo a planificar y complementar los elementos jugables, así como a asegurarme de que los aspectos visuales se alinearan con el estilo del juego. Estoy contento con el resultado, aunque soy consciente de que las animaciones podrían estar más pulidas y tener un timing más acertado.

Como puntos de mejora, me gustaría que, si en un futuro el juego tuviera más recursos y tiempo de desarrollo, se pudieran añadir más robots y escenarios para enriquecer la experiencia. Además, sería interesante incorporar un ataque especial para cada robot, con animaciones únicas que le den un toque más distintivo a cada uno. También me gustaría mejorar cada animación, tanto en términos de fluidez como de timing para que las transiciones entre ellas se perciban más naturales y realistas.

En resumen, este proyecto me ha permitido aprender y aplicar diversos conocimientos en modelado 3D, animación, programación en Unity y diseño de interfaces, lo cual me ha proporcionado una base sólida para futuros proyectos en el desarrollo de videojuegos.

Recursos Utilizados

A continuación, se detalla la lista de recursos utilizados en el desarrollo de Robotic Fighters, con sus respectivos enlaces:

Controles del juego

Controles para Archie V 1.34
  • Avanzar: Letra D
  • Retroceder: Letra A
  • Atacar: Letra F
  • Defenderse: Letra R
Controles para Robotydus
  • Avanzar: Letra L
  • Retroceder: Letra J
  • Atacar: Letra H
  • Defenderse: Letra Y
Controles comunes
  • Pausar el juego: Tecla Espacio. Al pulsarla, el juego se detiene, y al volver a pulsarla, el juego se reanuda con un margen de 1 segundo.

Enlace al juego en Simmer.io:

https://simmer.io/@daniTydus/fighting-robots

Debat0el PEC 05 – Media para videojuegos

No hi ha comentaris.

Publicat per

Joc de lluites amb les animacions i models fets als curs

Publicat per

Joc de lluites amb les animacions i models fets als curs

Introducció En aquest curs, s’ha vist pas per pas com construir un model 3D de dos robots i s’ha creat desde zero…
Introducció En aquest curs, s’ha vist pas per pas com construir un model 3D de dos robots i s’ha…

Introducció

En aquest curs, s’ha vist pas per pas com construir un model 3D de dos robots i s’ha creat desde zero les seves animacions corresponents (a tenir en compte: atac, defensa, moviment, mort i estàtic). En aquesta última entrega es desenvouparà un joc de lluites incorporant aquests elements.

Joc pujat al drive: https://drive.google.com/file/d/1-3Y7mxidDEZgoWxsRzLo29FpTkHCK-fn/view?usp=drive_link

Correccions en les animacions

Els primers problemes van venir en exportar les animacions a Unity ja que el motor gràfic necessita d’unes certes correcions per funcionar tal com es veu a Maya. A continuació, s’enumeren les difcultats trobades en aquest apartat

-Problema amb el rig del peu: Desafortunadament, es va obsevar que, al importar l’animació del robot 2 (el blanc) a Unity, el peu esquerre no estava correctament conectat a seu òs superior (en aquest cas lower leg). Això provocava que Unity no llegís bé l’estructura òssea i no pogués desenvolupar un rig humanoide correcte. Es va decidir tornar a Maya, desencaixar el peu i tornar-ho a connectar. Això provoca que aquest peu, si un es fixa molt, faci un moviment diferent del seu parell però no s’aprecia gaire. En la següent figura, s’observa com quedava el peu al desencaixar-lo.

-Posició del robot 1 en l’animació: Un altre problema que va sorgir durant els primers compassos va ser que Unity interpretava incorrectament la posició incial de l’animació, produint un gir de casi 45 graus (provocant que el robot ataqués en diagonal en comptes de recte). Això es va solucionar canviant l’0pció de Root Transforn Rotation de l’animació a Original en comptes de Body Orientation.

En les següents figures s’aprecia el canvi d’orientació. La figura dreta és la correcta.

-Problema típic del model movent-se cap adalt: Per últim, un problema comú que va sorgir va ser que el model, una vegada exportat, es movia cap adalt. Això es va corregir, canviant l’opció a Center of Mass en el Root Transfrom Position (Y).

Controlador d’animacions

El controlador d’animacions pels dos robots va acabar sent de la següent manera:

L’animació d’entrada es l’anomenada Idle (repòs) i per tant, només encendre el programa els robots aniran cap aquest estat. Des d’aquí hi ha un paràmetre float, anomenat Run, que incialment es zero però que quan els robots es moguin variará. Aquest paràmetre controlarà l’animació Movement i l’activarà quan Run sigui diferent a zero i la desactivarà quan torni al seu valor original.

Per les animacions Block, Death i Attack s’ha decidit que s’activin des de Any State per poder fer els canvis d’animació instantàneament sense passar per Idle. Els paràmetres són de tipus Trigger i, quan s’apreta la tecla corresponent, s’activa l’estat especificat. Per impedir que les animacions es superposin, es controla la duració de les animacions mitjançant codi de la següent manera:

El mètode GetCurrentAnimatorStateInfo() permet comprobar si l’animació entre cometes está activa o no. Si una animació está activa no es permetrá començar d’altres. El mètode Block() no té aquesta restricció (intencionalment) per permetre bloquejar de forma ràpida, interrumpent altres animacions si es necessari. El mètode Death(), inclou la destrucció del codi i per tant no pot ser interrumput.

A mode d’exemple s’incorpora el mètode Attack():

On es pot veure que s’invoca a un mètode (amb Invoke) que provocará l’activació del Collider de l’espasa per tal de controlar quan els cops d’un robot impacten contra l’altre. Com que les animacions que es van exportar eren ReadOnly (no es va poder fer d’una altra manera) no es va poder utilitzar l’Animation de Unity per tal d’especificar en quin moment de l’animació acitvar el Collider dels cops. Alternativament, es va mesurar el temps en el que l’espasa estava recta i es va escruire en el codi, directament, en quin moment passava això. Tambés es pot veure en el codi que es para el so del moviment del robot i s’activa el so de l’espasa.

Elements de Gameplay afegits

Aquí s’enumeren elements de joc que s’han pogut afegir

-S’ha pogut realitzar un menu inicial, que permet començar nova partida i sortir del programa.

-S’ha implementat una barra de vida i es té en compte que els cops bloquejats no resten vida. Quan la vidda arriba a zero, el robot mor i surt un menú on s’indica quin robot ha guanyat, un botó per tornar a jugar i un botó per sortir.

-L’espasa emet soroll a l’atacar. També hi ha so pels cops bloquejats i els cops que resten vida. El robot emet so quan es mou i també hi ha música de fons.

Valoració de futur
Millores 
Hi ha força millores que es poden realitzar sense ampliar el propi programa:
-Implementar un gradient a la barra de vida (verd, groc o vermell depenent de la vida sobrant)
-Encara que GetCurrentAnimatorStateInfo() permet que no es superposin les animacions, si es tecleja molt ràpid hi ha un petit staggering. Una cosa semblant passa amb el so, al teclejar vàries tecles al mateix temps, a vegades, el so del moviment del robot no es sent. Investigar per tal que això no passi.
-L’atac del robot 2 no sembla que impacti bé contra el robot 1. Intentar arreglar-ho d’alguna manera.
-Implementar un timer per mostrar un compte enrere abans de començar a lluitar
-Crear un menú i una  taula pel so.
-Retardar el temps al rebre un KO.
Ampliació
El joc es pot ampliar, implementat elements típics dels jocs de lluita, com poden ser:
-Ampliar la selecció de personatges disponibles per batallar.
-Crear diferents movesets per cada personatge i ampliar el llistat d’atacs que poden realitzar els robots,
-Implementar combos de tecles per realitzar atacs més espectaculars
-Permetre saltar i atacar a l’aire.
Es podrien aplicar altres aspectes més avançats però es creu que els primers passos seríen aquests.
Plataforma
Es creu que els jocs d’aquests gènere tenen sortida sobretot en consola (tipus PlayStation y XBox) ya que el controlador es ideal en aquestes situacions. Millorat i ampliat es creu que s’hauria de publicar primordialment en aquestes plataformes.
Assets

Els assets de tercers utilitzats són els següents:

So:

RibhavAgrawal Pixabay (block)

Mixkit.co (hit and sword sound)

jeussfl2009 (backgorund)

DavidDumaisAudio (robot steps)

Models 3D:

MadMedicSoft- Russian buildings pack
Kobra Game Studios-Storage Building
EVPO Games-Modular Lowpoly Streets

 

Debat0el Joc de lluites amb les animacions i models fets als curs

No hi ha comentaris.

Publicat per

R5 – Integración de assets con Unity

Publicat per

R5 – Integración de assets con Unity

Introducción En esta última práctica de la asignatura de Media para Videojuegos debemos hacer un pseudo-juego de lucha con los personajes que…
Introducción En esta última práctica de la asignatura de Media para Videojuegos debemos hacer un pseudo-juego de lucha con…

Introducción

En esta última práctica de la asignatura de Media para Videojuegos debemos hacer un pseudo-juego de lucha con los personajes que hemos realizado durante el curso.

Desarrollo

Mi intención es hacer una simulación muy simple del videojuego Pacific Rim: The Game en 2.5D (es decir, con los personajes moviéndose únicamente en el eje Y y X aunque sea en un entorno 3D).

He recreado un entorno importando diferentes assets gratuitos de la Store (enlances en el apartado de referencias), recreando un mundo post-apocalíptico con ciudades hundidas en el océano como fondo. También he incluido un skybox de cielo nocturno para dar más realismo y un ambiente oscuro.

He incluido los paquetes “Animation Rigging” y “Cinemachine” para controlar mejor los movimientos de los personajes y el seguimiento de la cámara.

Pare empezar con la programación y las animaciones, he añadido componentes de física a todos los elementos. El robot tiene un RigidBody con un Capsule Collider y, por otro lado, el suelo tiene un Box Collider. Importante bloquear la rotación y el movimiento del eje Z del rigid body con constraints.

El script de robot jugador lo he ido escribiendo y mejorando con ChatGPT. Básicamente, consiste en una máquina de estados que transiciona según el input de las teclas y que llama a las animaciones adecuadas según cada estado. Este acercamiento me permitirá añadir la lógica de juego sencillamente después.

He creado este animator controller donde la animación por defecto es la de Idle. Ésta puede transicionar bidireccionalmente con la de Walking dependiendo del parámetro de velocidad. Después las demás animaciones pueden partir desde cualquier estado y al acabar vuelven a Idle (excepto Defeat, que termina la máquina de estados). CORRECCIÓN: hay que eliminar la transición a exit, ya que si no la animación de Defeat se queda en Loop al ser derrotado.

El primer “problema” que me he encontrado es que las animaciones no transicionaban a no ser que hubiera acabado el clip. Por suerte esto tiene fácil arreglo: solo hace falta desmarcar la casilla “Has Exit Time” en la transición de las animaciones correspondientes.

Algo similar sucedía cuando se mantenía presionada una tecla, ya que la animación se reiniciaba constantemente. Esto lo he podido solucionar por código haciendo que no se pueda transicionar entre estados hasta que las animaciones de ataque o defensa hayan finalizado.

He escrito por código que cuando el personaje camine hacia el lado opuesto al que empieza se invierta la animación ( de speed 1 a speed -1) para que haga el efecto de caminar hacia atrás con el parámetro WalkingSpeed.

Al aplicar lo realizado en el V1 al V2 me he encontrado algún que otro inconveniente. Primero, la animación de Walking por alguna razón se exportó con 40 frames congelados así que la he tenido que recortar. Por suerte, desde el inspector de Unity esto se puede hacer fácilmente. Con este robot no se siente tan bien el invertir la animación para hacer que camina hacia atrás, pero todos los parámetros son correctos, así que debe ser un problema artístico de la práctica anterior. CORRECCIÓN: resulta que el problema es que al girar el robot la pierna que comienza a caminar se debía invertir. Es decir, haciendo un flip del personaje se ha solucionado.

He añadido dos barreras invisibles a los laterales para que los personajes no puedan salirse de cámara. Finalmente no he utilizado Cinemachine para hacer seguimiento de los personajes.

En este punto he añadido dos BoxCollider as Trigger delante de los robots para activar la zona de puño cuando se ejecuta la animación. También he hecho que tengan un indicador de vida (100 puntos) y que si se están defendiendo que no puedan sufrir daño. Como extra, he añadido un sistema de partículas que lance chispas cuando impactan para dar más feedback. Para que quede en escrito, este juego no pretende estar balanceado ni dar una experiencia de combate justa.

Para los SFX he utilizado diversos audios de PixaBay y los he reproducido en momentos concretos del script. Los SFX que se reproducen son: Attack, Defeat, Impact y Walking.

Para la lógica del menú he creado un GameManager con una FSM para los diferentes estados del juego: GameStart, GameRunning, GamePaused, GameWinnerV1, GameWinnerV2. Los menús son gameObjects con botones, ya que me parecía mucho más sencillo hacerlo así que crear una nueva escena para el menú principal, etc. También he hecho que reproduzca música en loop y algunos efectos de comenzar y terminar partida.

Finalmente, para exportar con WebGL he instalado el paquete WebGL publisher y he creado una build en local para debuggear. Al principio el asset de la store de Vrbn Studios me ha dado algunos problemas, pero he eliminado del proyecto todos los scripts relacionados (ya que aportaban funcionalidades que no necesitaba para los edificios). De esta manera ya compilaba (con varias advertencias en la consola, pero son ingorables).

Ahora llega el momento que más me temía, que es que el proyecto parece ser demasiado grande para ser exportado en WebGL. Tras una tarde de prueba y error, conseguí exportarlo correctamente importando todas las partes del proyecto de una en una a una versión anterior de Unity y comprimiendo los archivos. Aun así, los edificios seguían dando problemas, así que opté por la vía rápida: hacer un pre-renderizado y ponerlo como textura plana en el fondo. Este método es muy efectivo en cuanto a rendimiento, y más para una versión web. Además, con los efectos de desenfoque y demás no se nota tanto. Debería haber pensado en utilizarlo antes, la verdad.

Edificios con canal Alpha aplicado.

Resultado final exportado con WebGL Publisher.

Juego en WebGL

Mecha Battle! – Unity Play

Apunte: he intentado incrustar el proyecto con un iframe tanto de Itch.io como de Unity Play, pero el WordPress de este servicio no lo permite.

El repositorio de todo el proyecto se puede encontrar públicamente en GitLab: https://gitlab.com/jongompal/r5-mecha-battle.git

Visión de futuro

Lo cierto es que el resultado es sencillo, pero estoy muy contento con el empaque final y cómo se integran los modelos con el entorno. Evidentemente, se podría expandir muchísimo más con más animaciones, personajes, entornos, más tipos de ataque y hacer un sistema de combate más atractivo.

Lo cierto es que me ha atraído mucho la idea de hacer un combate más estratégico y lento en lugar de uno en el que cada milisegundo cuenta y los reflejos rápidos son la joya de la corona. Creo que es una perspectiva del género inexplorada y que empaca muy bien con la estética de Mechas que he querido transmitir.

En el hipotético caso de que siguiera en un futuro apostando por este concepto, claramente haría un rediseño total, pensando muchísimo más en las mecánicas y recreando el apartado artístico en consecuencia (aunque no ha estado mal investigar el camino inverso por una vez).

Para terminar, decir que el punto que me falla siguen siendo las animaciones. Son el apartado que claramente requieren más trabajo y que se nota más antinatural. Por ello, en un futuro proyecto de este estilo buscaría cómo integrar aún más las herramientas del motor con las externas e incluso investigar si sería posible crear animaciones procedurales que se adaptaran al entorno.

Referencias

Debat0el R5 – Integración de assets con Unity

No hi ha comentaris.