Null Exception

Whenever the enemy get destroy, there an error
“MissingReferenceException: The object of type ‘Transform’ 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.”
I’m not sure how to check for enemy != null, so here my script

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;

public class PlayerAIBehaviour : MonoBehaviour
{
    public float playermaxhealth; //maxhealth
    public float playercurrenthealth; //currenthealth
    public float speed; //speed
    public float attackrange; //attackrange
    private Transform enemy;
    private Animator anim;
    Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        enemy = GameObject.FindGameObjectWithTag("Enemy").transform;
        anim = GetComponent<Animator>();
        playercurrenthealth = playermaxhealth;
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromEnemy = Vector2.Distance(enemy.position, transform.position);

        if (distanceFromEnemy > attackrange)
        {
            transform.position += Vector3.right * speed * Time.deltaTime;
            anim.SetBool("Moving", true);
            anim.SetBool("Attack", false);
        }
        else if (distanceFromEnemy < attackrange)
        {
            anim.SetBool("Moving", false);
            anim.SetBool("Attack", true);
        }
    }

    public void DoesDamage(float damage) //EnemyTakingDamage
    {
        anim.SetTrigger("Attack");   
        playercurrenthealth -= damage;
        if (playercurrenthealth <= 0)
        {
            Destroy(this.gameObject);
        }
    }

    public void SetMaxHealth()
    {
        playercurrenthealth = playermaxhealth;
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            anim.SetBool("Moving", true);
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            anim.SetBool("Moving", false);
        }
    }

    public void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere(transform.position, attackrange);
    }
}

Line number of error would be very helpful but guessing it is the enemy so doubtful anyone could solve this from your code example.

How?

I’m pretty sure if you just check if the enemy is null in the update before attempting to access that variable it will solve the issue. In this case you could just return when the enemy is null so it does not run the rest of the code in the update
see line 27-28

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
public class PlayerAIBehaviour : MonoBehaviour
{
    public float playermaxhealth; //maxhealth
    public float playercurrenthealth; //currenthealth
    public float speed; //speed
    public float attackrange; //attackrange
    private Transform enemy;
    private Animator anim;
    Rigidbody2D rb;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        enemy = GameObject.FindGameObjectWithTag("Enemy").transform;
        anim = GetComponent<Animator>();
        playercurrenthealth = playermaxhealth;
    }
    // Update is called once per frame
    void Update()
    {
        if(enemy == null)
            return;
          
        float distanceFromEnemy = Vector2.Distance(enemy.position, transform.position);
        if (distanceFromEnemy > attackrange)
        {
            transform.position += Vector3.right * speed * Time.deltaTime;
            anim.SetBool("Moving", true);
            anim.SetBool("Attack", false);
        }
        else if (distanceFromEnemy < attackrange)
        {
            anim.SetBool("Moving", false);
            anim.SetBool("Attack", true);
        }
    }
    public void DoesDamage(float damage) //EnemyTakingDamage
    {
        anim.SetTrigger("Attack");
        playercurrenthealth -= damage;
        if (playercurrenthealth <= 0)
        {
            Destroy(this.gameObject);
        }
    }
    public void SetMaxHealth()
    {
        playercurrenthealth = playermaxhealth;
    }
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            anim.SetBool("Moving", true);
        }
    }
    void OnTriggerExit2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            anim.SetBool("Moving", false);
        }
    }
    public void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere(transform.position, attackrange);
    }
}
1 Like

Exactly like that.

if(enemy != null) {
   //Do something with enemy.
}
1 Like

The null exception error is gone, but the playerAI still keep attacking and stop moving after the enemy get destroyed.
(I want the playerAI to move after the enemy get destroy)
How do I fix that?

Nullref is ALWAYS the same answer:

Some notes on how to fix a NullReferenceException error in Unity3D

  • also known as: Unassigned Reference Exception
  • also known as: Missing Reference Exception

http://plbm.com/?p=221

The basic steps outlined above are:

  • Identify what is null
  • Identify why it is null
  • Fix that.

Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.

NOW, for your other error:

How to report problems productively in the Unity3D forums:

http://plbm.com/?p=220

Help us to help you.

You need to set

  anim.SetBool("Moving", true);
  anim.SetBool("Attack", false);

You could do something like

    void Update()
    {
        if(enemy == null && anim.GetBool("Attack") == true)
            anim.SetBool("Attack", false);
        
        if(enemy == null)
            return;
...
1 Like

Yes!!! I use your method and add some code to it and it work!!!
Thanks for Helping Me :smile: