recrear remasterizar videojuegos 3D Unity programación
28
junio
2021

Continuamos con la serie “Proyecto de recreación de juego clásico de los 80”, en este segundo video/artículo vamos a implementar los disparos del jugador que le sirven de defensa contra las burbujas de ácido escupidas por las cabezas de dragón.

Si no has visto el episodio 2 de la serie, visítalo en este enlace: Creación del Escenario

Para empezar, necesitamos un sprite a partir del que crear un Prefab que implemente el comportamiento de cada proyectil laser que el jugador es capaz de disparar:

Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 1Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 2

Imagen del prefab “laser”

El prefab del láser integra un colisionador circular (Circle Collider 2D) de tipo disparador (trigger) y un cuerpo rígido de tipo kinemático. Para controlar el movimiento añadimos un script de control que desplaza el GameObject a determinada velocidad en la dirección de su propio eje Y:

public class LaserControl : MonoBehaviour

{

public float Velocidad;

// Update is called once per frame

void Update()

{

transform.Translate(Vector3.up * Velocidad * Time.deltaTime);

}

}

Dado que el movimiento se realizado desplazando el elemento mediante el método translate() y no empleando fuerzas empleamos un cuerpo rígido kinemático. Esto también es así en el caso del jugador, pero en su caso interesa un cuerpo rígido dinámico para facilitar la colisión contra el resto de elementos del escenario.

En el caso del láser, éste impacta pero no colisiona. Esto significa que es preciso detectar el momento en el que un láser se solapa contra otro GameObject para destruirlo, no para hacer que rebote o se detenga. Por ello empleamos un colisionador de tipo disparador marcando la casilla Trigger.

Para capturar el momento de impacto incluimos el método OnTriggerEnter2D().

private void OnTriggerEnter2D(Collider2D collision)

{

Destroy(gameObject);

}

Al ejecutarse el método, el láser se autodestruye y desaparece.

Una medida recomendable de optimización que impide que se acumulen las instancias de Laser una vez salen de pantalla es hacer que se destruyan. Esto evita que sigan avanzando y consumiendo recursos una vez que ya no son visibles, lo que es importante dado que generaremos gran cantidad de ellos rápidamente.

Para ello es preciso que el elemento conste de un componente SpriteRenderer e implementar el método OnBecameInvisible():

private void OnBecameInvisible()

{

Destroy(gameObject);

}

Una vez completada la implementación del prefab del Laser, es preciso modificar el prefab del jugador para que pueda disparar.

Para ello copiamos la mecánica de disparo del juego original según la cual la nave del jugador dispara en las cuatro direcciones al mismo tiempo. Los disparos se efectúan además con una frecuencia fija al mantener pulsado el control de disparo.

Si estás interesado en ampliar tus conocimientos en el área creación, desarrollo y diseño de videojuegos, visita nuestros cursos de videojuegos

Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 3

Para efectuar los disparos deben instanciarse cuatro veces el prefab Laser en la posición del jugador, pero con una rotación de 90º en el eje Z entre ellas:

Instantiate(Laser, transform.position, Quaternion.identity);

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, 90.0f));

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, -90.0f));

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, 180.0f));

Esto debe repetirse a una frecuencia determinada una vez que el usuario pulsa el control de disparo. Para ello, empleamos una corutina que se ejecuta cada 35 milisegundos mientras el jugador mantiene pulsada la barra espaciadora como tecla de disparo:

IEnumerator DisparoCorutina(){

disparando = true;

while( Input.GetKey(KeyCode.Space ))

{

Instantiate(Laser, transform.position, Quaternion.identity);

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, 90.0f));

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, -90.0f));

Instantiate(Laser, transform.position, Quaternion.Euler(0.0f, 0.0f, 180.0f));

yield return new WaitForSeconds(.35f);

}

disparando = false;

}

La variable “disparando” se activa (True) cuando se inicia la corutina y se desactiva (False) cuando se efectúa el último disparo en la corutina tras dejar de pulsar la barra espaciadora.

En el método Update() añadimos una línea para lanzar la corutina de disparo cuando el usuario pulse la barra espaciadora y la corutina de disparo no esté aun activa:

void Update()

{

Vector3 desplazamiento = Vector3.zero;

if ( Input.GetKey(KeyCode.UpArrow))

{

desplazamiento.y = +1.0f;

}

if (Input.GetKey(KeyCode.DownArrow))

{

desplazamiento.y = -1.0f;

}

if (Input.GetKey(KeyCode.LeftArrow))

{

desplazamiento.x = -1.0f;

transform.rotation = Quaternion.Euler(0.0f, 0.0f, 90.0f);

}

if (Input.GetKey(KeyCode.RightArrow))

{

desplazamiento.x = +1.0f;

transform.rotation = Quaternion.Euler(0.0f, 0.0f, -90.0f);

}

transform.Translate(desplazamiento * Velocidad * Time.deltaTime, Space.World);

if (Input.GetKeyDown(KeyCode.Space) && disparando == false )

StartCoroutine(DisparoCorutina());

}

Esto permite evitar que el jugador efectúe disparos a mayor frecuencia pulsando repetidamente la barra espaciadora.

Un problema que debe resolverse ahora es evitar que las instancias de los disparos se destruyan nada más ser creadas al solaparse con el colisionador de la propia nave del jugador. Para ello es preciso definir capas (Layers).

Una capa en Unity define un conjunto de uno o más GameObjects que pueden interactuar o no con los pertenecientes a otras capas o entre ellos. En este caso debemos definir dos capas:

Capa “Jugador” -> A la que pertenece el prefab “nave”:

Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 4

Capa “Laser” -> A la que pertenece el prefab “laser”:

Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 5

Para controlar si interactúan o no entre si los GameObjects de diferentes capas debemos configurar el esquema de interacción de capas. Este es accesible a través de:

Edit -> Project Settings..

En este caso, para que los disparos del jugador no colisionen ni impacten contra la propia nave del jugador debemos desmarcar la casilla que intercepta las capas “Jugador” y “Laser”:

Recrear videojuegos clásicos con Unity 3D: Disparos del jugador 6

Vista del esquema de interacción de capas.

En el próximo video veremos cómo hacer que los dragones escupan burbujas de ácido y su destrucción mediante los disparos del jugador.

Si estás interesado en ampliar tus conocimientos en el área creación, desarrollo y diseño de videojuegos, visita nuestros cursos de videojuegos

Otros episodios de la serie:

Author

Ángel Aguinaga

Profesor de Programación y Bases de Datos de la Sede Bilbao. Formador experimentado en áreas como .Net, Java, BB.DD., Python, Desarrollo y programación Web.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Recibe de primero nuestras ofertas de empleo y noticias