Publicado por

The sky is the limit

Publicado por

The sky is the limit

Sea of Clouds v2.0 «Sea of Clouds» es el nombre de mi prototipo para la tercera Práctica de Evaluación Continua (PEC3) y…
Sea of Clouds v2.0 «Sea of Clouds» es el nombre de mi prototipo para la tercera Práctica de Evaluación…

Sea of Clouds v2.0

«Sea of Clouds» es el nombre de mi prototipo para la tercera Práctica de Evaluación Continua (PEC3) y para la Práctica Final (FP) de la asignatura Programación de Videojuegos 3D del Máster Universitario en Diseño y Programación de Videojuegos de la UOC.

El objetivo de la práctica era desarrollar un juego de plataformas en tercera persona utilizando los conocimientos adquiridos en el estudio del tercer módulo de la asignatura y realizando investigación por cuenta propia. La práctica final, además, requería ampliar el juego añadiendo mejoras y nuevas características.

Novedades de la práctica final

Como la práctica final es una extensión de la práctica anterior, a continuación se detallan los cambios y mejoras que se han llevado a cabo para poder determinar de manera fácil las diferencias entre ambas:

  • Se ha añadido un submenú de opciones y una pantalla de créditos al menú principal
  • Se ha rehecho completamente la escena de juego
  • Se ha añadido un vehículo controlable por el jugador
  • Se ha añadido vehículos con movimiento autónomo
  • Se ha añadido un nuevo comportamiento para todos los tipos de personaje que hace que exploten si son arrollados por un vehículo
  • Se ha corregido los errores detectados en la práctica anterior

La práctica también ha servido para corregir los errores detectados en la práctica anterior:

  • Los sistemas de partículas asociados a los personajes y objetos ya no se están renderizando por detrás de los elementos del terreno.
  • Las olas del agua que rodea la isla ya no se reflejan en los personajes y enemigos repartidos por la escena.
  • Todos los personajes están completamente sonorizados.
  • No es posible caer a las zonas de muerte.

Además, al final se ha optado por prescindir de la munición y de los diferentes tipos de armas, debido principalmente a la falta de tiempo, pero también porque el diseño del mundo ludoficcional no lo ha contemplado desde el principio y su inclusión hubiera sido forzada. En cualquier caso, tanto el cambio de arma como la gestión de la munición son conceptos que se han aplicado anteriormente en otras prácticas.

Tampoco se ha aplicado el sistema de control de tráfico por motivos similares, dado que la existencia de semáforos u otras señales de tráfico no acaba de encajar con la atmósfera del juego.

Vídeo explicativo (PF)

Vídeo explicativo (PEC3)

Repositorio en GitLab

UOC – M7.458 – PEC3 en GitLab

Versión de Unity

La versión de Unity utilizada para el desarrollo de la práctica es la 2021.3.19f1 LTS.

El orden de las escenas está definido en los builds settings del proyecto, siendo Assets/Scenes/Opening.scene la primera escena que debe cargarse.

Cómo jugar

El objetivo del juego es conseguir tres llaves mientras se esquiva a hordas de monstruos. Una vez conseguidas las tres llaves, aparece un enemigo mayor cuya derrota es el objetivo final del juego.

El control se lleva a cabo mediante teclado y ratón, aunque también está preparado para ser compatible con gamepad:

  • Las letras WASD mueven al personaje.
  • El Espacio hace que el personaje salte.
  • La tecla Mayúsculas izquierda sirve para que el personaje esprinte.
  • El botón derecho del ratón apunta el arco.
  • El botón izquierdo del ratón dispara el arco.
  • El botón central del ratón realiza un ataque cuerpo a cuerpo.
  • La tecla E sirve para entrar y salir del vehículo.
  • La tecla Escape sirve para pausar el juego y abrir el menú de pausa.

Desarrollo

De cara a completar el desarrollo de ambas prácticas, se han llevado a cabo las siguientes tareas obligatorias y opcionales, además de incluir algunos extras que se han ido añadiendo a lo largo del desarrollo.

Tareas obligatorias

  • ✅ Se ha creado un escenario que dispone de zonas urbanas y vegetales.
  • ✅ El personaje dispone de un arma a distancia que le permite disparar hacia delante.
  • ✅ El personaje está completamente animado.
  • ✅❗La salud y la armadura se muestran constantemente en el HUD, pero no la munición.
  • ✅ Los enemigos pasean por la ciudad y atacan al enemigo cuando está cerca.
  • ✅ Los enemigos están completamente animados.
  • ✅ Se dispara un sistema de partículas cuando un personaje (jugador o no) recibe daño o muere.
  • ✅❗Hay objetos de salud y armadura repartidos por el escenario, pero no de munición.
  • ✅ El juego dispone de una pantalla de juego terminado que permite reiniciar la partida.
  • ✅ Los enemigos se mueven entre puntos aleatorios y corren hacia el jugador al detectarlo.
  • ✅ Hay personajes de carácter neutral paseando por el escenario.
  • ✅ Los personajes de carácter neutral huyen de los enemigos.
  • ✅ Se ha creado un menú principal que, además de empezar la partida, permite configurar varios parámetros del juego: volumen general, velocidad del juego y dificultad del juego.
  • ✅ Hay vehículos que se mueven por el escenario.
  • ✅ El jugador puede entrar en los vehículos y desplazarse con ellos.

