No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

2D
16H
23M
43S

Comportamiento de enemigo

16/40
Recursos

Aportes 12

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Segun lo visto hay un problema y es que a medida que el enemigo se acerca al jugador este empieza a disminuir su velocidad. Para solucionar esto, hay que dividir el vector direccion por su magnitud. asi:

transform.position += (Vector3)direction/direction.magnitude * Time.deltaTime * enemySpeed;

Reto 1

Reto 2

primero le damos al player un rigibody2d con gravity scale en 0
y tildamos is trigger
lo mismo con el enemigo
luego Generamos una valiable [serializeField] int PlayerHealt = 5;

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Enemy"))
    {
        PlayerHealt--;
        if(PlayerHealt<= 0)
        {
            gameObject.SetActive(false);
        }
    }
}

En el script del enemigo:
public void TakeDamage()
{
healt鈥;
if (healt <= 0)
{
Destroy(gameObject);
}

}

}
En el Script del Bullet
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag(鈥淓nemy鈥)) {
collision.GetComponent<Enemy1>().TakeDamage();
Destroy(gameObject);
}
}
}

Para mover un objeto a otro, se utiliza la resta de vectores.

Hola 馃槃
Con estos retos me sent铆 creativo y me puse a hacer las cosas de una forma un tanto diferente a lo venimos haciendo en el curso. No se como vaya a resultar a futuro conforme vaya creciendo el proyecto, pero es parte de la diversi贸n 馃槣

<h3>Destruir el enemigo</h3>

Al principio solo agregue, dentro del script de Enemy, una condici贸n de que se destruyera el gameObject cuando health fuese menor o igual a 0

Pero me sent铆 inspirado y decid铆 extraer el comportamiento de ser 鈥渄a帽able鈥 a otro script, para poder reutilizarlo luego con el Player u otros objetos

Para este comportamiento 鈥淒amageable鈥 se me ocurri贸 que iba a querer que pudieran suceder diferentes cosas al gameObject cuando se quedara sin vida, as铆 que le agregu茅 cre茅 un event llamado OnEmptyHealt que me sirviera para ejecutar N cantidad de comportamientos cuando el gameObject en cuesti贸n se quedase sin vida

Esto tiene que ver con Delegados y Eventos

Una explicaci贸n algo burda del c贸digo de arriba (que bien puede que no sea del todo correcta, pero me ayuda a entenderle un poco) ser铆a

En la l铆nea 6 digo:
He aqu铆 un tipo de delegado, que recibe cero par谩metros y no retorna ning煤n valor, este tipo de delegado se llama EmptyHealthAction

En la l铆nea 7 digo:
He aqu铆 un evento cuyo nombre es OnEmptyHealth, que puede ejecutar delegados del tipo EmptyHealthAction

y en las l铆neas 11 y 12 digo:
si la vida es menor o igual a cero y el evento OnEmptyHealt tiene alg煤n delegado a ejecutar, invoca al evento OnEmptyHealth para que ejecute todas los delegados que tiene asignados

Ya con eso listo, en el OnTriggerEnter2D de Bullet cambi茅 el componente se obtiene de Enemy a Damageable

Ahora lo que me faltaba era crear scripts/comportamientos independientes que pudiera escuchar al evento OnEmptyHealth del Damageable

Para esto cre茅 una clase abstracta, llamada DieBehaviour, que tuviera la l贸gica de:

  • Requerir que el game object en el que se encuentra el script tenga el componente Damageable (DieBehaviour linea 3)
  • Obtener el componente Damageable para poder suscribirme al evento OnEmptyHealth mas adelante (DieBehaviour l铆nea 9)
  • Suscribir y des suscribirse al evento cuando el script o el gameObject en el que est茅 sea habilitado o deshabilitado (DieBehaviour l铆nea 11 a 18)
  • Y declarar un m茅todo abstracto Die, para que quien implemente la clase lo sobre escriba

Y ya con esa clase abstracta como plano, cree el script 鈥淒estroyOnDeath鈥 que destruye al gameObject cuando muere, aqu铆 est谩 el c贸digo

La idea de esto es que ahora que quiera crear una l贸gica especial para cuando un GameObject que sea Damageable 鈥渕uera鈥 basta con crear un script que herede la clase DieBehaviour, agregarle la l贸gica que quiera en el m茅todo Die y ya

Ahora puedo agregar y mezclando diferentes o/y multiples comportamientos a la muerte de un GameObject simplemente arrastrando los scripts que vaya creando.

Por ejemplo si tuviera el siguiente catalogo de efectos que puedan suceder cuando un Damageable muera, separado cada uno en su propio script

  • invocar n cantidad de enemigos al morir,
  • darle un efecto de ceguera al jugador al morir
  • explotar al morir
  • marcar el juego como terminado al morir (si muere el jugador por ejemplo)
  • re-vivir a la entidad en otro lugar
  • darle un efecto positivo al que lo mat贸
  • lanzar una onda congeladora alrededor de donde muere

