Getting reference to the healt in the enemyScript?

Hi! I found a lot of examples, but none of them is simple and clear.

I want only to destroy the enemy game object when his health will be 0 - in another script.

In my little game enemies get active or passive in the hierarchy, but I don’t destroy that objects. But now I need to do that and I would like to destroy the object when his health == 0.

How to do that?

I have the enemy and enemyScript. Now I am doing another script and I want to refer to the enemy health and make that object destroyed.

This is my wrong script

public class DestroyWhenDead : MonoBehaviour {

    //GameObject monster;
    //public GameObject health;

    void Start() {
        //EnemyScript = GameObject.Find("Health");
    }
   
    // Update is called once per frame
    void Update () {
        EnemyScript enemyScript = GetComponent<Health> ();
        if (health <= 0)
        {
            Destroy (gameObject);
        }
    }
}

It says, that:
error CS0118: DestroyWhenDead.health' is a field’ but a type' was expected rror CS0029: Cannot implicitly convert type T’ to EnemyScript' and error CS0019: Operator <=’ cannot be applied to operands of type UnityEngine.GameObject' and int’

Well right away I can see that your both your health’s are upper case H and lower case h so try fixing that first, can’t see anything else obviously wrong just yet but that’s often the biggest culprit.

“health” on your if statement should be “Health”, try that and we’ll see if any other errors pop up or if it changes.

It says:
Assets/DestroyWhenDead.cs(16,42): error CS0246: The type or namespace name health' could not be found. Are you missing an assembly reference? The name health’ does not exist in the current context’

So, it doesn’t correspond to the ‘health’.

I’ve changed that to

    public int Health;

    void Start() {
        EnemyScript enemyScript = GetComponent<"Health">();
    }
   
    // Update is called once per frame
    void Update () {
       
        if (Health <= 0)
        {
            Destroy (gameObject);
        }
    }
    }

And now it says only: error CS1525: Unexpected symbol `)’ - but it has no sense.

Oh, hang on, I think I might know what you’ve done now I’ve got my second coffee.

        EnemyScript enemyScript = GetComponent<"Health">();

I’m not sure what you’re attempting to do with the first bit, might need more context but GetComponent<EnemyScript.Health>(); should be correct, don’t use quotation marks, did you get this from a tutorial or something?

Going to get some documentation because I’ve done this before myself with other scripts and it works fine, could I perhaps take a look at your enemy script as well?

When I changed that in such a way, it had made a lot of strange errors.

This is a part of enemy script

public class EnemyScript : MonoBehaviour {
    public Animator animator;
    public Transform healthBar;
    private SpriteRenderer healthBarSprite;
    public GameObject enemyDead;
    public GameObject player;

    public Transform[] checkpoints;
    private int checkpoint = 0;

    private Vector2 desiredVelocity = Vector3.zero;
    private Vector2 desiredForce = Vector3.zero;
    private Vector2 desiredDirection = Vector2.zero;

    public int acceleration = 10;
    public int speed = 2;
   
    public MeleeAttack meleeAttack;

    private Rigidbody2D rb;
    private float attackStarted;
    private Transform currentTarget;
    private bool attacking = false;
    public float health = 250;
    public bool takesDamage = true;
    public float DestroyAfterTime = 3.0f;


    void Start () {
        rb = GetComponent<Rigidbody2D>();
        healthBarSprite = healthBar.GetComponent<SpriteRenderer>();
        rb.freezeRotation = true;
        enemyDead.SetActive (false);

    }
   

    void Update () {
        healthBarSprite.color = Color.Lerp(Color.red, Color.green, health / 250);
        healthBar.localScale = new Vector3(health%250 / 250, 1, 1);
        animator.SetBool("fight", false);
   
        if (health <= 0)
        {
            enemyDead.SetActive (true);
            enemyDead.transform.position = transform.position;
            transform.rotation = Quaternion.identity;
            gameObject.SetActive (false);
            Destroy (enemyDead, DestroyAfterTime);

        }

Are you absolutely sure you need that public integer there? Try this, let me know how it goes.

    void Start() {
   
    }
 
    // Update is called once per frame
    void Update () {
     
        if (EnemyScript.health <= 0)
        {
            Destroy (gameObject);
        }
    }
    }

Ok. It says now: error CS0120: An object reference is required to access non-static member `EnemyScript.health’

