epelpad

Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

Terminada la 5ta y ultima parte del tuto!!


Buenas de nuevo gente esta es la 4ta entrega del tutorial para hacer tu propio videojuego desde 0


Las partes anteriores:






En la parte 3 lo dejamos en:
  • Diseñar el enemigo
  • Animarlo
  • Importar a Unity y configurarlo
  • Script de movimientos del enemigo


En esta ocasión vamos a:
  • Effectos y Sonidos
  • Sistema de vida y barra de vida de los enemigos
  • Ataque de espada y Disparo de bala
  • Vida y barra de vida del player
  • Ataque del enemigo



Música para ambientar






Effectos y Sonidos


Lo primero que vamos a hacer es diseñar los effectos 2D y los sonidos. Así a medida que hacemos los scripts los agregamos.

Los effectos 2D que vamos a usar son:
  • Salpicadura de sangre(para cuando recibimos daño)
  • Salpicadura de sangre(pero verde para los enemigos)
  • Polvo para cuando aterrizamos
  • Polvo para cuando corremos
  • Una pequeña explosión para el disparo
  • Un effecto para el espadazo
  • Una explosión para marcar el daño del enemigo

Muchas veces pueden encontrar los effectos en internet ya hechos. Pero tienen que estar seguros de que son libres y de que pueden usarlos en su juego para evitarse problemas.

Alternativamente pueden buscar effectos, y usarlos de referencia para hacer unos lo mas parecido posible. La ventaja de esto es que el estilo del efecto va a coincidir mejor con el de su juego.

Ejemplo, para la sangre voy a usar esta imagen de referencia:


Y esta es la que hice yo, como ven es mucho mas básica. Ya que nada en el juego tiene contornos, ni sombras, la hice solo roja:
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

Y se ven muy similar animadas:
desarrollo

Aquí dejo un todas las imagenes que use de referencia:
Link a Google Drive

Y aquí con las que hice yo por si se quieren saltear el paso de diseñarlas:
Link a Google Drive

Ya teniendo los efectos 2D. Vamos a buscar los sonidos.

Los sonidos que vamos a usar son:
  • Run
  • Land(para cuando aterrice el monstruo o el player)
  • Explosion(para el ataque del monstruo)
  • Shoot
  • Slash
  • Hurt(para cuando el player reciba daño)
  • Dying(para el player)
  • Dying Monster
  • "Oh Yeah" para cuando el jugador mate un monstruo o recoja un pick up

En el caso de los sonidos tienen que pensar que clase de sonido quieren y googlearlo. Hay varias paginas de donde pueden descargarlos gratis por ejemplo:

Alternativamente pueden buscar en youtube los sonidos que necesiten y descargarlos con la web youtube to mp3

Si quieren hacer sus sonidos un poco mas retro, pueden generarlos 8bits acá:
http://www.bfxr.net/

Y para la música de fondo también pueden buscar en youtube. Hay muchisima buena música gratis y legal. Pero les recomiendo esta pagina mejor:
JukeDeck

Ahí pueden facilmente editar sus propios soundtracks y usarlos gratis(dando credito a la pagina). Por ejemplo yo hice uno con un estilo de acción y es el que voy a usar de fondo:
https://www.jukedeck.com/share/dd1195df55fed0c393562272ed5fa739c6b33219ad8531461f7e3c801ec7efb3

Por ultimo: Los efectos de sonido que descarguen, rara vez van a ser perfectos. A veces van a ser muy largos y van a necesitar recortarlos en el final, o el principio. O quizás tengan ruido de fondo que necesiten limpiar. En cualquier caso pueden editarlos con el programa Audacity, que es muy fácil de usar, y es gratis:
Audacity

Acá les dejo los sonidos que voy a usar yo:
Link a google Drive

Arrastren los sonidos a la capeta de sonidos que crearon en Unity. Y arrastren la carpeta efectos, dentro de la carpeta de imagenes.

