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<PlayerController> 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?