The health of all soldiers goes down when 1 soldier get's hit (Please help)

Well, this is a big code, but i hope someone can see what’s wrong with my script. The problem is that when 1 soldier gets hit al the soldiers get’s damage, and ofcourse isn’t this what i want. i dont know if it’s the AI script or the Sword script. But i place them both.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Soldier_Black_Knights : MonoBehaviour {
    //The nav mesh agent
    public NavMeshAgent agent;
   
    //The target
    public GameObject target;
    //Enemies
    public List<GameObject> enemies;
    //List with allies
    public List<GameObject> Allies;
    //Closest enemy
    public GameObject Closest;
    //sword
    public GameObject sword;
   
   
    //the animator
    public Animator anim;
   
    //The number of closest enemy
    public int Closest_Number;
    //The Attackrange varaible
    public int Attack_Range;
    //The shoot range
    public int Shoot_Range;
    //the hit range variable
    public int Hit_Range;
    //The number of weapon it has equiped
    public int weapon_num;
    //damage
    public int damage;
    //health
    public  int health;
    public int Health;
   
    //The distance between all enemies and soldier
    public List<float> Distance;
    //The closest distance
    public float Closest_Distance;
   
    //List with all the tags
    public string Tags;
   
    //this is a boolean that wil be true if it is the first time that the game is launched
    public bool First_Time;
    //When the soldier is alive
    public bool alive;
    //this boolean is used to say if the distance has been calculated
    public bool Distance_Calculated;
    //this boolean is used to say if the closed enemy has been calculated
    public bool Closest_Calculated;
    //can swing
    public static bool Can_Swing;
    //is swinging
    public  bool Is_Swinging;
    //for walking
    public bool walking;
    //can walk
    public bool can_walk;
    //die variable
    public bool die;
    //can
    public bool Monitor_Can_Swing;
   
    public RaycastHit hit;
   
    public Soldier_Black_Knights_Sword swingtest;

    public int combat_style;
   
   
    void Awake(){
        health = 100;
        damage = 0;
        can_walk = true;
        Can_Swing = true;
        die = true;
        swingtest = (Soldier_Black_Knights_Sword) sword.GetComponent(typeof(Soldier_Black_Knights_Sword));
    }   
    // Use this for initialization
    void Start () {
        //calls the function to set all the variable's
        Set_Variable();
        alive = true;
        agent = this.GetComponent<NavMeshAgent>();
        //it says automaticly that the game has been launched for the first time, because there will other loaded if it is not
        First_Time = true;
        //Cal the function for adding all the tags
        Add_Tag();
        //set enemy ally
        Set_Enemy_Ally();
        //alive
        Alive();
        //can swing
        Can_Swing = true;

        can_walk = true;
        anim = GetComponent<Animator>();
       
       
       
    }
   
    void Set_Variable(){
        //The hitrange variable will be set to 2 meter
        Hit_Range = 2;
        //the attack range variable will be set to 10 meters
        Attack_Range = 50;
        //closest number wil be set to -1
        Closest_Number = -1;
    }
   
    // Update is called once per frame
    void Update () {
        //When the Soldier is alive
        if(alive == true){
            //Then it will cal the function Alive
            Alive();
        }
       
       
        Health = health;
       
        if(health <= 0){
            alive = false;
            if(die == true){
                anim.Play("Front_Attack_Side_neck_stab_Finish_01");
                die = false;
                StartCoroutine (Tmer ());
               
            }
        }
       
        Monitor_Can_Swing = Can_Swing;
    }
   
    //This function will add al the tag's
    void Add_Tag(){
       
       
    }
   
    //This function will set all the enemies and allies
    void Set_Enemy_Ally(){
        //when it is the first time that the game has been launched
        if(First_Time == true){
            //Then it will set the tag's
            enemies.AddRange(GameObject.FindGameObjectsWithTag("Friendly"));
           
            Distance.AddRange(new float[enemies.Count]);
        }
    }
   
    //This will call all the functions when a soldier is alive
    void Alive(){
        Scan_For_Death();
        if(enemies.Count > 0){
        //It will call a function for the attack part, the soldier will only attack when the enemy is close
       
        //the scan function
        Scan_Attack();
            Scan_For_Death();
        //WHen the closest has been calculated
        if(Closest_Calculated == true){
                Distance_Calculate();
            //Then it will cal the function for scanning if the enemy is close enough to attack
            Scan_Distance_For_Attack();
        }
        if(Closest_Calculated){
            if(Distance[Closest_Number] < Hit_Range && Can_Swing == true && Is_Swinging == false){
                StartCoroutine(Swing ());
            }
        }
        }

        if(enemies.Count == 0){
            Closest_Calculated = false;
            enemies.AddRange(GameObject.FindGameObjectsWithTag("Friendly"));
        }
       
        //when is swinging is false, then it wil turn into idle state
        if(Is_Swinging == false  && walking == false ){
            anim.Play("Idle_Ready");
        }

       
       
    }

    void Scan_For_Death(){
        for(int i = 0; i<enemies.Count; i++){
            if(enemies[i].tag == "Dead"){
                enemies.RemoveAt(i);
            }


        }
    if(Closest_Calculated == true){
        if(Closest.tag == "Dead"){
            Closest = null;
                Closest_Calculated = false;
        }
        }


    }
   
    //The function for calculating the distance
    void Distance_Calculate(){
        //this is a loop, and i used it to calculate each enemies distance
        for(int i = 0; i < enemies.Count; i++){
            //This wil calculate the distance
            Distance[i] = Vector3.Distance(transform.position, enemies[i].transform.position);
            //When all the distances has been calculated
            if(i == enemies.Count){
                //the boolean distance_calculated will be true
                Distance_Calculated = true;
            }
        }
        if(Closest_Calculated == true){
            Closest_Distance = Vector3.Distance(transform.position, Closest.transform.position);
        }
       
    }
   
    //This function is for scanning if the enemie is close enough to attack
    void Scan_Attack(){
        //It wil start with a loop
        for(int i = 0; i < enemies.Count; i++){
            //Here it will start comparing
            if(Closest_Number == -1 || Closest_Distance > Distance[i]){
                Closest = enemies[i];
                Closest_Number = i;
                Closest_Distance = Distance[i];
                Closest_Calculated = true;
            }
        }
    }
   
    //This function is for comparing the distance to the attack range
    void Scan_Distance_For_Attack(){
        //If the distance is closer then the attack range
        if(Closest_Distance < Attack_Range && Closest_Distance > 1.5 && can_walk == true){
            //then it will set the as target, the closest enemy
            target = Closest;
            agent.SetDestination(target.transform.position);
            agent.Resume();
        }
       
        if(Closest_Distance <= 1.5){
            agent.Stop();
        }
        if(transform.forward.magnitude > 1 && can_walk == true){
            walking = true;
            anim.Play("Basic_Run_01");
        }
       
        if(transform.forward.magnitude <= 0){
            walking = false;
        }
        //when not
        if(can_walk == false){
            //when the enemy is not in the right range
            agent.SetDestination(transform.position);
        }
    }
   
    IEnumerator Swing(){
        //it wil only look at the target
        transform.LookAt(Closest.transform.position);
        if(Can_Swing == true && Is_Swinging == false){
            //then it will play the attack animation
            yield return new WaitForSeconds(1.0f);
            anim.Play("Attack1");
            walking = false;
            can_walk = false;
            //when the weapon collides or almost collides
           
        }
       
        Is_Swinging = true;
        Can_Swing = false;
        StartCoroutine (Timer ());
    }
   
   
    IEnumerator Timer(){
       
        yield return new WaitForSeconds(2.0f);
       
        Can_Swing = true;
        Is_Swinging = false;
        can_walk = true;
        swingtest.hite = false;
    }
   
    void ApplyDamage(int damage){
        Soldier_Black_Knights biear = (Soldier_Black_Knights) gameObject.GetComponent(typeof(Soldier_Black_Knights));
        biear.health -= damage;
    }
   
    IEnumerator Tmer(){
        yield return new WaitForSeconds(1.5f);
        anim.StopPlayback();
        yield return new WaitForSeconds(2.0f);
        transform.tag = "Dead";
    }
}



