One enemy triggers all the enemies

When player get close to an enemy and the enemy starts attacking the player, all the enemies throughout the map start their attacking animation. Player’s health get deducted and go to negatives. Player never dies but keeps getting hit by enemies that are not even close to him. Here are the two scripts used on enemies.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ZombieFollow : MonoBehaviour {
	
	public GameObject player;
	public float targetDistance;
	public float allowedRange = 10;
	public GameObject enemy;
	public float enemySpeed;
	public static int attackTrigger;
	public RaycastHit shot;
	
	public int isAttacking;
	public GameObject screenFlash;
	public AudioSource hurt01;
	public AudioSource hurt02;
	public AudioSource hurt03;
	public int painSound;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		transform.LookAt (player.transform);
		if (Physics.Raycast (transform.position, transform.TransformDirection (Vector3.forward), out shot)) {
			targetDistance = shot.distance;
			if (targetDistance < allowedRange) {
				enemySpeed = 0.6f;
				if (attackTrigger == 0) {
					enemy.GetComponent<Animation> ().Play ("Walking");					
					GetComponent<Rigidbody>().AddForce(transform.forward * enemySpeed * Time.deltaTime);
				}
			} else {
				enemySpeed = 0;
				enemy.GetComponent<Animation> ().Play ("Idle");
			}
		}

		if (attackTrigger == 1) {
			if (isAttacking == 0) {
				StartCoroutine(EnemyDamage());
			}
			enemySpeed = 0;
			enemy.GetComponent<Animation>().Play("Attacking");
		}
	}
	
	void OnTriggerEnter() {
		attackTrigger = 1;
	}

	void OnTriggerExit() {
		attackTrigger = 0;
	}
	
	IEnumerator EnemyDamage() {
		isAttacking = 1;
		painSound = Random.Range (1, 4);
		yield return new WaitForSeconds (0.9f);
		screenFlash.SetActive (true);
		GlobalHealth.playerHealth -= 10;
		if (painSound == 1) {
			hurt01.Play ();
		}
		if (painSound == 2) {
			hurt02.Play ();
		}
		if (painSound == 3) {
			hurt03.Play ();
		}
		yield return new WaitForSeconds (0.05f);
		screenFlash.SetActive (false);
		yield return new WaitForSeconds (1);
		isAttacking = 0;

	}

}

Second one which is responsible for enemy death

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyScript : MonoBehaviour {

    public int enemyHealth = 10;
    public GameObject zombie; 

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        if (enemyHealth <= 0) {
			this.GetComponent<ZombieFollow>().enabled = false;
			zombie.GetComponent<Animation>().Play("Dying");
			StartCoroutine(EndZombie());            
        }
    }

    void DeductPoints(int damageAmount) {
        enemyHealth -= damageAmount;        
    }
    
    IEnumerator EndZombie() {
		yield return new WaitForSeconds(3);
		Destroy(gameObject);
	}

}

I have no idea how Physics.Raycast () and transform.TransformDirection() really work, but I was not expecting to see Vector3.foward, but maybe transform.foward instead. Again, I don’t know how it works, just look at the documentation.


Also make sure the targetDistance has a value that makes sense for each enemy. Debug.Log(gameobject.Name +" "+ targetDistance), pause the game and calculate the distance yourself. Maybe you are not calculating the right distance…


Look at Nocktion suggestion.


I noticed that attackTrigger is static. This means that ALL object instances of the ZombieFollow class wil share the same value. This is a big part of the bug.


Irrelevant to the current problem, but please don’t use GetComponent inside update , it’ll work, but it’ll kill your performance. Do that in Start() and store the components in member variables.

All enemies start attack because you use static variable.

public static int attackTrigger;

static variables store same value for all object. So when you set attackTrigger = 1 for one object , other objects script’s attackTrigger field change