Tareas opcionales

  • ✅ El juego dispone de al menos un puzle que requiere saltar para progresar.
  • ❌ Se han añadido diferentes tipos de armas.
  • ❌ Las armas están repartidas por el escenario.
  • ✅ El juego está totalmente sonificado.
  • ✅ Se han añadido diferentes tipos de enemigos.
  • ✅ Es posible apuntar al disparar.
  • ✅ El juego dispone de al menos un puzle que requiere obtener llaves para progresar.
  • ✅ El jugador tiene un arma cuerpo a cuerpo.
  • ✅ Los enemigos pueden dejar objetos al morir.
  • ✅ Los enemigos aparecen en varias fuentes del escenario de manera incremental.
  • ✅ Se ha utilizado el componente animation rigging para que el personaje mire hacia los objetos cercanos.
  • ✅ Se ha implementado la iluminación global.
  • ✅ Los personajes de carácter neutral se convierten en enemigos al morir a manos de un enemigo.
  • ❌ Hay un sistema de control del tráfico que limita el movimiento autónomo de los vehículos.
  • ✅ Los NPC y los enemigos explotan si el jugador los atropella a gran velocidad.

Características principales

A continuación se detallan las características más importantes del desarrollo de la práctica.

La escena de juego (PEC3 y PF)

La escena del juego se ha rehecho completamente para la práctica final. Ahora, el escenario consiste en cuatro islas flotantes en un mar de nubes.

  • La isla principal, Gada, situada al suroeste, consiste en una aldea con varios edificios y zonas vegetales. Hay varios NPC repartidos por ella y enemigos que empiezan a aparecer la primera vez que se vuelve a ella. Uno de los enemigos que aparece posee una de las llaves.
  • La isla del sureste, Stria, contiene un templo en el que se encuentra una de las llaves. Para llegar a ella, es necesario resolver un puzle que consiste en abrir varias puertas pisando diferentes interruptores y llegado a una zona inaccesible mediante plataformas.
  • La isla del norte, Voni, contiene un bosque en el que se encuentra la última de las llaves. Hay varios enemigos fuertes repartidos por ella que conviene evitar.
  • Finalmente, la isla del centro, Vanglasaar, contiene una estructura en la que se encuentra el jefe final del juego. Para llegar a él, es necesario haber recogido previamente las tres llaves.

Apuntado, disparo y ataque cuerpo a cuerpo (PEC3)

Para poder disparar el arco, es necesario cargarlo primero. Al hacerlo, el juego bloquea el movimiento del jugador para que no pueda girar con las flechas (sólo desplazarse lateralmente) y enfoca la visión utilizando una segunda cámara. Además, permite apuntar de manera libre a cualquier punto de la escena.

El HUD (PEC3 y PF)

Como en el caso de la práctica anterior, la interfaz de usuario muestra en todo momento la salud y el escudo del jugador, así como las llaves que ha conseguido. También muestra la cruceta y los mensajes enviados por el juego.

Tipos de personaje (PEC3)

A efectos de gestionar de manera transversal las características comunes entre jugador, enemigos y NPC, se ha creado una clase maestra que contiene las propiedades y métodos compartidos y que se apoya en una máquina de estados para manejar el tipo del jugador. Esta aproximación permite, entre otras cosas, poder cambiar fácilmente de tipo a un personaje y se implementa cuando un NPC neutral o aliado se convierte en enemigo al morir. E incluso permitiría al jugador controlar a un NPC o a un enemigo, así como a cualquier otra entidad a la que se extienda la clase.

Se han incluido los tipos siguientes:

  • Player. En este estado, se desactivan las automatizaciones y se activan el character controller y el resto de componentes necesarios para poder jugar.
  • Enemy. En este estado, el personaje deambula por la escena y ataca al jugador y a los NPC neutrales y aliados cuando pasan cerca.
  • Boss. En este estado, el personaje se comporta igual que un enemigo, pero añade la lógica de finalización del juego al derrotarlo.
  • Neutral. En este estado, el personaje deambula por la escena y huye cuando un enemigo pasa cerca.
  • Ally. En este estado, el personaje deambula por la escena y ataca a los enemigos que pasan cerca.

En el caso de los enemigos y los NPC (neutrales y aliados) se han añadido varios tipos con modelos y características diferentes (velocidad, daño, resistencia, etc.).

Objetos y llaves (PEC3)