Podr铆a combinarlos en diferentes enemigos y tener un enemigo que al morir explote y te de un efecto de ceguera, o uno que lance una onda congeladora al rededor y despu茅s invoque a otros 3 enemigos cuando muera.

Al final el prefab de mi Enemy qued贸 as铆 por ahora:

<h3>Da帽ar al jugador cuando los enemigos lo toquen</h3>

Para da帽ar al jugador le agregu茅

  • un Riggidbody 2D, con gravedad 0
  • y un CircleCollider2D

Le agregu茅 el evento OnTriggerEnter2D al script de Player para que cuando chocara con un enemigo se haga da帽o

Cre茅 un script para que se escriba el nombre del GameObject cuando muere, para ver que el player pueda morir

y al GameObject Player le puse los componentes 鈥淒amageable鈥 y 鈥淧rint Message On Death鈥

As铆 qued贸 el player

Reto completado!

Destruccion de enemigo

Primero debemos darle una variable de salud

[SerializeField] int health = 5;

Luego en en metodo 鈥淭akeDamage鈥 colocamos un condicional

public void TakeDamage(){
        if (health < 1){
            Destroy(gameObject); //Destruyo al enemigo 
        }
        health--;
    }

Dano hacia el jugador

  1. En Unity en 鈥淗ierachy鈥 selecciono a 鈥淧layer鈥 y le asigno el tag Player
  2. Luego le agrego el componente 鈥淏ox colider 2D鈥 鈥> selecciono 鈥淚s Trigger鈥
  3. Despues selecciono a 鈥淓nemy鈥 y le agrego el componente 鈥淩igidbody 2D鈥 鈥> gravity scale 鈥0鈥

En el codigo del 鈥淧layer鈥 le agrego salud y el metodo TakeDamage

// Setteo la variable
[SerializeField] int health = 10;

// Metodo take damage
public void TakeDamage(){
        if (health < 1){
            print("[Engine] GAME OVER")
        }
        health--;
    }

En el codigo del 鈥淓nemy鈥 escucho por una colision con Player y llamo su metodo TakeDamage

private void OnTriggerEnter2D(Collider2D collision){

        if (collision.CompareTag("Player")){
            collision.GetComponent<Player>().TakeDamage();
        }
    }

Primero le damos al player un rigibody2d con gravity scale en 0, lo mismo con el enemigo, luego generamos una variable [SerializeField] int HealthOfPlayer = 10;

Hacer que el enemigo mire en direcci贸n al jugador

void Update() {
	// Obtenemos la posici贸n
        Vector2 direcction = player.position - transform.position;
	// Calculamos el 谩ngulo para rotar
        float angle = Mathf.Atan2(direcction.y, direcction.x) * Mathf.Rad2Deg;
        Quaternion targetRotation = Quaternion.AngleAxis(angle, Vector3.forward);
        // Asignamos la rotaci贸n
	transform.rotation = targetRotation;
	// Finalmente asemos que avance el enemigo
        transform.position += transform.right * Time.deltaTime * speed;
}

muy buena explicacion se entiende todo

Antes de llegar a este v铆deo ya hab铆a hecho los retos D:
Me gusta mucho este curso.

Destrucci贸n del Enemigo por las Balas

En OnTriggerEnter2D, comparo si es el enemigo y si lo es, le hago da帽o al enemigo y destruyo la bala.

    void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.CompareTag("Enemy"))
        {
            EnemyBehaviour enemy = collider.GetComponent<EnemyBehaviour>();
            enemy.TakeDamage(Damage);
            BulletPooler.sharedInstance.DestroyBullet(this);
        }
    }

Cada bala tiene una variable da帽o que es el da帽o que produce la arma (Aparte de lo ense帽ado en el cur hasta ahora, tambi茅n cre茅 un script Weapon).

    public int Damage
    {
        get => Weapon.Damage;
    }
    public WeaponBehaviour Weapon { get; set; }

Y Take Damage resta el da帽o pasado a la vida. Para eso tengo una propiead Health

    private int health;
    public int Health
    {
        get => health;
        set
        {
            health = value;
            if (health <= 0)
            {
                Die();
            }
        }
    }

Da帽o del Enemigo al jugador

Tengo una funci贸n Attack que le quita vida al jugador.

    public void Attack()
    {
        if (CanAttack && Player != null)
        {
            CanAttack = false;
            Player.TakeDamage(10);
            StartCoroutine(WaitAttack());
        }
        else if (Player == null)
        {
            state = State.Wander;
        }
    }

    public IEnumerator WaitAttack()
    {
        yield return new WaitForSeconds(1.0f);
        CanAttack = true;
    }

Genial