Implementing Enemy Pickup Destruction Behavior in Unity

Damian Dąbrowski
3 min readMar 8, 2024

--

In 2D shooter, an intriguing behavior is enabling enemies to actively destroy pickups, such as powerups, before the player can collect them. This article delves into implementing such a behavior in Unity, demonstrating how enemies can detect pickups in their vicinity and fire at them, changing their firing direction if necessary. Let’s explore the solution and the associated code to achieve this behavior.

Understanding the Solution

The goal is for enemies to detect pickups in front of them and respond by firing their weapons to destroy these pickups. This behavior requires enemies to be aware of pickups’ positions and adjust their firing direction accordingly. It’s essential for this system to support multiple enemies and pickups on the screen simultaneously.

Key Tasks for Implementation:

  1. Detecting Pickups: Utilize a child GameObject with a BoxCollider2D and Rigidbody2D as a detection area in front of the enemy.
  2. Calculating Firing Direction: Once a pickup is detected, calculate the direction vector from the enemy to the pickup.
  3. Adjusting Laser Movement: Modify the laser’s movement to target the detected pickup’s position.

Code Implementation

DetectorInEnemy Class

This class is responsible for detecting pickups within a predefined area in front of the enemy.

public class DetectorInEnemy : MonoBehaviour
{
private Enemy _enemy;
void Start()
{
_enemy = gameObject.transform.GetComponentInParent<Enemy>();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Powerup")
{
Vector3 powerupPos = other.transform.position;
_enemy.UpdatePickupPos(powerupPos);
_enemy.PowerupDestroyed(false);
Debug.Log("Detection of Powerup!");
}
}
}

Enemy Class

The Enemy class handles firing at the detected pickup by adjusting the laser’s direction based on the pickup’s position.

public class Enemy : MonoBehaviour
{
// Additional class variables and methods for context

void FireEnemyLaser()
{
// Laser firing logic
GameObject enemyLaser = Instantiate(_enemyLaserPrefab, _laserPos, Quaternion.identity, this.transform);
Laser[] lasers = enemyLaser.GetComponentsInChildren<Laser>();
for (int i = 0; i < lasers.Length; i++)
{
lasers[i].SetEnemyLaser();
if (_isPickupPosReceived)
{
lasers[i].SetPickupPos(Vector3.Normalize(_pickupPos - transform.position));
lasers[i].PickupBehavior(_powerupDestroyed ? false : true);
}
}
}
public void UpdatePickupPos(Vector3 pos) // Called by DetectorInEnemy
{
_pickupPos = pos;
_isPickupPosReceived = true;
Debug.Log("Position received");
}
public void PowerupDestroyed(bool status) // Updates powerup destruction status
{
_powerupDestroyed = status;
}
}

Laser Class

The Laser class is modified to change its movement behavior when targeting pickups, based on the direction vector provided by the Enemy class.

public class Laser : MonoBehaviour
{
// Additional class variables and methods for context
public void SetPickupPos(Vector3 powPos)
{
_actualPowerupPos = powPos;
}
public void PickupBehavior(bool status)
{
_pickupBehavior = status;
}
void FirePowerup(Vector3 powerupPos)
{
_laserRigidbody.AddForce(powerupPos * 20f);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Powerup")
{
Destroy(other.gameObject);
_enemy.GetComponent<Enemy>().PowerupDestroyed(true);
Debug.Log("PowerUp destroyed");
}
}
}

Implementing enemy pickup destruction behavior adds a strategic layer to gameplay, encouraging players to quickly secure pickups before they are destroyed by enemies. This behavior not only enriches the game’s dynamics but also showcases the flexibility of Unity’s system in creating complex AI behaviors. By following the outlined steps and understanding the provided code, developers can integrate this engaging feature into their games, offering players a more immersive and challenging experience.

--

--

Damian Dąbrowski
Damian Dąbrowski

Written by Damian Dąbrowski

Hi, I’m Damian, an Electrical Power Engineer, who loves building AI powered apps.

No responses yet