Como en la práctica anterior, el juego incluye tanto objetos de curación como llaves repartidas por el escenario o dejadas por los enemigos al morir.

Vehículos (PF)

La principal novedad añadida en la práctica final es la inclusión de vehículos. En concreto, se han añadido una nave que permite al jugador desplazarse entre las islas flotantes y que tiene dos estados posibles, ya que, como en el caso de los jugadores, se apoya en una máquina de estados para gestionar su comportamiento y permite cambiar de tipo en tiempo de ejecución:

  • Human. En este estado, el jugador puede controlar la nave y atropellar a los enemigos flotantes.
  • AI. En este estado, la nave se desplaza de manera autónoma en rutas predeterminadas.

El jugador sólo puede subir y bajar del vehículo desde el muelle de cada isla.

Animaciones y rigging (PEC3)

Todos los personajes están completamente disponen de animaciones para todas las posibles combinaciones, aunque no las utilicen, precisamente por la posibilidad de que cualquiera de ellos cambie de tipo. Además, se usan capas y animation events para poder controlar de manera fácil desde el código los momentos en los que se produce algún factor de interés en la reproducción de la animación.

También se ha implementado el animation rigging para el jugador, principalmente para hacer que tanto la cabeza como el torso del personaje miren suavemente hacia los objetos que tienen cerca, pero también para asegurar que el arco mira en todo momento a la posición correcta cuando se está apuntando.

Sistemas de partículas (PEC3)

Se han implementado partículas para un gran número de acciones: al ser golpeado, al morir, al recuperar salud, al convertirse en enemigo, etc.

Inteligencia artificial (PEC3)

Para implementar los objetivos relacionados con la inteligencia artificial, se utiliza una mezcla de NavMesh y de detección de colisiones. Todos los personajes disponen de tres maneras de detectar colisiones: con el collider incorporado al modelo a través del player controller o del capsule collider, con un trigger en un una esfera con un radio de cuatro metros (esfera interna) y por otra con un radio de siete metros (esfera externa). Además, disponen del componente NavMeshAgent para poder navegar por el terreno de manera autómoma.

Teniendo eso en cuenta, el flujo de un personaje normalmente es:

  1. En su estado inicial, a falta de objetivos, el personaje deambula por el escenario desplazándose entre puntos aleatorios con NavMesh.
  2. Cuando otro personaje entra en su esfera interna, lo añade a una lista de objetivos que utiliza para escapar (NPC neutral) o para saber a qué atacar (NPC Aliado, Enemigo y Enemigo final).
  3. Además, si el personaje es atacado por cualquier otro personaje, lo define directamente como objetivo forzado, independientemente de si está o no dentro del rango de detección.
  4. Mientras la lista contiene objetivos, el personaje comprueba qué personaje es el que está más cerca y en base a ello fija un punto de origen del cuál huir (NPC neutral) o fija un punto de destino para atacar (NPC Aliado, Enemigo y Enemigo final).
  5. Si el personaje alcanza a su objetivo, ataca siempre y cuando no exista una determinada distancia entre ambos.
  6. Cuando un objetivo sale de la esfera externa, el personaje lo elimina de la lista de personajes y deja de perseguirlo.
  7. Si la lista de objetivos se vacía, el personaje vuelve a deambular por el escenario.

 

Iluminación global (PEC3)

Finalmente, se ha hecho uso de la iluminación global y el baking para optimizar el uso de la iluminación en la escena de juego y mejorar el rendimiento general.

 

Créditos

Paquetes completos

Fuentes

Música

Shaders

Sonidos

Referencias

C# – General

Unity – General

Animaciones – General

Animaciones – Interrupción

Animaciones – Rigging

Cinemachine

Iluminación

NavMesh

Shaders

Debate1en The sky is the limit

  1. Anna Zango Palau says:

    Salva, que pasada!! Me encantan las islas flotantes, que idea tan genial! Y el sistema de transporte con navecitas encaja tan bien con el diseño del escenario. Vaya, como siempre, un trabajo espectacular :D

Publicado por

As above, so below

Publicado por

As above, so below

Sea of Clouds «Sea of Clouds»es el nombre de mi prototipo para la tercera Práctica de Evaluación Continua (PEC3) de la asignatura…
Sea of Clouds «Sea of Clouds»es el nombre de mi prototipo para la tercera Práctica de Evaluación Continua (PEC3)…

Sea of Clouds

«Sea of Clouds»es el nombre de mi prototipo para la tercera Práctica de Evaluación Continua (PEC3) de la asignatura Programación de Videojuegos 3D del Máster Universitario en Diseño y Programación de Videojuegos de la UOC.

El objetivo de la práctica era desarrollar un juego de plataformas en tercera persona utilizando los conocimientos adquiridos en el estudio del primer módulo de la asignatura y realizando investigación por cuenta propia.

Vídeo explicativo

Repositorio en GitLab

UOC – M7.458 – PEC3 en GitLab

