*** Trigger Collider2D event only once ***

Hello there,

I have some difficulties executing a Collision2D trigger event only once. For a top-down 2D game with melee fight, I am using a Capsule Collider 2D for dealing damage to the enemy. Whenever the attack key (‘Space’) is pressed, the Capsule Collider2D attached to the player is activated and any enemy within the range of this collider is damaged.

Now this part of the script works fine. The problem is, that when the OnTriggerEnter2D event is triggered, it should be executed only once and decrease enemy health by 1. The code in the script looks like this:

public class enemyControl : MonoBehaviour {

	public int enemyHealth = 3;

	public GameObject enemy;

	public SpriteRenderer enemySprite;
	public Sprite enemyDead;

	public Collider2D enemyCollider;
	public Collider2D damageCollider;
	public Collider2D playerAttack;

	void OnTriggerEnter2D (Collider2D playerAttack) {

		if (playerAttack.tag == "plrAttack") {

				enemyHealth-=1;

		}
	}

	void Start () {
		
		enemySprite = GetComponent<SpriteRenderer> ();
	}

	void Update () {
   
		if (enemyHealth <= 0) 
		{

			enemySprite.sprite = enemyDead;
			enemyCollider.enabled = false;
		}
		
	}
}

The problem is that whenever I press the attack key (‘Space’), the collision trigger starts a very fast loop that decreases the enemy’s health to zero immediately. Is there some way to break this “loop” after only one execution?

I have to add, that I have searched the forum for possible solutions, including using OnTriggerExit and introducing a boolean value for checking the state of the trigger, but none of that seemed to work as the loop just goes on.

The attack action script looks like this, btw.:

if (Input.GetKey (KeyCode.Space) && !moving) {
			playerAnimator.SetBool ("isAttacking", true);
			attack.enabled = true;
			fighting = true;
		}

“attack.enabled = true” is the row that enables the Capsule Collider 2D that is dealing the damage.

I would really appreciate any help or hints as I am stuck with this unnerving problem for days…

Many thanks!

Try making a new bool to check if collider has been triggered on each hit.

public bool hitCheck;

void OnTriggerEnter2D (Collider2D playerAttack) {
 
         if (playerAttack.tag == "plrAttack" && !hitCheck) {
 
                 enemyHealth-=1;
                 hitCheck = true;
 
         }
     }

set hitCheck to false again on your Input Space for example.

If you’ve tried using a bool state to track if it’s been hit that frame or not, and it still doesn’t work, the problem might be elsewhere. Have you tried using the debugger and putting a breakpoint in the OnTrigger method, then seeing how many times it’s called? Or even just printing something to the console inside the method.

@unidad2pete
I think I have found the root problem why the boolean checker value (“takingDamage”) won’t flip back to “false” when hitting the attack button.

All the enemies are instantiated as clones from a prefab at random points inside the procedurally generated dungeon. Even though I reference the GameObject / prefab in the script, the variable change won’t apply to the clones. I have searched through the forum, but couldn’t find any viable solution.

Could you please look at my below script and provide me with any hints regarding how could I reference the prefab clone variables?

Many thanks!

 /* I have removed some of this script for now as it is irrelevant to the question */

public class playerControl : MonoBehaviour {


	public GameObject enemy;
	enemyControl ec;  //for referencing another script 

	public Animator playerAnimator;
	private bool moving = false;
	private bool fighting = false;

	public Collider2D attack; // referencing the attack collider

	void Start () {

		playerAnimator = GetComponent<Animator>();
		playerAnimator.SetBool ("isMoving", false);
		playerAnimator.SetBool ("isAttacking", false);

		attack.enabled = false;
		ec = enemy.GetComponent<enemyControl> ();


	}

	void Update ()
	{

if (Input.GetKey (KeyCode.Space) && !moving) {
			ec.takingDamage = false; //it won't flip back to false on the clones!
			playerAnimator.SetBool ("isAttacking", true);
			attack.enabled = true;
			fighting = true;

		}

	}
}