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

Missing Reference Exception

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

  1. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    So when my enemy game object get destroy by the player, an error pop up
    "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 fix this, if anyone can help me that would be great
    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 damage; //damage
    14.     public float speed; //speed
    15.     public float attackrange; //attackrange
    16.  
    17.     public bool moving;
    18.     private Transform enemy;
    19.     Rigidbody2D rb;
    20.  
    21.     void Start()
    22.     {
    23.         rb = GetComponent<Rigidbody2D>();
    24.         enemy = GameObject.FindGameObjectWithTag("Enemy").transform;
    25.         moving = true;
    26.         playercurrenthealth = playermaxhealth;
    27.     }
    28.  
    29.     // Update is called once per frame
    30.     void Update()
    31.     {
    32.         if (moving == true)
    33.         {
    34.             transform.position += Vector3.right * speed * Time.deltaTime;
    35.         }
    36.         float distanceFromEnemy = Vector2.Distance(enemy.position, transform.position);
    37.         if (distanceFromEnemy < attackrange)
    38.         {
    39.             moving = false;
    40.         }
    41.     }
    42.     private void OnTriggerEnter2D(Collider2D other)
    43.     {
    44.         if (other.tag == "Enemy")
    45.         {
    46.             EnemyBehaviour EnemyScript = other.GetComponent<EnemyBehaviour>();
    47.             EnemyScript.TakeDamage(damage);
    48.         }
    49.     }
    50.  
    51.     public void TakeDamage(float damage) //PlayerTakingDamage
    52.     {
    53.         playercurrenthealth -= damage;
    54.         if (playercurrenthealth <= 0)
    55.         {
    56.             Destroy(this.gameObject);
    57.         }
    58.     }
    59.  
    60.     public void SetMaxHealth()
    61.     {
    62.         playercurrenthealth = playermaxhealth;
    63.     }
    64.  
    65.     public void OnDrawGizmosSelected()
    66.     {
    67.         Gizmos.color = Color.blue;
    68.         Gizmos.DrawWireSphere(transform.position, attackrange);
    69.     }
    70. }
    71.  
    72.  
    73.  
     
  2. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    I'm assuming the
    enemy
    Transform field in this script is the enemy GameObject that's being destroyed.
    When you destroy the enemy GameObject, the reference to
    enemy
    becomes null.

    The typical fix is to check
    if(enemy != null)
    before doing anything with it, but the way you structured this makes it look like there's supposed to be only one enemy in the game, is that correct?
    If so, can it be assumed that the game is supposed to end when the enemy gets destroyed? Because you may not need to bother with null-checking if that's the case. You could just end the game right when the enemy dies.

    If that's not the case, and there are supposed to be multiple enemies for the player to encounter in the game, then this script won't really handle that. It's only getting a reference to one random enemy when it loads.
     
    SpiderPig1660 likes this.
  3. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    oop I didn't know that gonna cause the game to end when one enemy get killed but I need to learn more if(enemy != null) statement first.
     
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    No, it won't cause the game to end; I'm saying that if your game only has one enemy, and the game should end when that enemy is destroyed, then there's no need to add null-checking, because you would just end the game after the enemy is destroyed.

    If the game isn't supposed to end when the enemy is destroyed, then yes, you will need to check if the enemy still exists before doing any logic with it.
    Either way, the game won't just magically "end" on its own when a GameObject is destroyed; you have to explicitly create some way for the game to end.

    The other thing I was pointing out is that, if there are supposed to be multiple enemies that the player has to deal with, then this script doesn't make much sense, since it's just getting the reference to one random enemy in the scene and comparing its distance to the player.
    Once that one random enemy is destroyed, that distance check will stop running. If that's intentional, then there's no problem; I just wanted to make sure that it is, indeed, intentional.
     
    SpiderPig1660 likes this.
  5. SpiderPig1660

    SpiderPig1660

    Joined:
    Jul 26, 2020
    Posts:
    37
    I want to make this game like battle cat/line ranger