Recuerden seleccionar cada una de las imágenes de efectos y cambiar a multiple, y usar el slice, dividiendo en columnas y filas según cada sprite(como hicieron al importar los sprites del enemigo)



Vida del Enemigo


Primero vamos a hacer unos cambios al script Enemy, añadiendo lo siguiente:



Vamos a crear un empty object > Add Component > Circle Collider 2D > isTrigger
A este objecto le vamos a asignar un tag nuevo llamado "Weapon"
tutorial

Ahora vamos a probar mover este empty object a traves del enemy. Para que les sea mas fácil pongan la velocidad y el salto del enemy en 0 así no se mueve. También pongan su hp en 4

Pongan play, y en la pestaña escena muevan el empty object atraves del enemy y confirmen que en la consola les salga el mensaje con la vida del enemy, que debería ir bajando.

Confirmado que eso esta bien, seleccionen al Enemy, con click derecho > UI > Canvas
Al objeto canvas cambien su render mode a World Space
Cambien el tamaño a width 2 height 0.5
Posición 0 / 0 y después subanlo un poco hasta que quede sobre la cabeza del enemigo
Cambien el Sorting Order a uno nuevo llamado "Canvas" y ponganlo arriba del todo.
Quiten el componente de raycast
Debe quedarles así:
juegos

Dentro de la carpeta Imagenes creen un nuevo Sprite > Square
Dentro de Canvas creen con click derecho > UI > Image
Cambien el tamaño a 2 y 0.25
A esa Imagen renombrenla HP_Back, cambien su sprite por el recién creado Square
Cambien el color a rojo y desmarquen raycast target
game

Ahora seleccionen HP_Back y presionen Ctrl+D para duplicarlo. Arrastren la copia dentro del original.
A la copia cambienle el nombre solo a HP, y el color a verde
Seleccionen HP y cambien ImageType a Filled > Horizontal
Ahora si usan el slider, van a ver que al bajarlo se reduce la barra verde dejando la roja a la vista
Unity

Ahora vamos a hacer las siguientes modificaciones al script del enemy
Añadir using UnityEngine.UI; arriba del todo
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]
Estas variables nuevas:
desarrollo
Y estos cambios en OnEnable y OnTrigger:
Programacion

Ahora en Unity arrastramos el Objecto HP a la variable del enemy "HP_UI" y el objeto Canvas a la variable "HP_Canvas".
Si le damos play vamos a ver como la barra desaparece, y al pasar el objeto que usamos de prueba con la etiqueda weapon, aparece con 3/4 de relleno, al pasarlo de nuevo solo con la mitad, etc.

También verán que la barra de vida se voltea si el enemigo se voltea. Vamos a arreglar cambiando esto en Move:
Videojuegos

Finalmente hacemos este pequeño cambio para detectar si el enemigo muere:
indie




Efectos y Ataque del Enemigo


Vamos a empezar a crear los efectos que vamos a usar. Partamos con algo simple, hacer la animación del polvo al caer.

Creen un empty object, nombrenlo Land_Effect
Arrastren todos los sprites de la animación de aterrizar, dentro de ese objeto
Creen la nueva animación en la carpeta animaciones y llamenla también Land_Effect
En el sprite editor, cambien su sprite por el primer frame de la animacion para poder verlo
Cambien el sorting order a Player y ponganlo en -20
Ahora muevanlo hasta que este debajo del enemigo, y haganlo mas pequeño hasta que quede de un tamaño apropiado.

Ahora con Land_Effect seleccionado, abran la pestaña Animation, y en el ultimo frame cambien su color alpha a 0 para que se haga invisible(automáticamente en el primer frame se va a crear el color alpha en 1) en el ante ultimo frame pogan el alpha en 1 también para que sea visible toda la animación y después desaparezca.

Seleccionen la animación en la carpeta y desmarquen "loop"
Al objeto Land_Effect > Add Component > AudioSource > Audio Clip > Land
Vuelvan a editar la animación y en el segundo frame desactiven y activen el Audio Source. Y en el ultimo dejenlo desactivado.

