Home | Clases | Unity: Navegación | Ejercicio propuesto 6: Estilo Pacman

Ejercicio propuesto 6: Estilo Pacman


Ejercicio propuesto 6: Estilo Pacman

Añade coleccionables de forma aleatoria cada 5 segundos (con una vida de 10 segundos) de modo que si los recoges, los enemigos cambien de color durante 10 segundos y huyan de ti (tipo Pacman). Además, añade la interactividad necesaria para que si durante ese tiempo los tocas se destruyan.

Lo primero que haremos, igual que con los enemigos, será arrastrar el objeto Coleccionable a la carpeta Assets > Prefabs y borrarlo de la escena, ya que lo instanciaremos desde el GameManager.

A continuación, modificaremos el script GameManager de modo que instancie coleccionables cada 5 segundos:


using System.Collections;
using UnityEngine;

public class GameManager : MonoBehaviour {

public GameObject enemigo, coleccionable;
public Vector3 posicion;
public int numeroEnemigos;
public float esperaInicial;
public float esperaEntreEnemigos;
public float esperaEntreOlas, esperaEntreColeccionables;

void Start() {

//LLamo a la rutina de crear enemigos
StartCoroutine(crearEnemigos());

//LLamo a la rutina de crear coleccionables
StartCoroutine(crearColeccionables());

}

IEnumerator crearEnemigos()
{
//Espero un tiempo antes de crear enemigos
yield return new WaitForSeconds(esperaInicial);

//Bucle durante toda la vida del juego
while (true)
{
//Bucle de número de enemigos
for (int i = 0; i < numeroEnemigos; i++)
{
//Instancio el enemigo en una posición aleatoria del tablero
Vector3 posicionEnemigo = new Vector3(Random.Range(-posicion.x, posicion.x), posicion.y, Random.Range(-posicion.z, posicion.z));
Quaternion rotacionEnemigo = Quaternion.identity;
Instantiate(enemigo, posicionEnemigo, rotacionEnemigo);

//Espero un tiempo entre la creación de cada enemigo
yield return new WaitForSeconds(esperaEntreEnemigos);
}

//Espero un tiempo entre oleadas de enemigos
yield return new WaitForSeconds(esperaEntreOlas);
}
}

IEnumerator crearColeccionables()
{
yield return new WaitForSeconds(esperaInicial);
while (true)
{
//Instancio el coleccionable en una posición aleatoria del tablero
Vector3 posicionColeccionable = new Vector3(Random.Range(-posicion.x, posicion.x), posicion.y, Random.Range(-posicion.z, posicion.z));
Quaternion rotacionColeccionable = Quaternion.identity;
Instantiate(coleccionable, posicionColeccionable, rotacionColeccionable);

//Espero un tiempo entre la creación de cada coleccionable
yield return new WaitForSeconds(esperaEntreColeccionables);


}

}

}


Ahora tan solo tendríamos que ajustar en la Inspector window del GameManager el valor de esperaEntreColeccionables a 5 y asociar la variable Coleccionable al prefab Coleccionable:



Si además queremos que el Coleccionable se destruya a los 10 segundos, crearemos un script llamado Coleccionable y se lo asociaremos al prefab Coleccionable con el siguiente código:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Coleccionable : MonoBehaviour {

void Update () {

//Lo destruyo a los 10 segundos
Destroy(gameObject, 10);

}
}


el siguiente paso sería que si el Jugador se coma un Coleccionable, ocurran las siguientes cosas:

  • Se inicie un contador hacia atrás de 10 segundos.
  • Los enemigos cambien de color durante esos 10 segundos.
  • Los enemigos huyan del Jugador durante esos 10 segundos.
  • Si el Jugador se come algún Enemigo durante esos 10 segundos, el Enemigo se destruye.


Lo primero que haremos será modificar el código de NavJugador para que compruebe si se ha recogido un Coleccionable y, en caso afirmativo establezca una variable pública booleana a true que podamos usar en el resto de scripts, así como un contador de 10 segundos hacia atrás que cuando termine establezca el valor del booleano de nuevo a false:


using UnityEngine;

public class NavJugador : MonoBehaviour {

private Rigidbody rb;
public float velocidad;
public bool huir = false;
private float tiempo;

void Start () {

//Capturo el componente rigidbody del jugador
rb = GetComponent<Rigidbody>();

}

void FixedUpdate () {

//Capturo el movimiento en los ejes
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Genero el vector de movimiento
Vector3 movimiento = new Vector3(movimientoH, 0, movimientoV);

//Muevo el jugador
transform.position += movimiento * velocidad;

//Si los enemigos están huyendo y nos e ha acabado el tiempo, decremento el tiempo
if (huir && tiempo > 0)
{
tiempo -= Time.deltaTime;
//Lo muestro en consola
Debug.Log(tiempo);
}
else
{
huir = false;
}


}

void OnTriggerEnter(Collider other)
{

//Si atraviesaa con el coleccionable
if (other.gameObject.CompareTag("Coleccionable"))
{
//Borro el coleccionable
other.gameObject.SetActive(false);

//Inicio el contador hacia atrás y pongo a true el booleano
tiempo = 10;
huir = true;
}

}
}


A continuación, indicaremos a los enemigos que si la variable huir está a true, deben cambiar de color y huir del Jugador. Además, si el Jugador les toca los que se mueren son ellos y no el Jugador. Modifica el script de NavEnemigo:


using UnityEngine;
using UnityEngine.AI;

public class NavEnemigo : MonoBehaviour {

NavMeshAgent agente;
GameObject jugador;
private MeshRenderer meshRenderer;

void Start () {

//Busco el jugador
jugador = GameObject.Find("Jugador");

//Capturamos en nav mesh agent del enemigo
agente = GetComponent<NavMeshAgent>();

//Capturamos el SkinnedMeshRenderer del children del enemigo para cambiarle el material
meshRenderer = GetComponent<MeshRenderer>();

}

void Update () {

//Muevo el enemigo hacia el jugador (si no lo han matado aún)
if (jugador != null)
{
if (jugador.GetComponent<NavJugador>().huir)
{
//Huye del jugador
agente.SetDestination(transform.position - jugador.transform.position);
//Color temporal
meshRenderer.material.color = Color.blue;
}
else
{
//Persigue al jugador
agente.SetDestination(jugador.transform.position);
//Color original
meshRenderer.material.color = Color.red;
}

}

}

private void OnTriggerEnter(Collider other)
{

//Si se choca con el jugador
if (other.gameObject.tag == "Jugador")
{
if (jugador.GetComponent<NavJugador>().huir)
{
//Destruyo al enemigo
Destroy(gameObject);
}
else
{
//Destruyo al jugador
Destroy(other.gameObject);
//Paro el tiempo del juego para que no se creen más enemigos
Time.timeScale = 0;
}
}
}
}



Fecha de publicación: 16/10/2019
Asignaturas: desarrollo de entornos interactivos multidispositivo
Temas: unity c# visual studio
Utilizamos cookies propias y de terceros para mejorar su experiencia en la navegación. Al seguir navegando entendemos que acepta su uso.
Si lo desea, consulte nuestras políticas de privacidad y cookies
ENTENDIDO
[X] Cerrar

Contacta conmigo


[X] Cerrar

Acceso alumnos