Programación de colisiones para enemigos en videojuegos

Clase 49 de 53Curso de C# para Videojuegos

Resumen

Domina un patrón robusto para enemigos en Unity: colisiones que activan el giro, daño configurable al jugador y control del escenario con prefabs. Con una lógica clara en OnTriggerEnter2D y el uso correcto de capas y colliders, el enemigo queda contenido entre rocas y se mueve con un efecto visual suave gracias a la animación en FixedUpdate.

¿Cómo configurar rocas, capas y prefabs para contener al enemigo?

Coloca un bloque de nivel desde los prefabs y sitúa rocas en el suelo para delimitar la zona. No hace falta etiquetarlas: la capa suelo ya evita que el personaje atraviese el escenario. Si quieres identificarlas, puedes usar etiquetas como rock o escenario, pero no es necesario.

  • Usa un bloque de nivel base y sitúalo en 0,0,0.
  • Arrastra el enemigo dentro del bloque para que el cambio quede en el prefab.
  • Añade una roca y ajusta su tamaño y collider para que el personaje pueda saltar sobre ella.
  • Clona una segunda roca y coloca al enemigo entre ambas: rebotará de una a otra.
  • Aplica los cambios al prefab y elimina la instancia en escena si tienes generación automática de niveles.

Resultado esperado: el enemigo queda “domesticado”, rebotando entre rocas y sin escapar del área diseñada por el game designer.

¿Cómo detectar colisiones y depurar con OnTriggerEnter2D?

El enemigo tiene su propio collider (por ejemplo, un Capsule Collider) marcado como isTrigger. Así, cuando entra en contacto con otro collider, Unity llama a OnTriggerEnter2D. Para comprobar con qué choca, usa un registro simple del tag en consola.

¿Qué comprobar con Debug.Log?

  • Ver etiquetas como: untagged, Player, Coin.
  • Ajustar temporalmente la velocidad del jugador para observar mejor la consola.
void OnTriggerEnter2D(Collider2D collision)
{
    Debug.Log(collision.tag);
}

Idea clave: en función de collision.tag decides la acción. Con monedas no haces nada; con el jugador aplicas daño; con escenario u otros, giras al enemigo.

¿Cómo aplicar daño al jugador y provocar el giro automático?

Gestiona la lógica por casos. Si la etiqueta es Coin, sales del método. Si es Player, localizas su componente y llamas a CollectHealth con un valor negativo. Si no es ninguna de las anteriores, cambias la dirección del enemigo invirtiendo la variable facingRight.

¿Cómo definir daño configurable desde el editor?

  • Expón un entero público enemyDamage.
  • Evita “hardcodear” valores: podrás crear enemigos con daños distintos.
public int enemyDamage = 10;

void OnTriggerEnter2D(Collider2D collision)
{
    // Moneda: no reaccionar.
    if (collision.tag == "coin") return;

    // Jugador: aplicar daño.
    if (collision.tag == "Player")
    {
        var player = collision.gameObject.GetComponent<PlayerController>();
        if (player != null)
        {
            player.CollectHealth(-enemyDamage);
        }
        return;
    }

    // Escenario u otros: girar.
    facingRight = !facingRight;
}

¿Cómo se logra el efecto visual del giro?

  • Cambias solo el estado: facingRight = !facingRight.
  • La rotación real la hace el método FixedUpdate ya implementado, generando un giro suave.

Comportamiento logrado: el enemigo choca con la roca, da la vuelta y vuelve. Al pasar por detrás de las monedas, no las afecta. Se crea un sistema de rutas simple con colisiones, alternativa directa a usar waypoints.

Habilidades y conceptos puestos en práctica: - Configuración de prefabs y colocación de elementos de escenario. - Uso de capas frente a etiquetas para colisión del suelo. - Manejo de colliders con isTrigger y método OnTriggerEnter2D. - Depuración con Debug.Log y lectura de collision.tag. - Parámetros configurables en el editor: enemyDamage como int. - Interacción con el jugador vía GetComponent y CollectHealth con valores negativos. - Control de dirección con bandera booleana facingRight y animación en FixedUpdate. - Rutas por colisión frente a waypoints.

Nota práctica: queda por ajustar la altura de colisión para evitar que el collider se quede “enganchado” y gestionar la muerte del personaje en una mejora posterior.

¿Te gustaría comentar cómo limitas tú las rutas de los enemigos o qué otras etiquetas/capas te funcionan mejor en Unity?