En el Animator, creen una condición tipo Trigger "Land" y creen una transición de Any a Land con esa condición.
También creen un Empty State y hagan que este sea el Default State.

Finalmente cambien el color alfa del Sprite a 0 para que sea invisible desde el principio, y desactiven el audio source para que no haga sonido al empezar.

Arrastren el objeto a la carpeta Prefabs, para que se nos cree un prefab de el y después podamos volver a usarlo.

Editen el Script Enemy para poner esto
Dos variables nuevas:
juegos

land_Effect.transform.SetParent(null) en el Awake
game

Un nuevo método Land_Effect() y lo van a llamar desde el FixedUpdate
Unity

Ahora arrastren el objecto Land_Effect dentro del Enemy. Y también arrástrenlo dentro de la variable "Land_Effect" en el Script Enemy.

Si lo prueban ahora, cada vez que el enemigo toca el suelo se activa el efecto. asegúrense de que este todo funcionando bien antes de seguir.
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

Siguiendo este proceso, vamos a crear un objeto nuevo con la animación Explosion, que es el ataque del enemigo

Es todo el mismo proceso, solo que ademas de hacer que en el ultimo frame se haga invisible, también vamos a hacer que se haga mas grande desde el primer hasta el ultimo frame. Y que el circle collider este desactivado al final de la animación.

Ponganle el Audio Source con el clip Monster_Explosion.
Añadanle un circle collider, con isTrigger marcado.
Y ponganle un nuevo tag "Explosion"
Quitenle el loop a la anamación
Y editen el animator con la condición "Explosion"
Desactiven el AudioSource
Pongan el Sprite invisible
Dejen el circle collider desactivado
Y creen un prefab en la carpeta prefabs

Modificar el script para esto es mucho mas simple. En la variable animator de hoy agreguen esto;
desarrollo

Y en Attack() agreguen:
Programacion

Listo, ahora arrastren la Explosion dentro del Enemigo, y también arrastrenla dentro de la variable del script.

Si le ponen la velocidad de movimiento y salto al enemigo debería pasar esto:
Videojuegos

Para asegurarnos de que el ataque le pega al Player vamos a agregar este codigo en el Script Player:
indie

Ahora cuando la explosión alcance al player, va a aparecer ese mensaje en consola.

Para que el monstruo muera, vamos a añadir un audio source. Le vamos a poner de clip el Monster_Die. Y desmarquen PlayOnAwake.

Vamos a crear una nueva variable AudioSource en el script del enemigo, y a crear una referencia en el Awake
sprite

Un pequeño cambio al TriggerEnter:
tutorial

Y un cambio a Die() junto con la creación de AddToPool:
juegos

Si todo quedo bien podemos ver el resultado usando el objeto que habiamos creado con el tag weapon(que simula los golpes del player)
game

Para terminar esta parte, vamos a usar el mismo método que usamos para crear el Land_Effect y el Explosion. Y vamos a crear la sangre verde.
Esta vez usen el clip de audio: Blood_Splat

El código lo vamos a modificar así:
Añadir un nuevo animator:
Unity
Y una pequeña modificación en el TriggerEnter:
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

Pongan el sprite invisible, y desactiven su AudioSource.
Luego creen un prefab, y arrastrenlo dentro del enemigo, y dentro de la variable del script

Le subí la vida a 10 para probarlo mas veces:
desarrollo

Con eso ya queda todo lo que es el combate por el lado del enemigo. Ataca y hace daño, recibe daño, muere, sangra, etc etc.



Vida del Player


Primero vamos a añadir la variable hp y current_hp como hicimos con el enemigo.
Luego vamos a seleccionar el Canvas que esta en el enemigo. Presionar ctrl+D para duplicarlo, y pasar la copia al player.
Muevanlo hasta que se ajuste debajo de el, y hagan la barra mucho mas larga.
Podríamos poner la barra de vida en una esquina, como en muchos videojuegos. Pero en esta ocasión vamos a hacerlo así para ver como queda.

