[Solved] multiple enemy prefabs all get damage help

I created an enemy that gets hit by laserbeams or missiles. everything works fine, so I created a Prefab.

When I add to the Scene multiple Prefabs of the same Enemy, when one gets hit, all of them get damage at the same time like they are chained - how do I fix that?

but they don’t die at the same time, they wait for the last hit even if their health is 0…

is it because I use static variables for their health?(curLife, totalLife, percLife)

I have no experience in unity or c#, this is my first project trying to learn the code.
Thanks

This is the EnemyScript:

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

public class EnemyScript : MonoBehaviour
{
 
    private Laserbeam laserbeam;
    private Missiles missile;

    private static float  totalLife = 20;
    private static float curLife = totalLife;
    public static float percLife = curLife / totalLife;


    //Materials
    private Material matWhite;
    private Material matDefault;
    private UnityEngine.Object explosionRef;
    SpriteRenderer sr;

    private void Awake()
    {
        laserbeam = GameObject.FindObjectOfType<Laserbeam>();
        missile = GameObject.FindObjectOfType<Missiles>();
    }


    // Start is called before the first frame update
    private void Start()
    {
        sr = GetComponent<SpriteRenderer>();
        matWhite = Resources.Load("WhiteFlash", typeof(Material)) as Material;
        matDefault = sr.material;

 
    }

    private void Update()
    {
      
 
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
 
 
        if (collision.CompareTag("LaserBeam"))
        {
   
            Destroy(collision.gameObject);
            curLife -= 1;
            sr.material = matWhite;
            explosionRef = Resources.Load("Explosion");
            percLife = curLife/totaLife

            if(curLife <= 0)
            {
                curLife = 0;
                KillSelf();
            }
            else
            {
                Invoke("ResetMaterial", 0.05f);
            }
  
        }

        if (collision.CompareTag("Missile"))
        {

            Destroy(collision.gameObject);
            curLife -= 5;
            sr.material = matWhite;
            explosionRef = Resources.Load("Explosion");
            percLife = curLife/totalLife

            if (curLife <= 0)
            {
                curLife = 0;
                KillSelf();
            }
            else
            {
                Invoke("ResetMaterial", 0.05f);
            }
        }
 
 


    }
    void ResetMaterial()
    {
        sr.material = matDefault;
    }
    private void KillSelf()
    {
        GameObject explosion = (GameObject)Instantiate(explosionRef);
        explosion.transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
        Destroy(gameObject);
    }

 
  
 

}

You are right, Remove static from your variables (in your case: floats), adding static means that there is only one health variable in your scene, in other words, all of your enemies are sharing the same health.

I’m still beginner like you, but there is a very easy tutorials on YouTube for C# and unity, try them.

1 Like

Yes indeed it’s the static, thank you Agent003. But now I encounter another problem:

totaLife = the enemy’s starting life.
curLife = the enemy’s life while the game is runing (updated when being hit).
percLife = the percentage of curLife / totalLife which returns a float value from 0 to 1.

Now by removing the static, I have to call those variables from the Awake - so they would enter the scene with a full life health bar.

private void Awake()
    {
        laserbeam = GameObject.FindObjectOfType<Laserbeam>();
        missile = GameObject.FindObjectOfType<Missiles>();
  
        curLife = totalLife; // which starts the scene having the currentLife equal to the totalLife
        percLife  = curLife / totalLife; // which now it is equal to 1, I get the percentage and a full healthBar in my HealthbarScript.

    }

But I now need to access the percLife value from my EnemyScript and call it in the HealthBarScript.

The percLife is updated again in the OnTriggerEnter2D function in the bottom (percLife = curLife/totaLife) of the EnemyScript

when I access it from another class, it reads from the Awake. How can I access the updated variable from the OnTriggerEnter2D?

While I had this as static, I could do it fine, but then I encountered the problem I mentioned in my first post.

This is the other class:

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

public class HealthBarScript : EnemyScript

{

    Vector3 localScale;
    private float xScale;
 

     private void Start()
    {
        localScale = transform.localScale;
        xScale = localScale.x;

    }

    private void Update()
    {
 
      localScale.x = xScale * percLife;     // Here is where I need the percLife from EnemyScript 
                                                               // but it returns a 1 since it gets it from the Awake of     
                                                               // EnemyScript - and a full HealthBars is shown always.
      transform.localScale = localScale;
 
    }

 
}

You can create a reference to you your health bar object in the enemy script:
public GameObject healthBar;
then add your health bar object to your enemy object (in the inspector).
in your health bar script remove the update function (you don’t need to update the bar each frame), then add this function:

public void updateBar(float pLife) {
localScale.x = xScale * pLife;
transform.localScale = localScale;
}

call the above code each time your enemy get hit, your OnTriggerEnter2D function should be like this:

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("LaserBeam"))
        {
            Destroy(collision.gameObject);
            curLife -= 1;
            sr.material = matWhite;
            explosionRef = Resources.Load("Explosion");
            percLife = curLife/totaLife;
            healthBar.getcomponent<HealthBarScript>().updateBar(percLife);     // we call the updateBar function from here and send the percLife variable with it

Try it and tell me if it worked.

1 Like

Yes! it works! finally!!

Thank you so much!

It seemed it was that simple. The problem was me, I did know about this, but I got so much info in my head the past days trying to learn the code, that I just need to learn to combine all of that the right way!

https://imge.to/i/vJoJBi

2 Likes