How do I trigger an event (health loss) only once?

I have a one-on-one fighting style game.

I have sphere colliders for the weapons and various body parts.
Using this code, I can trigger the ‘hit’ animation,
if (weaponCollider.bounds.Intersects(bodCollider.bounds))
{
if (animation.IsPlaying(“AnnaHammerJab”) &&
animation[“AnnaHammerJab”].time > .5f)
{
Debug.Log(“-1 health”);

            }
        }

And this is fine, my problem is when I look at the Debug.log, it fires repeatedly, which is what I assume health code would do.

If the weapon sphere skims the hit sphere, it only logs for a frame or two, at close range, it fires for longer.
This would mean that more health would be lost, the longer the two spheres intersect.

What I would like is for the health to be subtracted only once (in this case, the Debug.log is the stand in for health code.

Is there a way to trigger it only once per intersection?

Depending on how you programmed your game you may want to use Animation Events. A good tutorial can be seen for that here:

This would allow you to call functions based on the animation timing of your characters and could eliminate the possibility of multiple hits.

If your game is a 2D street fighter type game this may be preferable. So when they hit the right spot of their attack animation it would call the animation event and then at that point your function could check if the collision occurs at that exact moment to determine what happens.

However if it is more of a 3d fighting game where you should be able to hit them at multiple points during an attack swing I would recommend some kind of control bool like the other user suggested.

You must be careful with these though because they do have potential for more bugs than an Animation Event. For example if the player wiggles back and forth very quickly while they are attacking they may be able to exploit the collision detection and still execute multiple hits in one strike by entering and leaving the collision zone. However you could also eliminate that behavior with additional variable checks similar to what the other user posted above.

So in summarry:

If you want super easy animations to deal with that call a function once per animation I would use an Animation Event.

If you want really realistic combat that can detect all kinds of different moments of combat whether the strike if just starting or nearly complete you should use something like the failSafeVariables listed above, and be prepared to potentially use multiple conditions to control it depending on how your game works.

I don’t know what the proper name of it would be, but I personally would use what I would call a “fail safe” variable.

Try something like:

using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour {
	private bool failSafeVar = true;

	void Update () {
		if (weaponCollider.bounds.Intersects(bodCollider.bounds)) {
			if (failSafeVar == true){
				if (animation.IsPlaying("AnnaHammerJab") && animation["AnnaHammerJab"].time > .5f) { 
					failSafeVar = false;
					Debug.Log("-1 health");
				}
			}
		}
		else {
			failSafeVar = true;
		}
	}
}

The idea is that while the two colliers were in contact, the failSafeVar would only be true to allow damage once otherwise it would be false.

The other option is the OnCollisionEnter method that is built into the system…just toss it down in your script and it only gets called the one time that the two intersect.

void OnCollisionEnter(Collider col)
{
     if (col.gameObject.tag = "[ENTER TAG HERE]")
          Debug.Log("-1 Health");

}

Obviously the conditional statement is up to you, but I would consider applying a tag to each of the objects (projectiles) you’ll be shooting. If this method is invoked on any of the scripts attached to the target, it result in only one subtraction each time/ You could also trigger the animation in the same statement.