De nuevo como hicimos con el enemy vamos a agregar using UnityEngine.UI; arriba del todo
Y esto es un poco distinto al enemy:
Añadan la variables public Image hp_UI, back_hp_UI; y la variable private bool isDead;
indie
Arrastren las barras de vida a las variables correspondientes. Pongan el slider de la barra de vida lleno, y cambien el color alpha de ambas barras a 125.
Ponganle 10 de vida al player.

Agregamos el void Start()
sprite

Modificamos un poco el TriggerEnter, y agregamos una variable Coroutine junto con una Corutina:
tutorial

Esto, si salio bien nos deberia dar una barra de vida que esta semi transparente, y al recibir un impacto se hace visible, para luego de un segundo volver a ser transparente:
juegos

Ahora dupliquen el objeto Monster_Blood, y renombrenlo solo blood. Seleccionen el Animator Monster_Blood en la carpeta, y tambien dupliquenlo y renombrenlo Blood, y lo mismo con la animación Monster_Blood
game

Arrastren el animator Blood al objeto Blood. Seleccionen el objeto y abran el Animator. Seleccionen el state de la animación, y en el inspector cambien Motion, de la animación Monster_Blood a Blood

Con todo esto hecho ya duplicamos completamente todo, y podemos modificar la animación sin perder la que usamos en el monstruo.

Abran la pestaña Animation, y en cada frame remplacen el sprite de sangre verde, por su equivalente rojo.

Finalmente seleccionen el objeto Blood(sin estar editando la animación) y cambien el sort layer de Enemy a Player. Y cambien el sprite que tiene por su equivalente rojo.

Arrastren el objeto a la carpeta prefabs para que se cree su propio prefab. Y arrástrenlo también dentro del player en la posición 0/0/0

Ahora en el Script agreguen la variable public Animator blood, y borren las barras de comentario de la corutina Hitted.
//blood_Splat.SetTrigger("Hurt"Unity;

Finalmente arrastren el objeto Blood a la variable que corresponde en el script del player y confirmen que funciona bien.

Para terminar esta parte, añadan la variable:
public GameObject hp_Canvas;
Y arrastren el canvas dentro, y modifiquen el método Move() para hacer que la barra de vida no se gire con el player:
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]





Efectos del Player


Vamos a empezar por lo mas simple, arrastren el Land_Effect de la carpeta prefabs, hasta el player. Y modifiquen el script del Player añadiendo la variable animator "land_Effect" junto a donde tienen blood_Splat.

también agreguen la variable private bool land;

Copien el método Land del script del enemigo. Y pongan Land() en el FixedUpdate
Videojuegos
Remplacen la linea
land_Effect.transform.position = new Vector2(transform.position.x, transform.position.y - height);
por:
land_Effect.transform.position = playerPos();

Con esto y arrastrando Land_Effect dentro de la variable del script del player ya debería quedar pronto.

Ahora vamos a crear un nuevo efecto, como hicimos con la sangre y el aterrizar.
Creen un empty
Nombrenlo Running_Dust
Arrastren a el los sprites de la animación del polvo
Añadanle un AudioSource con el clip Running. Dejenlo desactivado
Suban la velocidad de la animación aumentando los frames a 18
Hagan que sea totalmente transparente en el ultimo frame, pero totalmente visible en el anteultimo
En el primer frame marquen el AudioSource como desactivado, y activenlo en el segundo frame
Ponganlo en el sorting layer Player, order 20
Quitenle el loop a la animación
Ponganlo en un tamaño pequeño. en mi caso 0.5/0.5/0.5
En el animator creen un empty state como default
Creen una condición "Spawn" y ponganla de Any a la animación
Y arrastrenlo a la carpeta prefabs

Ahora vamos a crear un nuevo script en la carpeta scripts, y nombrenlo "Running_Dust"
Este lo vamos a usar para generar polvo al correr, pero tambien me va a permitir introducirles el concepto Object Pooling.

