I can't kill two or more enemies in unity

I can’t kill two plant monsters. Okay, so I have an plant monster AI who has a health bar. When my player kills one plant monster depleting his health to zero, everything is fine. But then after he kills the next, this error comes up.
MissingReferenceException: The object of type ‘Animator’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Animator.SetBool (System.String name, Boolean value) (at C:/buildslave/unity/build/artifacts/generated/common/modules/Animation/AnimatorBindings.gen.cs:283)
EnemyMovementController.OnTriggerStay2D (UnityEngine.Collider2D other) (at Assets/Scripts/EnemyMovementController.cs:65)

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnemyHealth : MonoBehaviour {

    public float enemyMaxHealth;

    float EcurrentHealth;

    public Slider enemySlider;

   

    // Use this for initialization
    void Start () {
        EcurrentHealth = enemyMaxHealth;
        enemySlider.maxValue = EcurrentHealth;
        enemySlider.value = EcurrentHealth;
            }
   
    // Update is called once per frame
    void Update () {
   
    }

    public void addDamage(float damage)
    {
        EcurrentHealth -= damage;

        enemySlider.value = EcurrentHealth;
        if (EcurrentHealth <= 0) {
            makeDead ();
        }
    }

    void makeDead()
    {
       
        Destroy (gameObject);
    }

}

this is the enemies health code.

Next, this is the EnemyMovementController with the animator codes which unity says it still tries to access.
EnemyMovementController is on the parent gameobject
while the health script is on the plant monster which is the child of the parent object.

using UnityEngine;
using System.Collections;

public class EnemyMovementController : MonoBehaviour {

    public float enemySpeed;

    Animator enemyAnimator;

    //facing
    public GameObject enemyGraphic;
    bool canFlip = true;
    bool facingRight = false;
    float flipTime = 5f;
    float nextFlipChance = 0f;

    // aggression time
    public float chargeTime;
    float startChargeTime;
    bool charging;
    Rigidbody2D enemyRB;

    public float lifespan = 1f;

 

    // Use this for initialization
    void Start () {
         enemyAnimator = GetComponentInChildren<Animator>();
        enemyRB = GetComponent<Rigidbody2D> ();
    }
   
    // Update is called once per frame
    void Update () {
   
        if (Time.time > nextFlipChance){
        if (Random.Range (0, 10) >= 5)
            flipFacing ();
            nextFlipChance = Time.time + flipTime;
        }
    }

    void OnTriggerEnter2D(Collider2D other){
        if(other.tag == "Player"){
            if (facingRight && other.transform.position.x < transform.position.x) {
                flipFacing ();
            } else if (!facingRight && other.transform.position.x > transform.position.x) {
                flipFacing ();
            }
            canFlip = false;
            charging = true;
            startChargeTime = Time.time + chargeTime;
        }
    }

    void OnTriggerStay2D(Collider2D other){
        if (other.tag == "Player"){
        if(startChargeTime < Time.time){
                if (!facingRight) {
                    enemyRB.AddForce (new Vector2 (-1, 0) * enemySpeed);
                }
            else
                enemyRB.AddForce (new Vector2 (1,0) * enemySpeed);
                enemyAnimator.SetBool ("IsCharging", charging);
        }
      }
    }

    void OnTriggerExit2D(Collider2D other){
        if (other.tag == "Player") {
            canFlip = true;
            charging = false;
            enemyRB.velocity = new Vector2 (0f, 0f);
            enemyAnimator.SetBool ("IsCharging", charging);
        }
    }

    void flipFacing ()
    {
        if (!canFlip)
            return;
        float facingX = enemyGraphic.transform.localScale.x;
        facingX *= -1f;
        enemyGraphic.transform.localScale = new Vector3 (facingX, enemyGraphic.transform.localScale.y, enemyGraphic.transform.localScale.z);
        facingRight = !facingRight;
    }

}

can anyone help? thanks from david

(I haven’t tested this myself, but…) Like the error says, I think it’s because you are Destroying on line 40. The docs for Destroy says: “If obj is a GameObject it will destroy the GameObject, all its components and all transform children of the GameObject.” (Unity - Scripting API: Object.Destroy**)**

So since your plants are likely sharing that Animator component, it’s getting destroyed along with the first monster. You shouldn’t instantiate, destroy, instantiate objects as it can take up too much processor time. You should do object pooling and just “deactivate” rather than destroy. (Sorry, I’m just getting back into Unity and don’t know how that’s done exactly, but definitely look up “object pooling”)

If the health script is on the child, then only the child will be destroyed if you call Destroy(gameObject). If you destroy the child which has the Animator, but the parent still exists, the next time it tries to access the Animator through a reference created when the Animator still existed will throw this error. You’ll need to reference to the parent by using Destroy(transform.parent.gameObject).

A controversial statement. Even for mobile, it’s not usually necessary unless the objects in question are being instantiated at high rates. Things like bullets and effects and otherwise swarms of things need pooling to combat garbage collection lag. Look it up for sure, and also consider the fact that it may not be necessary for your case.

2 Likes