Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'Scripting' started by briyan, Aug 12, 2015.

  1. briyan

    briyan

    Joined:
    Jan 13, 2015
    Posts:
    52
    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.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. public class Soldier_Black_Knights : MonoBehaviour {
    5.     //The nav mesh agent
    6.     public NavMeshAgent agent;
    7.    
    8.     //The target
    9.     public GameObject target;
    10.     //Enemies
    11.     public List<GameObject> enemies;
    12.     //List with allies
    13.     public List<GameObject> Allies;
    14.     //Closest enemy
    15.     public GameObject Closest;
    16.     //sword
    17.     public GameObject sword;
    18.    
    19.    
    20.     //the animator
    21.     public Animator anim;
    22.    
    23.     //The number of closest enemy
    24.     public int Closest_Number;
    25.     //The Attackrange varaible
    26.     public int Attack_Range;
    27.     //The shoot range
    28.     public int Shoot_Range;
    29.     //the hit range variable
    30.     public int Hit_Range;
    31.     //The number of weapon it has equiped
    32.     public int weapon_num;
    33.     //damage
    34.     public int damage;
    35.     //health
    36.     public  int health;
    37.     public int Health;
    38.    
    39.     //The distance between all enemies and soldier
    40.     public List<float> Distance;
    41.     //The closest distance
    42.     public float Closest_Distance;
    43.    
    44.     //List with all the tags
    45.     public string Tags;
    46.    
    47.     //this is a boolean that wil be true if it is the first time that the game is launched
    48.     public bool First_Time;
    49.     //When the soldier is alive
    50.     public bool alive;
    51.     //this boolean is used to say if the distance has been calculated
    52.     public bool Distance_Calculated;
    53.     //this boolean is used to say if the closed enemy has been calculated
    54.     public bool Closest_Calculated;
    55.     //can swing
    56.     public static bool Can_Swing;
    57.     //is swinging
    58.     public  bool Is_Swinging;
    59.     //for walking
    60.     public bool walking;
    61.     //can walk
    62.     public bool can_walk;
    63.     //die variable
    64.     public bool die;
    65.     //can
    66.     public bool Monitor_Can_Swing;
    67.    
    68.     public RaycastHit hit;
    69.    
    70.     public Soldier_Black_Knights_Sword swingtest;
    71.  
    72.     public int combat_style;
    73.    
    74.    
    75.     void Awake(){
    76.         health = 100;
    77.         damage = 0;
    78.         can_walk = true;
    79.         Can_Swing = true;
    80.         die = true;
    81.         swingtest = (Soldier_Black_Knights_Sword) sword.GetComponent(typeof(Soldier_Black_Knights_Sword));
    82.     }  
    83.     // Use this for initialization
    84.     void Start () {
    85.         //calls the function to set all the variable's
    86.         Set_Variable();
    87.         alive = true;
    88.         agent = this.GetComponent<NavMeshAgent>();
    89.         //it says automaticly that the game has been launched for the first time, because there will other loaded if it is not
    90.         First_Time = true;
    91.         //Cal the function for adding all the tags
    92.         Add_Tag();
    93.         //set enemy ally
    94.         Set_Enemy_Ally();
    95.         //alive
    96.         Alive();
    97.         //can swing
    98.         Can_Swing = true;
    99.  
    100.         can_walk = true;
    101.         anim = GetComponent<Animator>();
    102.        
    103.        
    104.        
    105.     }
    106.    
    107.     void Set_Variable(){
    108.         //The hitrange variable will be set to 2 meter
    109.         Hit_Range = 2;
    110.         //the attack range variable will be set to 10 meters
    111.         Attack_Range = 50;
    112.         //closest number wil be set to -1
    113.         Closest_Number = -1;
    114.     }
    115.    
    116.     // Update is called once per frame
    117.     void Update () {
    118.         //When the Soldier is alive
    119.         if(alive == true){
    120.             //Then it will cal the function Alive
    121.             Alive();
    122.         }
    123.        
    124.        
    125.         Health = health;
    126.        
    127.         if(health <= 0){
    128.             alive = false;
    129.             if(die == true){
    130.                 anim.Play("Front_Attack_Side_neck_stab_Finish_01");
    131.                 die = false;
    132.                 StartCoroutine (Tmer ());
    133.                
    134.             }
    135.         }
    136.        
    137.         Monitor_Can_Swing = Can_Swing;
    138.     }
    139.    
    140.     //This function will add al the tag's
    141.     void Add_Tag(){
    142.        
    143.        
    144.     }
    145.    
    146.     //This function will set all the enemies and allies
    147.     void Set_Enemy_Ally(){
    148.         //when it is the first time that the game has been launched
    149.         if(First_Time == true){
    150.             //Then it will set the tag's
    151.             enemies.AddRange(GameObject.FindGameObjectsWithTag("Friendly"));
    152.            
    153.             Distance.AddRange(new float[enemies.Count]);
    154.         }
    155.     }
    156.    
    157.     //This will call all the functions when a soldier is alive
    158.     void Alive(){
    159.         Scan_For_Death();
    160.         if(enemies.Count > 0){
    161.         //It will call a function for the attack part, the soldier will only attack when the enemy is close
    162.        
    163.         //the scan function
    164.         Scan_Attack();
    165.             Scan_For_Death();
    166.         //WHen the closest has been calculated
    167.         if(Closest_Calculated == true){
    168.                 Distance_Calculate();
    169.             //Then it will cal the function for scanning if the enemy is close enough to attack
    170.             Scan_Distance_For_Attack();
    171.         }
    172.         if(Closest_Calculated){
    173.             if(Distance[Closest_Number] < Hit_Range && Can_Swing == true && Is_Swinging == false){
    174.                 StartCoroutine(Swing ());
    175.             }
    176.         }
    177.         }
    178.  
    179.         if(enemies.Count == 0){
    180.             Closest_Calculated = false;
    181.             enemies.AddRange(GameObject.FindGameObjectsWithTag("Friendly"));
    182.         }
    183.        
    184.         //when is swinging is false, then it wil turn into idle state
    185.         if(Is_Swinging == false  && walking == false ){
    186.             anim.Play("Idle_Ready");
    187.         }
    188.  
    189.        
    190.        
    191.     }
    192.  
    193.     void Scan_For_Death(){
    194.         for(int i = 0; i<enemies.Count; i++){
    195.             if(enemies[i].tag == "Dead"){
    196.                 enemies.RemoveAt(i);
    197.             }
    198.  
    199.  
    200.         }
    201.     if(Closest_Calculated == true){
    202.         if(Closest.tag == "Dead"){
    203.             Closest = null;
    204.                 Closest_Calculated = false;
    205.         }
    206.         }
    207.  
    208.  
    209.     }
    210.    
    211.     //The function for calculating the distance
    212.     void Distance_Calculate(){
    213.         //this is a loop, and i used it to calculate each enemies distance
    214.         for(int i = 0; i < enemies.Count; i++){
    215.             //This wil calculate the distance
    216.             Distance[i] = Vector3.Distance(transform.position, enemies[i].transform.position);
    217.             //When all the distances has been calculated
    218.             if(i == enemies.Count){
    219.                 //the boolean distance_calculated will be true
    220.                 Distance_Calculated = true;
    221.             }
    222.         }
    223.         if(Closest_Calculated == true){
    224.             Closest_Distance = Vector3.Distance(transform.position, Closest.transform.position);
    225.         }
    226.        
    227.     }
    228.    
    229.     //This function is for scanning if the enemie is close enough to attack
    230.     void Scan_Attack(){
    231.         //It wil start with a loop
    232.         for(int i = 0; i < enemies.Count; i++){
    233.             //Here it will start comparing
    234.             if(Closest_Number == -1 || Closest_Distance > Distance[i]){
    235.                 Closest = enemies[i];
    236.                 Closest_Number = i;
    237.                 Closest_Distance = Distance[i];
    238.                 Closest_Calculated = true;
    239.             }
    240.         }
    241.     }
    242.    
    243.     //This function is for comparing the distance to the attack range
    244.     void Scan_Distance_For_Attack(){
    245.         //If the distance is closer then the attack range
    246.         if(Closest_Distance < Attack_Range && Closest_Distance > 1.5 && can_walk == true){
    247.             //then it will set the as target, the closest enemy
    248.             target = Closest;
    249.             agent.SetDestination(target.transform.position);
    250.             agent.Resume();
    251.         }
    252.        
    253.         if(Closest_Distance <= 1.5){
    254.             agent.Stop();
    255.         }
    256.         if(transform.forward.magnitude > 1 && can_walk == true){
    257.             walking = true;
    258.             anim.Play("Basic_Run_01");
    259.         }
    260.        
    261.         if(transform.forward.magnitude <= 0){
    262.             walking = false;
    263.         }
    264.         //when not
    265.         if(can_walk == false){
    266.             //when the enemy is not in the right range
    267.             agent.SetDestination(transform.position);
    268.         }
    269.     }
    270.    
    271.     IEnumerator Swing(){
    272.         //it wil only look at the target
    273.         transform.LookAt(Closest.transform.position);
    274.         if(Can_Swing == true && Is_Swinging == false){
    275.             //then it will play the attack animation
    276.             yield return new WaitForSeconds(1.0f);
    277.             anim.Play("Attack1");
    278.             walking = false;
    279.             can_walk = false;
    280.             //when the weapon collides or almost collides
    281.            
    282.         }
    283.        
    284.         Is_Swinging = true;
    285.         Can_Swing = false;
    286.         StartCoroutine (Timer ());
    287.     }
    288.    
    289.    
    290.     IEnumerator Timer(){
    291.        
    292.         yield return new WaitForSeconds(2.0f);
    293.        
    294.         Can_Swing = true;
    295.         Is_Swinging = false;
    296.         can_walk = true;
    297.         swingtest.hite = false;
    298.     }
    299.    
    300.     void ApplyDamage(int damage){
    301.         Soldier_Black_Knights biear = (Soldier_Black_Knights) gameObject.GetComponent(typeof(Soldier_Black_Knights));
    302.         biear.health -= damage;
    303.     }
    304.    
    305.     IEnumerator Tmer(){
    306.         yield return new WaitForSeconds(1.5f);
    307.         anim.StopPlayback();
    308.         yield return new WaitForSeconds(2.0f);
    309.         transform.tag = "Dead";
    310.     }
    311. }
    312.  
    313.  
    314.  
    315. //this is the sword script
    316. using UnityEngine;
    317. using System.Collections;
    318.  
    319. public class Soldier_Black_Knights_Sword : MonoBehaviour {
    320.  
    321.     public RaycastHit hit;
    322.     public int damage;
    323.     public bool hite;
    324.     public float Old_Y;
    325.     public static bool Taken_Damage;
    326.     public static bool good;
    327.     public GameObject soldier1;
    328.     public Soldier_Black_Knights otherr;
    329.     public bool test;
    330.     public GameObject Blood;
    331.     public Vector3 BLood_Location;
    332.     // Use this for initialization
    333.     void Start () {
    334.         Taken_Damage = false;
    335.         damage = 5;
    336.         Old_Y = 0.0f;
    337.         hite = false;
    338.         otherr = soldier1.GetComponent<Soldier_Black_Knights>();
    339.         Blood = soldier1.transform.Find("BloodSplat").gameObject;
    340.     }
    341.    
    342.     // Update is called once per frame
    343.     void Update () {
    344.        
    345.         test = otherr.Is_Swinging;
    346.         if(test == true && hite == false){
    347.             if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit)){
    348.                 float distance = hit.distance;
    349.                 if(hit.transform.tag == "Friendly"){
    350.                     Debug.Log ("Friendly has been hit");
    351.                     hite = true;
    352.                     good = true;
    353.                     hit.transform.SendMessage("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
    354.                     BLood_Location.x = hit.transform.position.x;
    355.                     BLood_Location.y = hit.transform.position.y;
    356.                     BLood_Location.z = hit.transform.position.z;
    357.                     Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);
    358.                     Blood.SetActive(true);
    359.                     StartCoroutine(Blood_Timer());
    360.                 }
    361.                
    362.                 Old_Y = hit.transform.position.y;
    363.                 StartCoroutine(Damage_Timer());
    364.             }
    365.            
    366.         }
    367.         if(good == true){
    368.            
    369.         }
    370.     }
    371.    
    372.     IEnumerator Damage_Timer(){
    373.         yield return new WaitForSeconds(2.0f);
    374.        
    375.     }
    376.  
    377.     IEnumerator Blood_Timer(){
    378.         yield return new WaitForSeconds(1.0f);
    379.         Blood.SetActive(false);
    380.     }
    381.    
    382.  
    383. }
    384.  
    385.  
     
  2. briyan

    briyan

    Joined:
    Jan 13, 2015
    Posts:
    52
    I found a fix, but it's not a simple and effective one.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Soldier_Black_Knights_Sword : MonoBehaviour {
    5.  
    6.     public RaycastHit hit;
    7.     public int damage;
    8.     public bool hite;
    9.     public float Old_Y;
    10.     public static bool Taken_Damage;
    11.     public static bool good;
    12.     public GameObject soldier1;
    13.     public Soldier_Black_Knights otherr;
    14.     public bool test;
    15.     public GameObject Blood;
    16.     public Vector3 BLood_Location;
    17.     // Use this for initialization
    18.     void Start () {
    19.         Taken_Damage = false;
    20.         damage = 5;
    21.         Old_Y = 0.0f;
    22.         hite = false;
    23.         otherr = soldier1.GetComponent<Soldier_Black_Knights>();
    24.         Blood = soldier1.transform.Find("BloodSplat").gameObject;
    25.  
    26.     }
    27.    
    28.     // Update is called once per frame
    29.     void Update () {
    30.        
    31.         test = otherr.Is_Swinging;
    32.         if(test == true && hite == false){
    33.             if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit)){
    34.                 float distance = hit.distance;
    35.                 if(hit.transform.tag == "White_Soldier"){
    36.                     Debug.Log ("Friendly has been hit");
    37.                     hite = true;
    38.                     good = true;
    39.                     Soldier1_AI_Test White_soldier = (Soldier1_AI_Test) hit.transform.GetComponent(typeof(Soldier1_AI_Test));
    40.                     White_soldier.health -= damage;
    41.                     BLood_Location.x = hit.transform.position.x;
    42.                     BLood_Location.y = hit.transform.position.y;
    43.                     BLood_Location.z = hit.transform.position.z;
    44.                     Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);
    45.                     Blood.SetActive(true);
    46.                     StartCoroutine(Blood_Timer());
    47.                 }
    48.                
    49.                 Old_Y = hit.transform.position.y;
    50.                 StartCoroutine(Damage_Timer());
    51.             }
    52.            
    53.         }
    54.         if(good == true){
    55.            
    56.         }
    57.     }
    58.    
    59.     IEnumerator Damage_Timer(){
    60.         yield return new WaitForSeconds(2.0f);
    61.        
    62.     }
    63.  
    64.     IEnumerator Blood_Timer(){
    65.         yield return new WaitForSeconds(1.0f);
    66.         Blood.SetActive(false);
    67.     }
    68.    
    69.  
    70. }
    71.  
     
  3. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    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?
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    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.
     
  5. briyan

    briyan

    Joined:
    Jan 13, 2015
    Posts:
    52
    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.
     
  6. briyan

    briyan

    Joined:
    Jan 13, 2015
    Posts:
    52
    The code is in the function ApplyDamage()
     
  7. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    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.
    Code (csharp):
    1.  
    2. public Soldier_Black_Knights_Sword swingtest;
    3.  
    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<ComponentType>() is far shorter than (ComponentType) GetComponent(typeOf(ComponentType)) :D

    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

    Code (csharp):
    1.  
    2. BLood_Location.x = hit.transform.position.x;
    3. BLood_Location.y = hit.transform.position.y;
    4. BLood_Location.z = hit.transform.position.z;
    5. Blood.transform.position = new Vector3(BLood_Location.x, BLood_Location.y, BLood_Location.z);
    6.  
    rather than
    Code (csharp):
    1.  
    2. Blood.transform.position = hit.transform.position;
    3.  
    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

    Code (csharp):
    1.  
    2. test = otherr.Is_Swinging;
    3. if(test == true && ...)
    4. {...}
    5.  
    rather than
    Code (csharp):
    1.  
    2. if(otherr.Is_Swinging && ...)
    3. {...}
    4.  
    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
     
  8. briyan

    briyan

    Joined:
    Jan 13, 2015
    Posts:
    52
    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).