Esto se trata de en vez de crear y destruir objetos constantemente(que no es eficiente e impacta negativamente en la performance de nuestro juego), vamos a crear objetos, desactivarlos, y reactivarlos cuando los necesitemos de nuevo.

Esto lo vamos a usar con varias cosas, como el polvo al correr, las balas, y los enemigos.
El script va a contener lo siguiente:
indie

Creen un empty object y llamenlo Dust. Ponganlo dentro del player a la altura del pie izquierdo. Arrastren el nuevo script a este objeto.

En el script del Player agreguen la variable
public Running_Dust runningDust;
Y dentro arrastren el objeto Dust

Creen un nuevo método en el script del Player:
sprite

Ahora seleccionen el player, y vayan a la pestaña animation. Pongan la animación Player_Run y vayan al frame donde apoya los pies. Y presionen el boton AddEvent(que esta cerca de los samples)

Seleccionen ese Event que se creo, y en el inspector cambien Function, y busquen
InstantiateDust()
Esto es para activar un método desde la animación.
Hagan lo mismo en el siguiente frame que apoya los pies:
tutorial

Con esto pronto, deberíamos poder ver como al correr el player hace ruido de pasos y genera motas de polvo:
juegos




Ataques del Player


Vamos a empezar con el ataque de espada. Seleccionen el sprite donde esta la espada, y añadanle un box collider generosamente mas grande que la espada misma. Marquenlo isTrigger, y ponganle el tag Weapon:
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]
Dejen este box collider desactivado.

Añadan dentro de la espada el sprite Slash y acomodenlo un poco por delante de la espada. Pónganlo en el sorting layer Player order 20:
desarrollo
Déjenlo con la transparencia al máximo para que no se vea.

Ahora vayan a la pestaña animation, y editen la animación del espadazo.
Hagan que en el primer frame el box collider este desactivado, y el efecto de slash transparente. Cuando sube la espada(segundo frame) activen el box collider y empiecen a hacer visible la espada.
Cuando la baja del todo tiene que estar visible el effecto.
Un par de frames después de que bajo la espada, desactiven el box collider, y hagan el efecto transparente de nuevo:
Programacion

Con esto hecho, el espadazo debería ser capaz de dañar al enemigo. Pongan la velocidad del enemigo en 0 e intenten pegarle:
Videojuegos

No es el efecto mas bonito del mundo, pero cumple con el propósito del tutorial. Les pido disculpas por no ser un artista, lo mio es mas bien programar indie

Para terminar el espadazo:
Agreguen a la espada un AudioSource
Dejenlo desactivado
Ponganle el Clip Slash
Y modifiquen la animación para que desactive audio source en el primer y ultimo frame, pero lo active en el segundo.

Finalmente el disparo! Para esto primero vamos a crear una bala.
Creen un empty object, y nombrenlo Bullet
En la carpeta imágenes > click derecho > Create > Sprites > Circle > Nombrenlo bullet
Arrastren el sprite al objeto Bullet.
Añadanle un circle collider(ligeramente mas grande que el sprite de bala)
Marquen isTrigger
Cambien el tag a Weapon

Ahora creen un nuevo script en la carpeta scripts. Nombrenlo Bullet.
sprite

Arrastren el script al objeto Bullet, y ponganle una velocidad que les guste(yo use 10). Pongan play para ir probando. Pongan la bala a la altura del monstruo así comprueban que funcione bien.
tutorial

Ahora arrastren la bala a la carpeta Prefabs.
En el script Player creen estas 3 variables:
juegos

Y estos dos métodos:
game

Arrastren el prefab Bullet a la variable del script.

Ahora editen la animación shoot, y en el segundo frame añadan una event key, y cambien function a:
ShootBullet()
Unity

Quiten las barras de comentario del método AddToPool del script bullet. Y borren el Destroy:
Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

Finalmente creen un empty object dentro de la mano con el arma, nombrenlo spawnPoint, y coloquenlo en la punta del arma. Este objeto arrastrenlo a la variable del player SpawnBulletPoint.