Versión de Unity

La versión de Unity utilizada para el desarrollo de la práctica es la 2021.3.19f1 LTS.

El orden de las escenas está definido en los builds settings del proyecto, siendo Assets/Scenes/Opening.scene la primera escena que debe cargarse.

Cómo jugar

El objetivo del juego es conseguir tres llaves mientras se esquiva a hordas de monstruos. Una vez conseguidas las tres llaves, aparece un enemigo mayor cuya derrota es el objetivo final del juego.

El control se lleva a cabo mediante teclado y ratón, aunque también está preparado para ser compatible con gamepad:

  • Las letras WASD mueven al personaje.
  • El Espacio hace que el personaje salte.
  • La tecla Mayúsculas izquierda sirve para que el personaje esprinte.
  • El botón derecho del ratón apunta el arco.
  • El botón izquierdo del ratón dispara el arco.
  • El botón central del ratón realiza un ataque cuerpo a cuerpo.
  • La tecla Escape sirve para pausar el juego y abrir el menú de pausa.

Desarrollo

De cara a completar el desarrollo de la práctica, se han llevado a cabo las siguientes tareas obligatorias y opcionales, además de incluir algunos extras que se han ido añadiendo a lo largo del desarrollo.

  • ✅ (Obligatorio) Se ha creado un escenario que consiste en un pueblo y una zona natural.
  • ✅ (Obligatorio) El personaje dispone de un arma a distancia que le permite disparar hacia delante.
  • ✅ (Obligatorio) El personaje está completamente animado.
  • ✅❗ (Obligatorio) La salud y la armadura se muestran constantemente en el HUD. La munición, no (ver explicación más adelante).
  • ✅ (Obligatorio) Los enemigos pasean por la ciudad y atacan al enemigo cuando está cerca.
  • ✅ (Obligatorio) Los enemigos están completamente animados.
  • ✅ (Obligatorio) Se dispara un sistema de partículas cuando un personaje (jugador o no) recibe daño o muere.
  • ✅❗ (Obligatorio) Hay objetos de salud y armadura repartidos por el escenario. Munición, no (ver explicación más adelante).
  • ✅ (Obligatorio) El juego dispone de una pantalla de juego terminado que permite reiniciar la partida.
  • ✅ (Opcional) El juego dispone de al menos un puzle que requiere saltar para progresar.
  • ❌ (Opcional) No se han añadido otros tipos de arma (ver explicación más adelante).
  • ✅ (Opcional) El juego está totalmente sonificado.
  • ✅ (Opcional) Se han añadido diferentes tipos de enemigos.
  • ✅ (Opcional) Es posible apuntar al disparar.
  • ✅ (Opcional) El juego dispone de al menos un puzle que requiere obtener llaves para progresar.
  • ✅ (Opcional) El jugador tiene un arma cuerpo a cuerpo.
  • ✅ (Opcional) Los enemigos pueden dejar objetos al morir.
  • ✅ (Opcional) Los enemigos aparecen en varias fuentes del escenario de manera incremental.
  • ✅ (Opcional) Se ha utilizado el componente animation rigging para que el personaje mire hacia los objetos cercanos.
  • ✅ (Opcional) Se ha implementado la iluminación global

Todos los objetivos que no se han cumplido o se han cumplido parcialmente están relacionados con la inclusión de nuevas armas o con la munición y es porque el proyecto se ha considerado como un todo que incluye los objetivos de esta práctica y de la siguiente y, por un motivo puramente arquitectónico y de optimización del proceso de desarrollo, se ha optado por implementar primero las características con mayor transversalidad y por posponer aquellas que son fácilmente incorporables como extras. En concreto, se ha priorizado la implementación de la IA en los personajes, afrontando las siguientes tareas de la próxima práctica:

  • ✅ (Obligatorio) Los enemigos se mueven entre puntos aleatorios y corren hacia el jugador al detectarlo.
  • ✅ (Obligatorio) Hay personajes de carácter neutral paseando por el escenario.
  • ✅ (Obligatorio) Los personajes de carácter neutral huyen de los enemigos.
  • ✅ (Opcional) Los personajes de carácter neutral se convierten en enemigos al morir a manos de un enemigo.

La escena de juego

La escena de juego no es propia. Ha sido extraída del paquete gratuito RPG Poly Pack – Lite de la Unity Assets Store y adaptado según lo requerido por la práctica. Entre otras adaptaciones, se han aplicado shaders a todas las texturas, tanto del escenario como de los personajes y los objetos, aplicando cel shading y un delineado grueso para dar un aspecto de dibujo animado.

Como tal, la escena dispone de una pequeña aldea en la que se desarrolla el juego y un entorno forestal sin mucho más que unos pocos objetos y enemigos repartidos, pero que ofrece la ventaja de poder huir de los enemigos si las cosas se tuercen.

Apuntado, disparo y ataque cuerpo a cuerpo

Para poder disparar el arco, es necesario cargarlo primero. Al hacerlo, el juego bloquea el movimiento del jugador para que no pueda girar con las flechas (sólo desplazarse lateralmente) y enfoca la visión utilizando una segunda cámara. Además, permite apuntar de manera libre a cualquier punto de la escena.

El HUD

Como en el caso de la práctica anterior, la interfaz de usuario muestra en todo momento la salud y el escudo del jugador, así como las llaves que ha conseguido. También muestra la cruceta y los mensajes enviados por el juego.

Tipos de personaje

A efectos de gestionar de manera transversal las características comunes entre jugador, enemigos y NPC, se ha creado una clase maestra que contiene las propiedades y métodos compartidos y que se apoya en una máquina de estados para manejar el tipo del jugador. Esta aproximación permite, entre otras cosas, poder cambiar fácilmente de tipo a un personaje y se implementa cuando un NPC neutral o aliado se convierte en enemigo al morir. E incluso permitiría al jugador controlar a un NPC o a un enemigo, así como a cualquier otra entidad a la que se extienda la clase.

Se han incluido los tipos siguientes:

  • Player. En este estado, se desactivan las automatizaciones y se activan el character controller y el resto de componentes necesarios para poder jugar.
  • Enemy. En este estado, el personaje deambula por la escena y ataca al jugador y a los NPC neutrales y aliados cuando pasan cerca.
  • Boss. En este estado, el personaje se comporta igual que un enemigo, pero añade la lógica de finalización del juego al derrotarlo.
  • Neutral. En este estado, el personaje deambula por la escena y huye cuando un enemigo pasa cerca.
  • Ally. En este estado, el personaje deambula por la escena y ataca a los enemigos que pasan cerca.

En el caso de los enemigos y los NPC (neutrales y aliados) se han añadido varios tipos con modelos y características diferentes (velocidad, daño, resistencia, etc.).

Objetos y llaves

Como en la práctica anterior, el juego incluye tanto objetos de curación como llaves repartidas por el escenario o dejadas por los enemigos al morir.

Animaciones y rigging

Todos los personajes están completamente disponen de animaciones para todas las posibles combinaciones, aunque no las utilicen, precisamente por la posibilidad de que cualquiera de ellos cambie de tipo. Además, se usan capas y animation events para poder controlar de manera fácil desde el código los momentos en los que se produce algún factor de interés en la reproducción de la animación.

También se ha implementado el animation rigging para el jugador, principalmente para hacer que tanto la cabeza como el torso del personaje miren suavemente hacia los objetos que tienen cerca, pero también para asegurar que el arco mira en todo momento a la posición correcta cuando se está apuntando.

Sistemas de partículas

Se han implementado partículas para un gran número de acciones: al ser golpeado, al morir, al recuperar salud, al convertirse en enemigo, etc.

Inteligencia artificial

Para implementar los objetivos relacionados con la inteligencia artificial, se utiliza una mezcla de NavMesh y de detección de colisiones. Todos los personajes disponen de tres maneras de detectar colisiones: con el collider incorporado al modelo a través del player controller o del capsule collider, con un trigger en un una esfera con un radio de cuatro metros (esfera interna) y por otra con un radio de siete metros (esfera externa). Además, disponen del componente NavMeshAgent para poder navegar por el terreno de manera autómoma.

Teniendo eso en cuenta, el flujo de un personaje normalmente es:

  1. En su estado inicial, a falta de objetivos, el personaje deambula por el escenario desplazándose entre puntos aleatorios con NavMesh.
  2. Cuando otro personaje entra en su esfera interna, lo añade a una lista de objetivos que utiliza para escapar (NPC neutral) o para saber a qué atacar (NPC Aliado, Enemigo y Enemigo final).
  3. Además, si el personaje es atacado por cualquier otro personaje, lo define directamente como objetivo forzado, independientemente de si está o no dentro del rango de detección.
  4. Mientras la lista contiene objetivos, el personaje comprueba qué personaje es el que está más cerca y en base a ello fija un punto de origen del cuál huir (NPC neutral) o fija un punto de destino para atacar (NPC Aliado, Enemigo y Enemigo final).
  5. Si el personaje alcanza a su objetivo, ataca siempre y cuando no exista una determinada distancia entre ambos.
  6. Cuando un objetivo sale de la esfera externa, el personaje lo elimina de la lista de personajes y deja de perseguirlo.
  7. Si la lista de objetivos se vacía, el personaje vuelve a deambular por el escenario.

 

Iluminación global

Finalmente, se ha hecho uso de la iluminación global y el baking para optimizar el uso de la iluminación en la escena de juego y mejorar el rendimiento general.

 

Problemas conocidos