I think that it still can’t get access to the Health in the above enemyScript. But when I place the code to get to the EnemyScript.Health element, then this element is red, what means, that it can’t also refers that to the script. Strange.

That is really weird, I’m afraid I’ve run out of ideas so it’s probably best if you wait for somebody more experienced, I can tell you though that I’ve used script.namedinteger before on my own code and it works just fine usually. Not sure what’s going on that it would behave like this.

Both of you need to go back to the learn section. :wink:

This is a pretty straight forward solution. Assuming the EnemyScript is on the same component as DestroyWhenDead, then the following code will work.

public class DestroyWhenDead : MonoBehaviour {
  
    void Update () {
        EnemyScript enemyScript = GetComponent<EnemyScript> ();
        if (enemyScript.health <= 0)
        {
            Destroy (gameObject);
        }
    }
}

Of course you should probably cache the component reference as a good habit.

public class DestroyWhenDead : MonoBehaviour {

    EnemyScript enemyScript;

    void Awake () {
        enemyScript = GetComponent<EnemyScript> ();
    }
    
    void Update () {
        if (enemyScript.health <= 0)
        {
            Destroy (gameObject);
        }
    }
}
2 Likes

Oh for crying out loud, of course it works like that :stuck_out_tongue:

Thanks Kiwasi, I’m going to double check my code because I bet I’ll have put my code in there somewhere like that and that’s why it all works, I got it half right at least.

        Text scoreText = GameObject.Find ("scoreText").GetComponent<Text> ();

Yes, of course, there it bloody is, I just wasn’t reading the code off right, I was wondering why there were errors popping up even after this, you need both, Kiwasi’s solution is definitely correct.

Oh yes, it works very well :smile: Great thanks Kiwasi! Now I can try to make another interaction. When two of monsters are already dead, then the conversation box should become active. I did it like that.

public class Mission1 : MonoBehaviour {

    public GameObject monster1;
    public GameObject monster2;
//it's a canvas
    public GameObject message;

    void Start () {

        message.SetActive (false);
    }

    void Update () {
        if(monster1&&monster2 == null)
        {
            message.SetActive (true);
        }
    }
}

Why is it not working?

I’l leave this one to Kiwasi lol :stuck_out_tongue:

if (monster1 == null && monster2 == null)
2 Likes

Yes, it should work. I’ll check that today evening.

Unfortunately it doesn’t work. I did a simple red square which should become active when two of the monsters will be dead. Instead they are null the square is still invisible.

Guess you’ll have to do some debugging then! Log the null checks to see which one isn’t null, etc etc.

Debugging showed no red alerts, only couple of yellow, but not connected with null function. But can it be so, that null is treated as a bool and without putting it in such a way it will not work?

if (monster1 != null) Debug.Log("monster1", monster1);
if (monster2 != null) Debug.Log("monster2", monster2);

I found in the web that there is no possibility to check if anything is or not active in hierarchy. Any of gameobject.activeSelf; .activeInHierarchy etc. are not working. That’s a shame, but it works like that.

That’s why I found the other solution. I have a script which is responsible for counting enemies. But the enemy is not active at the beginning. He appears after the conversation with one of the characters. I’ve wrote a script and attached it to the sensor object. The sensor is active, when the health of the enemy is >0. So, when the sensor is active it has a tag Enemy. But after the monster death it becomes inactive. Counting script “sees” it and he sends information to the collision box (on trigger), that it can already show the conversation box, because all the enemies are already killed. Mission passed. And it works! :smile: