My object dosent get destroyed.

Im doing my enemy’s health system, im trying with something simple, but for some reasson my enemy’s object fosent get destroyed. I wrote a debug.log too see if the problem was because of the health math, but it gives back “Dead”. So the problem is that the object for some reason dosent get destroyed, am i doing something wrong?

using Mono.Cecil.Cil;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{

    public int health = 100;
    public int currentHealth;

    public void Start()
    {
        currentHealth= health;
    }
    public void TakeDamage (int damage)
    {
        currentHealth -= damage;


        if (currentHealth <= 0)
        {
            Debug.Log("Dead");
            Destroy(gameObject);
        }
    }

}

Do this:

    public void TakeDamage (int damage)
    {
        Debug.Log("Apply Damage " + damage + " health before damage::" + currentHealth, gameObject);
        currentHealth -= damage;
        if (currentHealth <= 0)
        {
            Debug.Log("Dead");
            Destroy(gameObject);
        }
    }

Note the Debug.Log line I added. When it shows up in the console, just make a single click on it and Unity will highlight / “ping” the context object I passed as second argument. My guess is that you’re calling that method on a different object. Maybe you call it on a prefab in the project instead of the actual instance in the scene? We don’t know since you haven’t shown how or where the method is called.

1 Like

How do you check that it does not get destroyed? Visually in the hierarchy, or by accessing the object after you call the TakeDamage() function? Destroy() will only queue the object for destruction. It may still exist for the remainder of that frame.

2 Likes

Ok, so i used a bullet code, so when i hit the enemy, he dies

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Bullet : MonoBehaviour
{

    public int bulletDamage = 100;

    public GameObject impactEffect;



    private void OnCollisionEnter2D(Collision2D other)
    {
        Enemy enemy = gameObject.AddComponent<Enemy>();

        if (other.gameObject.CompareTag("Enemy"))
        {
            Debug.Log("Me dio");
            enemy.TakeDamage(bulletDamage);
        }


        GameObject effect = Instantiate(impactEffect, transform.position, transform.rotation);

        Destroy(effect);

        Destroy(gameObject);
    }
}

How can I see if it still exists on the frame?

Let’s pause a moment and reflect about the code above.

For instance, in your bullet class you have:

This adds an Enemy script to the bullet (gameObject). I don’t think this is what you want.

Instead, are you looking to use GetComponent() on the other object in this collision?

This will create the effect and immediately destroy it. You can supply an optional second argument to Destroy() that informs Destroy() to wait some amount of time before Destroy()-ing.

Work with it one step at a time, like this guy:

Imphenzia: How Did I Learn To Make Games:

2 Likes

I was just informing you that Destroy will not destroy the gameobject instantly, but at the end of the current update loop. There are people who call Destroy() and accidentally or intentionally access the destroyed gameobject the very same frame and wonder why it still exists. That’s why i asked how you checked it doesnt get destroyed. But if you visually see it in the hierarchy after blinking it certainly still exists.

Did you use Bunnys code to check you are actually damaging and destroying the gameobject you think you are? You could, for example, have a hierarchy where one parent object has several child objects. One such child could contain the model, the other could contain the Enemy script. In that specific case, you would end up only destroying the gameobject with the actual enemy script on it, not their parent(s). So visually, you would be lead to believe that nothing was destroyed, while in fact the code did what you told it to. If you have a similar hierarchy for your enemy object, try calling Destroy on transform.root.gameObject instead.

Kurt found some other mistakes with your code, but generally speaking, if your “Dead” Debug.Log message shows, then something should be getting destroyed (after the current frame). Make sure it’s what you actually want to destroy.

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
    public int bulletDamage = 100;
    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Enemy"))
        {
            other.gameObject.GetComponent<Enemy>().TakeDamage(bulletDamage);
        }
        GameObject effect = Instantiate(impactEffect, transform.position, transform.rotation);
        //Destroy(effect); // this shouldn't be here. It destroys the effect immediately. Add a script to the effect that destroys it when it has done its thing.
        Destroy(gameObject);
    }
}

Yea I know what you mean, but first i wanted to concentrate more on the damage script before using effects. But thank you, i didnt consider that

Ive tried doing using GetComponent, but for some reason it brings me other problems. I needed to do a reference to the other script so I could use the health system of my enemy. But thank you, I will also use the tips the video tips you just gave me, i was consider giving it time to the effects, but when i solve this problem ill use what you told me.

Don’t stop with that answer. That answer tells you and the entire world ABSOLUTELY NOTHING.

If you insist on a solution that uses GetComponent, go learn how it works. Use it. Make experiments to back up your understanding. Every element and function in Unity can be trivially tested with a blank scene and some scripts to test things.

If it helps you, set this project aside and work through tutorials (in a blank new project) for what you are attempting.

There will be no substitute for you iterating until you have built up a knowledge of what you are doing so you can do what you want successfully.

1 Like

So i’ve used Bunnys Debug.Log, and the consle told me “Damge 100 health before damage::0”. So this means that the health goes down, but for some reason the enemy dosent disappear. Maybe its the hierchy you where talking about. How should I solve this problem?

How you solve it is by first making sure that that’s the problem. It gets a bit hard helping you, since we basically repeat each thing twice to get a straight answer from you. I already told you in which case this would be a problem. Do you have one GameObject with all scripts on it (Enemy, Renderer, …), or do you have one parent with different children that contain individually the Renderer and the Enemy script. Check if the actual gameobject with the actual enemy script on it does not get destroyed. Make sure it’s the korrekt gameobject aswell. Bunnys Code highlights the object that will get destroyed when you click on the log message.

1 Like