Seleccionen las paredes del nivel > Add Component > RigidBody2D > BodyType = Kinematic
Y modifiquen el script bullet:
desarrollo

de esta manera las balas se van a destruir al chocar con los enemigos o con una pared.

Ahora si lo prieban deberian ser capaces de disparar balas con el click izquierdo:
Programacion

El único problema es que al girar el player las balas se siguen disparando hacia la derecha. Para arreglar esto vamos a hacer la siguiente modificación en el método Move.
Videojuegos
Y modificar el ShootBullet():
indie

Ahora para el efecto de disparo, arrastren uno de los sprites del efecto, dentro de la mano del arma. Ponganlo de un tamaño apropiado, y cambien el sorting layer a player order 20
Ponganlo transparente

Y editen la animación de disparo una vez mas.
En el segundo frame hagan completamente visible el efecto
En el tercer frame cambien el sprite por el segundo sprite de la animación
Un poco mas adelante vuelvan a poner transparente. Pero asegurense de que se mantenga completamente visible hasta después de haber cambiado de sprite.
sprite

Finalmente añadan a la mano del arma un AudioSource
Dejenlo desactivado
Cambien el clip a Shoot
Y editen la animacion una vez mas para que el audio soucer se active en el segundo frame, y se vuelva a desactivar al final.

Debería quedarles así:
tutorial

Ahí en el gif se ve un error donde el arma dispara hacia abajo. Eso lo solucione cambiando la linea dentro de move de:
spawnBulletPoint.transform.eulerAngles = new Vector3(0, rot, 0);
a:
spawnBulletPoint.transform.localEulerAngles = new Vector3(0, rot, 0);




Bueno con eso ya queda pronto lo que es el combate. Pueden duplicar el monstruo varias veces e intentar matarlos a todos para comprobar que este todo bien.

Aun nos falta poner que el player muera cuando tenga 0 de vida. Eso lo vamos a hacer en el proximo(y por fin ultimo) post.
Junto con el puntaje, el ranking, el menu principal, y el menu al perder, el script para spawnear enemigos, y finalmente hacer la build de su juego!

Aqui dejo los 4 scripts que tenemos hasta el momento:
Bullet
Running_Dust
Enemy
Player_Controller

Para que puedan comparar y buscar errores con lo que llevan hecho.

Este post fue TREMENDAMENTE largo y difícil de hacer. Espero poder hacer el siguiente mas resumido, que por suerte es el ultimo. Luego voy a centrarme en hacer tutoriales mas simples, y fáciles de seguir.

Si tienen cualquier duda me pueden contactar por MP acá en taringa(de paso si quieren me siguen)
https://www.taringa.net/RichLazydog
O en mi pagina de facebook(de paso si quieren le dan like Indie )
https://www.facebook.com/shioo4play

Si tienen cualquier recomendación de que les gustaría ver en el tutorial, avísenme! Ya sean alguna mecánica de algún juego o algo por el estilo.

Nos vemos el Lunes!

6 comentarios - Sistema de combate: Tu propio videojuego 2D desde 0 [P4]

esmerlin0 +1
Esta muy bueno podrias poner la parte 5 dentro del post
RichLazydog
Gracias! Estaba arriba del todo la parte 5
https://www.taringa.net/posts/ebooks-tutoriales/20046852/Terminar-y-publicar-tu-propio-videojuego-2D-desde-0-5-5.html
RikodouSennin21 +1
hola bro, segui tu consejo, ando viendo primero los video tutoriales del youtuber q aconsajaste, el pibe explica muy bien y eso que yo ya se algo de programaccion pero en si el uso de todo el inspector la documentacion de unity es basta espero poder acabar todos sus juegos y veria si puedo pasar al tuyo a ver si entiendo mas
RichLazydog
Me alegra! Yo los pongo a x2.5 de velocidad sus vídeos porque habla muy lento xD