//this is the sword script 
using UnityEngine;
using System.Collections;

public class Soldier_Black_Knights_Sword : MonoBehaviour {

    public RaycastHit hit;
    public int damage;
    public bool hite;
    public float Old_Y;
    public static bool Taken_Damage;
    public static bool good;
    public GameObject soldier1;
    public Soldier_Black_Knights otherr;
    public bool test;
    public GameObject Blood;
    public Vector3 BLood_Location;
    // Use this for initialization
    void Start () {
        Taken_Damage = false;
        damage = 5;
        Old_Y = 0.0f;
        hite = false;
        otherr = soldier1.GetComponent<Soldier_Black_Knights>();
        Blood = soldier1.transform.Find("BloodSplat").gameObject;
    }
   
    // Update is called once per frame
    void Update () {
       
        test = otherr.Is_Swinging;
        if(test == true && hite == false){
            if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit)){
                float distance = hit.distance;
                if(hit.transform.tag == "Friendly"){
                    Debug.Log ("Friendly has been hit");
                    hite = true;
                    good = true;
                    hit.transform.SendMessage("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
                    BLood_Location.x = hit.transform.position.x;
                    BLood_Location.y = hit.transform.position.y;
                    BLood_Location.z = hit.transform.position.z;
                    Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);
                    Blood.SetActive(true);
                    StartCoroutine(Blood_Timer());
                }
               
                Old_Y = hit.transform.position.y;
                StartCoroutine(Damage_Timer());
            }
           
        }
        if(good == true){
           
        }
    }
   
    IEnumerator Damage_Timer(){
        yield return new WaitForSeconds(2.0f);
       
    }

    IEnumerator Blood_Timer(){
        yield return new WaitForSeconds(1.0f);
        Blood.SetActive(false);
    }
   

}