En el momento de la entrega, se conocen los siguientes problemas:

  • Los sistemas de partículas asociados a los personajes y objetos se están renderizando por detrás de los elementos del terreno.
  • En la misma línea, las olas del agua que rodea la isla se reflejan en los personajes y enemigos repartidos por la escena.
  • Faltan sonidos para varios de los tipos de personajes.
  • El agua que rodea la isla no dispone de zona de muerte, por lo que es salir de la escena si se cae en ella.

Créditos

Paquetes completos

Fuentes

Música

Shaders

Sonidos

Referencias

C# – General

Unity – General

Animaciones – General

Animaciones – Interrupción

Animaciones – Rigging

Cinemachine

Iluminación

NavMesh

Shaders

Debate1en As above, so below

  1. Anna Zango Palau says:

    Como siempre, me encanta tu juego Salva! Me parece que has puesto una outline a los personajes con un Shader para que resalten, no? En plan cartoon, queda genial!! Por cierto, tus enemigos me parecen monísimos jajaja.

    También me parece muy buena idea como has planteado las tareas. Con perspectiva, debería haberlo hecho igual, porque ahora tendré que cambiar cosas de zero porque no las diseñé pensando en lo que haría falta. Muy buena planificación Salva!!

Publicado por

Pedal to the Metal

Publicado por

Pedal to the Metal

HELL to the King «HELL to the King» es el nombre de mi prototipo para la segunda Práctica de Evaluación Continua (PEC2)…
HELL to the King «HELL to the King» es el nombre de mi prototipo para la segunda Práctica de…

HELL to the King

«HELL to the King» es el nombre de mi prototipo para la segunda Práctica de Evaluación Continua (PEC2) de la asignatura Programación de Videojuegos 3D del Máster Universitario en Diseño y Programación de Videojuegos de la UOC.

El objetivo de la práctica era desarrollar un shooter en primera persona utilizando los conocimientos adquiridos en el estudio del primer módulo de la asignatura y realizando investigación por cuenta propia.

Vídeo explicativo

Repositorio en GitLab

UOC – M7.458 – PEC2 en GitLab

Versión de Unity

La versión de Unity utilizada para el desarrollo de la práctica es la 2021.3.19f1 LTS.

El orden de las escenas está definido en los builds settings del proyecto, siendo Assets/Scenes/Opening.scene la primera escena que debe cargarse.

Cómo jugar

El objetivo del juego es llegar hasta el final del nivel, acabando con tantos demonios como sea posible, y haciéndose con las llaves que permiten acceder a varias zonas inaccesibles.

El jugador disponer de varias armas, cada una de ellas con sus propias características,

El control se lleva a cabo mediante teclado y ratón, aunque también está preparado para ser compatible con gamepad:

  • Las letras WASD mueven al personaje.
  • El Espacio hace que el personaje salte.
  • La tecla Mayúsculas izquierda sirve para que el personaje esprinte.
  • El botón izquierdo del ratón dispara.
  • La rueda del ratón permite cambiar el arma activa.
  • La tecla Escape sirve para pausar el juego y abrir el menú de pausa.

Desarrollo

De cara a completar el desarrollo de la práctica, se han llevado a cabo todas las tareas obligatorias y gran parte de las opcionales, aunque por falta de tiempo no ha podido llegarse a todo cuanto se esperaba.

A modo de resumen:

URP

El proyecto de Unity se creó utilizando la plantilla 3D URP para habilitar URP desde el principio y evitar así problemas en caso de querer cambiar la render pipeline en fases posteriores. Pese a ello, debido a que muchos de los assets disponibles de manera gratuita no disponen de versión URP, fue necesario modificar el pipeline en un gran número de materiales para poder aprovechar los recursos. De hecho, un gran número de assets de terceros fue desestimado porque requerían rehacer manualmente sus shaders para poder utilizarlos.

Armas

Para completar tanto el objetivo obligatorio como el opcional, se han creado tres armas diferentes:

Guitarra (pistola)

  • Automática: no
  • Cadencia: baja
  • Daño: equilibrado
  • Retroceso: leve
  • Velocidad de recarga: baja

Bajo (ametralladora)

  • Automática: sí
  • Cadencia: alta
  • Daño: bajo
  • Retroceso: medio
  • Velocidad de recarga: alta

Micrófono (escopeta)

  • Automática: no
  • Cadencia: muy baja
  • Daño: muy alto
  • Retroceso: alto
  • Velocidad de recarga: alta

Enemigos

De igual modo, también se han creado tres tipos de enemigos, utilizando modelos diferentes y atribuyéndoles valores diferentes en la cadencia y en el daño. A uno de ellos, además, se le ha dado la condición de francotirador, que le permite no sólo disparar desde más lejos utilizando una mira de láser, sino también estar continuamente observando al jugador desde el momento en el que entra en esfera de colisión.

El resto de enemigos utilizan la inteligencia artificial mínima que se solicitaba en el enunciado de la práctica, patrullando una zona determinada y buscando al jugador en caso de que pase muy cerca.

