Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Null Exception

Discussion in 'Scripting' started by SpiderPig1660, Oct 17, 2020.

  1. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    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
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Collections.Specialized;
    5. using System.Security.Cryptography;
    6. using System.Security.Cryptography.X509Certificates;
    7. using UnityEngine;
    8.  
    9. public class PlayerAIBehaviour : MonoBehaviour
    10. {
    11.     public float playermaxhealth; //maxhealth
    12.     public float playercurrenthealth; //currenthealth
    13.     public float speed; //speed
    14.     public float attackrange; //attackrange
    15.     private Transform enemy;
    16.     private Animator anim;
    17.     Rigidbody2D rb;
    18.  
    19.     void Start()
    20.     {
    21.         rb = GetComponent<Rigidbody2D>();
    22.         enemy = GameObject.FindGameObjectWithTag("Enemy").transform;
    23.         anim = GetComponent<Animator>();
    24.         playercurrenthealth = playermaxhealth;
    25.     }
    26.  
    27.     // Update is called once per frame
    28.     void Update()
    29.     {
    30.         float distanceFromEnemy = Vector2.Distance(enemy.position, transform.position);
    31.  
    32.         if (distanceFromEnemy > attackrange)
    33.         {
    34.             transform.position += Vector3.right * speed * Time.deltaTime;
    35.             anim.SetBool("Moving", true);
    36.             anim.SetBool("Attack", false);
    37.         }
    38.         else if (distanceFromEnemy < attackrange)
    39.         {
    40.             anim.SetBool("Moving", false);
    41.             anim.SetBool("Attack", true);
    42.         }
    43.     }
    44.  
    45.     public void DoesDamage(float damage) //EnemyTakingDamage
    46.     {
    47.         anim.SetTrigger("Attack");  
    48.         playercurrenthealth -= damage;
    49.         if (playercurrenthealth <= 0)
    50.         {
    51.             Destroy(this.gameObject);
    52.         }
    53.     }
    54.  
    55.     public void SetMaxHealth()
    56.     {
    57.         playercurrenthealth = playermaxhealth;
    58.     }
    59.  
    60.     void OnTriggerEnter2D(Collider2D other)
    61.     {
    62.         if (other.tag == "Enemy")
    63.         {
    64.             anim.SetBool("Moving", true);
    65.         }
    66.     }
    67.  
    68.     void OnTriggerExit2D(Collider2D other)
    69.     {
    70.         if (other.tag == "Enemy")
    71.         {
    72.             anim.SetBool("Moving", false);
    73.         }
    74.     }
    75.  
    76.     public void OnDrawGizmosSelected()
    77.     {
    78.         Gizmos.color = Color.blue;
    79.         Gizmos.DrawWireSphere(transform.position, attackrange);
    80.     }
    81. }
    82.  
    83.  
    84.  
     
  2. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    Line number of error would be very helpful but guessing it is the enemy so doubtful anyone could solve this from your code example.
     
  3. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
  4. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    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

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Collections.Specialized;
    5. using System.Security.Cryptography;
    6. using System.Security.Cryptography.X509Certificates;
    7. using UnityEngine;
    8. public class PlayerAIBehaviour : MonoBehaviour
    9. {
    10.     public float playermaxhealth; //maxhealth
    11.     public float playercurrenthealth; //currenthealth
    12.     public float speed; //speed
    13.     public float attackrange; //attackrange
    14.     private Transform enemy;
    15.     private Animator anim;
    16.     Rigidbody2D rb;
    17.     void Start()
    18.     {
    19.         rb = GetComponent<Rigidbody2D>();
    20.         enemy = GameObject.FindGameObjectWithTag("Enemy").transform;
    21.         anim = GetComponent<Animator>();
    22.         playercurrenthealth = playermaxhealth;
    23.     }
    24.     // Update is called once per frame
    25.     void Update()
    26.     {
    27.         if(enemy == null)
    28.             return;
    29.          
    30.         float distanceFromEnemy = Vector2.Distance(enemy.position, transform.position);
    31.         if (distanceFromEnemy > attackrange)
    32.         {
    33.             transform.position += Vector3.right * speed * Time.deltaTime;
    34.             anim.SetBool("Moving", true);
    35.             anim.SetBool("Attack", false);
    36.         }
    37.         else if (distanceFromEnemy < attackrange)
    38.         {
    39.             anim.SetBool("Moving", false);
    40.             anim.SetBool("Attack", true);
    41.         }
    42.     }
    43.     public void DoesDamage(float damage) //EnemyTakingDamage
    44.     {
    45.         anim.SetTrigger("Attack");
    46.         playercurrenthealth -= damage;
    47.         if (playercurrenthealth <= 0)
    48.         {
    49.             Destroy(this.gameObject);
    50.         }
    51.     }
    52.     public void SetMaxHealth()
    53.     {
    54.         playercurrenthealth = playermaxhealth;
    55.     }
    56.     void OnTriggerEnter2D(Collider2D other)
    57.     {
    58.         if (other.tag == "Enemy")
    59.         {
    60.             anim.SetBool("Moving", true);
    61.         }
    62.     }
    63.     void OnTriggerExit2D(Collider2D other)
    64.     {
    65.         if (other.tag == "Enemy")
    66.         {
    67.             anim.SetBool("Moving", false);
    68.         }
    69.     }
    70.     public void OnDrawGizmosSelected()
    71.     {
    72.         Gizmos.color = Color.blue;
    73.         Gizmos.DrawWireSphere(transform.position, attackrange);
    74.     }
    75. }
    76.  
     
    SpiderPig1660 likes this.
  5. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Exactly like that.
    Code (CSharp):
    1. if(enemy != null) {
    2.    //Do something with enemy.
    3. }
     
    SpiderPig1660 likes this.
  6. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    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?
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    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.
     
  8. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    You need to set
    Code (CSharp):
    1.   anim.SetBool("Moving", true);
    2.   anim.SetBool("Attack", false);
    You could do something like
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if(enemy == null && anim.GetBool("Attack") == true)
    4.             anim.SetBool("Attack", false);
    5.        
    6.         if(enemy == null)
    7.             return;
    8. ...
     
    SpiderPig1660 likes this.
  9. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    Yes!!! I use your method and add some code to it and it work!!!!
    Thanks for Helping Me :D