I found a fix, but it’s not a simple and effective one.

using UnityEngine;
using System.Collections;

public class Soldier_Black_Knights_Sword : MonoBehaviour {

    public RaycastHit hit;
    public int damage;
    public bool hite;
    public float Old_Y;
    public static bool Taken_Damage;
    public static bool good;
    public GameObject soldier1;
    public Soldier_Black_Knights otherr;
    public bool test;
    public GameObject Blood;
    public Vector3 BLood_Location;
    // Use this for initialization
    void Start () {
        Taken_Damage = false;
        damage = 5;
        Old_Y = 0.0f;
        hite = false;
        otherr = soldier1.GetComponent<Soldier_Black_Knights>();
        Blood = soldier1.transform.Find("BloodSplat").gameObject;

    }
   
    // Update is called once per frame
    void Update () {
       
        test = otherr.Is_Swinging;
        if(test == true && hite == false){
            if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit)){
                float distance = hit.distance;
                if(hit.transform.tag == "White_Soldier"){
                    Debug.Log ("Friendly has been hit");
                    hite = true;
                    good = true;
                    Soldier1_AI_Test White_soldier = (Soldier1_AI_Test) hit.transform.GetComponent(typeof(Soldier1_AI_Test));
                    White_soldier.health -= damage;
                    BLood_Location.x = hit.transform.position.x;
                    BLood_Location.y = hit.transform.position.y;
                    BLood_Location.z = hit.transform.position.z;
                    Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);
                    Blood.SetActive(true);
                    StartCoroutine(Blood_Timer());
                }
               
                Old_Y = hit.transform.position.y;
                StartCoroutine(Damage_Timer());
            }
           
        }
        if(good == true){
           
        }
    }
   
    IEnumerator Damage_Timer(){
        yield return new WaitForSeconds(2.0f);
       
    }

    IEnumerator Blood_Timer(){
        yield return new WaitForSeconds(1.0f);
        Blood.SetActive(false);
    }
   

}

Why are you using two variables for the health? Looks like really bad design here…

however: where is the code where the soldier loses health?

I see the word static. That’s always a good hint.

The other common cause is checking if a raycast hit in Update on every soldier.

Your codes too long for me to read through everything and see, but those are common causes.

Well, i have changed a lot today and health was a static variable first, but because i wanted to acces it i changed it back to a non static but didn’t delete the Health. The Health was just a variable so that i could check in the game if the Health just did what it has to do.

The code is in the function ApplyDamage()

ok, lots of clutter in there…

if you are going to post more than one script into the forum, please use more than one code block. It makes it far easier to understand what you are showing us.

if you are going to use variables try to keep the same naming convention, you’ve got some all lower case, some capitalised first letters. Makes reading your code harder because we can’t easily see what is a variable and what is a function. The traditional version is functions Captialised, variables all lowerCase. You have some variables concatenated, some with underscores etc. try to be consistent. Again, traditionally it’s something like this:

thisIsAVariableWithMoreThanOneWordInItsName

(tradition is less important than consistency, most of us can adapt to whatever system you use so long as it’s all the same)

you don’t need to use GetComponent to get the script you are currently within, just use the variable

make your variable names descriptive of what they are, there are several instances in there where the variable name is totally misleading, again getting others to understand your code and help you requires them to be able to quickly understand your code, and if you come back to it in 6 months you’re probably not going to remember what things were as well.
i.e.

public Soldier_Black_Knights_Sword swingtest;

swingtest suggests a boolean to check something about a swing… it’s actually the sword script attached to the gameobject. Not intuitive further down when it’s being used.

GetComponent() is far shorter than (ComponentType) GetComponent(typeOf(ComponentType)) :smile:

static variables are class level variables and shared across all instances, you don’t want to use them for things like checks/locks/health values etc.

you seem to like doing things the very long way

BLood_Location.x = hit.transform.position.x;
BLood_Location.y = hit.transform.position.y;
BLood_Location.z = hit.transform.position.z;
Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);

rather than

Blood.transform.position = hit.transform.position;

you use 3 variables to break down and then reform a Vector3 without any alteration, wasteful on resources and makes the code more bulky and harder to read/understand

test = otherr.Is_Swinging;
if(test == true && ...)
{...}

rather than

if(otherr.Is_Swinging && ...)
{...}

you never use test again, there is no need to cache it in a variable, it’s wasteful resource wise and makes it harder to read and understand your code

Yes youre right, but i had some errors with the Blood.transform.position = hit.transform.position, so i tried it in a different way (the long way).