Además, todos los enemigos desaparecen lentamente al morir.

Pantallas

Debido a la falta de tiempo, sólo ha podido completarse la pantalla requerida por las tareas obligatorias, que consta de una zona montañosa, una zona urbana (en ruinas) y una zona interior.

Salud, escudo, munición y HUD

El jugador dispone de una barra de escudo que absorbe la mayor cantidad del daño, aunque no evita que una parte se consuma de la salud.

Durante la partida, el jugador puede ver en todo momento la salud, el escudo y la munición del arma equipada en el HUD de la parte superior de la pantalla.

Objetos

El jugador puede encontrar objetos repartidos por la pantalla o dejados por los enemigos al morir que le permiten recuperar salud, escudo y munición.

Puertas y plataformas móviles

En lo referente a las puertas, se ha creado una única puerta con tres comportamientos diferentes posibles:

  • Automática: se abre cuando el jugador pasa cerca.
  • Bloqueada: el jugador necesita una llave para abrirla.
  • Cronometrada: el jugador debe encontrar la placa de presión que la activa y llegar a ella antes de que se cierre.

También se han incorporado plataformas móviles que permiten al jugador desplazarse de manera horizontal y vertical.

Puntos de control y zonas de muerte

Por falta de tiempo, no ha sido posible incorporar puntos de control o zonas de muerte. No obstante, sí se incorporaron en la práctica anterior, por lo que su ejecución hubiera sido la misma.

Música y sonido

Se ha añadido música de fondo tanto a la escena del menú principal como a la de juego y se han añadido sonidos a las diferentes acciones que se suceden: disparar, abrir puertas, recoger objetos, etc.

Escenas

Finalmente, además de la principal, el juego dispone de una única escena adicional, la del menú principal.

Pendientes

En el momento de la entrega, se dejan como pendientes las siguientes tareas e intenciones:

  • Implementación de los puntos de control
  • Implementación de las zonas de muerte
  • No se han podido subir todos los sonidos de los que se disponía, incluyendo voces del personaje y de los enemigos que ya se encontraban grabadas.
  • Retoques finales a los atributos de los enemigos para ajustar la dificultad.

Elecciones de diseño

  • Se ha optado por hacer desaparecer a los enemigos reduciendo su tamaño en vez de haciendo un fade por una cuestión puramente visual. No obstante, el código para hacer el fade está igualmente implementado y se ha conservado en el código a pesar de no estar siendo utilizado.
  • Se ha optado por mostrar el final de juego y de partida directamente en la escena de juego, sin crear una escena adicional, por una cuestión de economía de recursos.

Créditos

Paquetes completos

Fuentes

Imágenes

Sonidos

Referencias

General

Colisiones y raycast

NavMesh

Partículas

Render pipelines

TextMesh Pro

Debate2en Pedal to the Metal

  1. Marc Rost Peñalosa says:

    Por la descripción parece muy divertida tu PEC Salvador!

    El tema de la guitarra como arma y el Rock es muy original :D

Publicado por

Skedaddle, y’all!

Publicado por

Skedaddle, y’all!

Welcome to the countryside! «Welcome to the countryside!» es el nombre de mi prototipo para la primera Práctica de Evaluación Continua (PEC1)…
Welcome to the countryside! «Welcome to the countryside!» es el nombre de mi prototipo para la primera Práctica de…

Welcome to the countryside!

«Welcome to the countryside!» es el nombre de mi prototipo para la primera Práctica de Evaluación Continua (PEC1) de la asignatura Programación de Videojuegos 3D del Máster Universitario en Diseño y Programación de Videojuegos de la UOC.

El objetivo de la práctica era implementar un modo contrarreloj, así como otros añadidos, al tutorial de conducción de coches incorporado en los StandardAssets de Unity, utilizando los conocimientos adquiridos en el estudio del primer módulo de la asignatura y realizando investigación por cuenta propia.

Vídeo explicativo

Versión jugable

Welcome to the Countryside! by Ragart on itch.io

Repositorio en GitLab

UOC – M7.458 – PEC1 en GitLab

Versión de Unity

La versión de Unity utilizada para el desarrollo de la práctica es la 2021.3.19f1 LTS.

Cómo jugar

El objetivo del juego es lograr el mejor tiempo en los circuitos disponibles. El jugador puede elegir entre dos circuitos y cuatro coches diferentes, cada uno con sus características, y puede configurar una carrera de entre 1 y 9 vueltas.

Una vez se haya completado la primera vuelta de un circuito, el jugador podrá competir contra el fantasma de su mejor vuelta. Cuando haya completado una carrera entera, se enfrentará al fantasma de su mejor carrera.

