- Home /
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 a beginner at Unity and I'm trying to make a game where when the enemy kills the player, the player dies and a game over screen is shown. However, every time I get the error shown in the title and I don't understand why or how I solve it. Here's my code (the error is at line 30):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
public float speed;
float horizontalMove = 0f;
private Transform target;
public float stoppingDistance;
public Animator animator;
public bool facingRight = false;
public Transform attackPoint;
public float attackRange;
public float attackRate = 2f;
public int attackDmg;
float nextAttackTime;
public LayerMask playerlayer;
// Start is called before the first frame update
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (Vector2.Distance(transform.position, target.position) > stoppingDistance) {
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
horizontalMove = Input.GetAxisRaw("Horizontal") * speed;
animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
animator.SetBool("isRunning", true);
}
else
{
animator.SetBool("isRunning", false);
if (Time.time >= nextAttackTime) //keeps track of current time
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
if (target.transform.position.x < gameObject.transform.position.x && !facingRight)
Flip();
if (target.transform.position.x > gameObject.transform.position.x && facingRight)
Flip();
}
void Flip()
{
//flipping in the direction of the player
facingRight = !facingRight;
Vector3 tmpScale = gameObject.transform.localScale;
tmpScale.x *= -1;
gameObject.transform.localScale = tmpScale;
}
void Attack()
{
//play attack animation
animator.SetTrigger("Attack");
//detect enemies in range of attack
Collider2D[] hitPlayer= Physics2D.OverlapCircleAll(attackPoint.position, attackRange, playerlayer); //stores all the enemies we hit inside the varible
//damage them
foreach (Collider2D player in hitPlayer)
{
player.GetComponent<PlayerHealth>().TakeDamage(attackDmg);
}
}
private void OnDrawGizmosSelected() //allows us to draw stuff in the unity editor whenever an object is selected
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackRange);
}
}
Yeah, it does. After it gets destroyed, the error message shows up
That is the problem, I have posted an answer it should work...
Answer by Caeser_21 · Apr 08 at 01:28 PM
Y̶o̶u̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶c̶a̶l̶l̶ ̶ ̶t̶a̶r̶g̶e̶t̶ ̶=̶ ̶G̶a̶m̶e̶O̶b̶j̶e̶c̶t̶.̶F̶i̶n̶d̶G̶a̶m̶e̶O̶b̶j̶e̶c̶t̶W̶i̶t̶h̶T̶a̶g̶(̶"̶P̶l̶a̶y̶e̶r̶"̶)̶.̶G̶e̶t̶C̶o̶m̶p̶o̶n̶e̶n̶t̶<̶T̶r̶a̶n̶s̶f̶o̶r̶m̶>̶(̶)̶;̶ ̶a̶f̶t̶e̶r̶ ̶t̶h̶e̶ ̶p̶l̶a̶y̶e̶r̶ ̶r̶e̶s̶p̶a̶w̶n̶s̶.̶.̶.̶ ̶t̶h̶a̶t̶ ̶s̶h̶o̶u̶l̶d̶ ̶f̶i̶x̶ ̶y̶o̶u̶r̶ ̶i̶s̶s̶u̶e̶
Based on your comment i think you have to add a null statement, like :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
public float speed;
float horizontalMove = 0f;
private Transform target;
public float stoppingDistance;
public Animator animator;
public bool facingRight = false;
public Transform attackPoint;
public float attackRange;
public float attackRate = 2f;
public int attackDmg;
float nextAttackTime;
public LayerMask playerlayer;
// Start is called before the first frame update
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (target != null)
{
if (Vector2.Distance(transform.position, target.position) > stoppingDistance) {
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
horizontalMove = Input.GetAxisRaw("Horizontal") * speed;
animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
animator.SetBool("isRunning", true);
}
else
{
animator.SetBool("isRunning", false);
if (Time.time >= nextAttackTime) //keeps track of current time
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
if (target.transform.position.x < gameObject.transform.position.x && !facingRight)
Flip();
if (target.transform.position.x > gameObject.transform.position.x && facingRight)
Flip();
}
}
void Flip()
{
//flipping in the direction of the player
facingRight = !facingRight;
Vector3 tmpScale = gameObject.transform.localScale;
tmpScale.x *= -1;
gameObject.transform.localScale = tmpScale;
}
void Attack()
{
//play attack animation
animator.SetTrigger("Attack");
//detect enemies in range of attack
Collider2D[] hitPlayer= Physics2D.OverlapCircleAll(attackPoint.position, attackRange, playerlayer); //stores all the enemies we hit inside the varible
//damage them
foreach (Collider2D player in hitPlayer)
{
player.GetComponent<PlayerHealth>().TakeDamage(attackDmg);
}
}
private void OnDrawGizmosSelected() //allows us to draw stuff in the unity editor whenever an object is selected
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackRange);
}
}
But in my game, the player doesn't respawn. He has a health bar and once that health bar is finished, he doesn't respawn
So once the player dies the game is over and you cant restart, correct?
Yeah, I want the player to die only once and not respawn again
It still gives me the same error. This time the error is at line 50
Oh right, I forgot about that line, sorry... i have changed my original answer...
Nvm I figured out the problem. It's because I didn't add the null condition at line 50 as well. It works now. Thank you for your help!