El control se lleva a cabo mediante el teclado:

  • La flecha superior y la tecla W sirven para acelerar.
  • La flecha inferior y la tecla S sirven para frenar y dar marcha atrás.
  • La flecha izquierda y la tecla A sirven para girar a la izquierda.
  • La flecha derecha y la tecla D sirven para girar a la derecha.
  • La barra espaciadora sirve para frenar con el freno de mano.
  • La tecla Control izquierdo sirve para reiniciar desde el último punto de control.
  • La tecla Escape sirve para pausar el juego y abrir el menú de pausa.

Desarrollo

De cara a completar el desarrollo de la práctica, se han llevado a cabo todas las tareas obligatorias y opcionales, además de incluir algunos extras que se han ido añadiendo a lo largo del desarrollo.

En orden de implementación:

  • Se ha completado los proyectos propuestos en el Módulo 1 de la asignatura para familiarizarse con el código existente en los StandardAssets.
  • Se ha llevado a cabo una refactorización parcial del código existente en los StandardAssets, así como una limpieza de los assets en desuso, aunque se ha optado por evitar modificar el código en la medida de lo posible y es posible que se mantengan assets huérfanos en el proyecto por la incertidumbre relativa a su uso actual.
  • Se ha implementado un sistema de checkpoints para asegurar que el jugador completa el circuito completo, pero también para permitirle reiniciar desde el último en caso de errores.

  • Se ha implementado el modo contrarreloj, que permite al jugador competir contra el tiempo y contra sus propios registros, utilizando un coche fantasma y mostrando en todo momento los tiempos en pantalla. Inicialmente, el fantasma se implementó únicamente para la mejor vuelta, pero debido a una relectura de las instrucciones, se ha implementado también para la mejor carrera, de manera que queda así:
    • La primera vez que el jugador corre un circuito, el fantasma no aparece hasta que no completa la primera vuelta. Durante esa primera carrera, el jugador compite contra el fantasma de su mejor vuelta.
    • Una vez que el jugador ha completado la primera carrera, el fantasma aparece desde el inicio de la siguiente y el jugador compite contra el fantasma de su mejor carrera completa.

  • Se ha implementado un sistema que almacena los mejores tiempos de cada circuito tanto por vuelta como por carrera completa, utilizando el persistenteDataPath de Unity para almacenar los datos en varios ficheros JSON, aunque también se utiliza Resources.Load() para comprobar si existen datos de tiempo en la build. En el caso de los ficheros por carrera completa, se almacena el tiempo de cada vuelta y se separan por circuito, pero también por el número de vueltas elegidas por el jugador.

  • Se ha implementado un sistema que ralentiza el coche cuando sale de la pista, aplicando directamente un penalizador del 50% a la propiedad maxSpeed del coche. Como de esta manera la frenada era muy abrupta, se optó por considerar el número de ruedas que se encuentran fuera de la pista para aplicar un ralentizador más suave. La penalización total sólo se aplica cuando las cuatro ruedas están fuera de la pista y se aplica de forma progresiva y proporcional a medida que van saliendo.
  • Se ha implementado un sistema de daño muy básico que penaliza una única vez la propiedad maxSpeed del coche cuando se golpea contra un objeto y que activa un sistema de partículas. Esta penalización puede acumularse a la que se produce al salir de la pista, por lo que el coche puede llegar a ralentizarse hasta un 75% de su velocidad máxima.

  • Se ha implementado una funcionalidad que devuelve al jugador al último checkpoint en caso de caer al agua.

  • Se ha implementado un sistema de pausa que permite al jugador pausar la partida en cualquier momento y salir del juego.

  • Se ha implementado un sistema de repetición de la carrera utilizando Cinemachine ClearShot.

  • Se han creado dos circuitos de carácter montañoso y con atajos, así como cuatro coches diferentes, tanto en color como en características. Adicionalmente, se ha añadido un menú principal y pantallas de selección de circuito y coche.

  • Se han añadido música y sonidos en diferentes momentos del juego.
  • Se ha implementado un sistema de minimapa utilizando una cámara ortográfica y Cinemachine.

  • Se ha probado la build para Windows 11 64 bits y para WebGL.

Problemas conocidos

  • Dado que el ratón no ha podido desactivarse por completo debido al uso del sistema de input antiguo, en ocasiones es posible desactivar por error la navegación en los menús y es necesario reiniciar la aplicación.

Créditos

Standard Assets

  • Todos los recursos incluidos en los Standard Assets son propiedad de Unity Technologies.

EasyRoads3D

EasyRoads3d es propiedad de UnityTerrainTools

Música y sonido

Fuentes

Referencias

Unity – General

Scriptable Objects

Standard Assets

Terrain

EasyRoads3D

TextMeshPro

Cinemachine

Debate2en Skedaddle, y’all!

  1. Ismael Navarro Páez says:

    Que chulo.

    He visto que has puesto un minimapa también con la posición del coche? Esa funcionalidad queda genial.

  2. Anna Zango Palau says:

    Justo quería comentar lo mismo, la idea del mini mapa es muy buena! Y los efectos que has puesto de humo y partículas quedan genial!!