When the player dies and I reload the scene the enemies spawn script stops working.

This is my first game and I’m trying to reset the game after player death, i already made the ui and all the functions but for some reason after the player dies and reloads the scene the enemy manager stops respawning my enemy prefab after I kill it once. The error message appears when I try to instantiate the new enemy. The error message is. “MissingReferenceException: The object of type ‘EnemyManager’ 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. EnemyManager.spawnNewEnemy () (at Assets/EnemyManager.cs:35) target.g__Die|26_0 () (at Assets/target.cs:116) target.TakeDamage (System.Single amount) (at Assets/target.cs:103) gun.Shoot () (at Assets/gun.cs:59) gun.Update () (at Assets/gun.cs:34)


target.cs

public class target : MonoBehaviour
{
    public float health = 30f;

    public NavMeshAgent agent;

    public Transform player;

    public LayerMask whatIsGround, whatIsPlayer;

    public HealthbarEnemy healthbar;

    public delegate void EnemyKilled();
    public static event EnemyKilled OnEnemyKilled;

    //Patroling
    public Vector3 walkPoint;
    bool walkPointset;
    public float walkPointRange;

    //Attacking
    public float timeBetweenAttacks;
    public float agentDamage = 50f;
    bool alreadyAttacked;

    //State
    public float sightRange, attackRange;
    public bool playerInSightRange, PlayerInAttackRange;

    private void Awake()
    {
        player = GameObject.Find("First Person Player").transform;
        agent = GetComponent<NavMeshAgent>();
    }

    public void Patroling()
    {
        if (!walkPointset)
        {
            SearchWalkPoint();
        }
        if (walkPointset)
        {
            agent.SetDestination(walkPoint);
        }
        Vector3 distaneTowalkPoint = transform.position - walkPoint;

        if (distaneTowalkPoint.magnitude < 1f)
        {
            walkPointset = false;
        }

    }

    private void SearchWalkPoint()
    {
        float randomZ = Random.Range(-walkPointRange, walkPointRange);
        float randomX = Random.Range(-walkPointRange, walkPointRange);

        walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, 
        transform.position.z + randomZ);
        if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround))
        {
            walkPointset = true;
        }
    }

    public void ChasePlayer()
    {
        agent.SetDestination(player.position);
    }

    public void AttackPlayer()
    {
        agent.SetDestination(transform.position);

        transform.LookAt(player);
        if (!alreadyAttacked)
        {
            //attack code here
            player.GetComponent<playerDamage>().damagePlayer(agentDamage);



            alreadyAttacked = true;
            Invoke(nameof(ResetAttack), timeBetweenAttacks);
        }
    }

    private void ResetAttack()
    {
        alreadyAttacked = false;
    }

    public void TakeDamage (float amount)
    {
        health -= amount;
        healthbar.SetHealth(health);
        if(health <= 0f)
        {
           Die();
        }

        void Die()
        {
            Debug.Log("this needs to be excuted");
            if (gameObject != null)
            {
                Debug.Log("this needs to be excuted");
                Destroy(gameObject);
                Debug.Log("this was excuted successfully");
            }
            Debug.Log("this needs to be excuted");
            OnEnemyKilled();
            Debug.Log("this was excuted successfully");
        }
    }

    private void Update()
    {
        player = GameObject.Find("First Person Player").transform;
        agent = GetComponent<NavMeshAgent>();
        //Check for sight and attack range
        playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
        PlayerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);

        if(!playerInSightRange && !PlayerInAttackRange)
        {
            Patroling();
        }

        if (health < 30f)
        {
            ChasePlayer();
        }

        if (playerInSightRange && !PlayerInAttackRange)
        {
            ChasePlayer();
        }

        if (playerInSightRange && PlayerInAttackRange)
        {
            AttackPlayer();
        }
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, attackRange);
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, sightRange);
    }
    
}

gun.cs

public class gun : MonoBehaviour
{
    public float damage = 10f;
    public float range = 100f;
    public float fireRate = 15f;
    public float impactForce = 3000f;

    public AudioSource soundSource;
    public AudioClip gunschot;
    public Camera fpsCam;
    public ParticleSystem muzzleFlash;
    public GameObject impactEffectBlood;
    public GameObject impactEffectGround;
    public pausmenu pausmenu;

    private float nextTimeToFire = 0f;

    void Start()
    {
        soundSource = GetComponent<AudioSource>();
        impactEffectBlood.SetActive(true);
        impactEffectGround.SetActive(true);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Fire1") && Time.time >= nextTimeToFire && !pausmenu.GameIsPaused)
        {
            nextTimeToFire = Time.time + 1f / fireRate;
            Shoot();
        }
        
    }

    void playgunsound ()
    {
        soundSource.clip = gunschot;
        soundSource.PlayOneShot(soundSource.clip);
    }

    void Shoot()
    {
        
        playgunsound();
        muzzleFlash.Play();

        RaycastHit hit;
        if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Debug.Log(hit.transform.name);

            target target = hit.transform.GetComponent<target>();
            if(target != null)
            {
                target.TakeDamage(damage);
            }

            if (hit.rigidbody != null)
            {
                hit.rigidbody.AddForce(-hit.normal * impactForce);
            }

            if (hit.transform.name == "Enemy")
            {
                GameObject impactGO = Instantiate(impactEffectBlood, hit.point, 
                Quaternion.LookRotation(hit.normal));
                Destroy(impactGO, 2f);
            }

            if (hit.transform.tag == "ground")
            {
                GameObject impactGO = Instantiate(impactEffectGround, hit.point, 
                Quaternion.LookRotation(hit.normal));
                Destroy(impactGO, 2f);
            }
            
        }
    }
}

EnemyManager.cs

public class EnemyManager : MonoBehaviour
{
    
    public Transform spawnpoint;
    public GameObject EnemyPrefab;

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("this needs to be excuted");
        spawnNewEnemy();
        Debug.Log("this was excuted successfully");
    }

    void OnEnable()
    {
        Debug.Log("this needs to be excuted");
        target.OnEnemyKilled += spawnNewEnemy;
        Debug.Log("this was excuted successfully");
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void spawnNewEnemy()
    {
        Debug.Log("this needs to be excuted");
        if (transform != null)
        {
            Debug.Log("this needs to be excuted");
            Debug.Log(transform);
            Instantiate(EnemyPrefab, spawnpoint.transform.position, Quaternion.Euler(Vector3.zero));
            Debug.Log("this was excuted successfully");
        } else
        {
            Debug.Log("ENEMYMANAGER.TRANSFORM = NULL");
        }
    }
}

Hi!

As I can see, you left out some part of your code, but in general this error means what it says. You destroyed the EnemyManager at some point with the Destroy(…) method and cannot find the reference anymore.

Another possibility, you mentioned that the player dies and the Scene reloads. Maybe here you implemented something which will destory the EnemyManager or not recreate it automatically and when the game restarts itself, the EnemyManager not yet created and this is the result of it.

I cannot point out the exact problem, because as I said it seems to me that this is not the full code where the restarting process happens or the player dies (or I missed them entirely, sorry for that).

But either way, this error appears if you or the system destroyed the gameobject and the class cannot be found anymore. In the latter case, you should check out the Unity’s lifecycle process (Unity - Manual: Order of execution for event functions) and get your head around it, because during resetting the scene improperly can lead to this problem, where Unity already destroyed your object (properly), but the starting process you wrote is flawed and will not recreate the object you need.

@simiel7 Thanks I will definitely read up on that. But i never call Destroy() on the enemy manager object. I can show you more of my code.


this is all the code that’s involved with the scene load. (Plus the code from before of course)

public class GameOver : MonoBehaviour
{
    public void PlayAgain()
    {
        Debug.Log("this needs to be excuted");
        SceneManager.LoadScene(1, LoadSceneMode.Single);
        Debug.Log("this was excuted successfully");
    }

    public void BackToMain()
    {
        Debug.Log("this needs to be excuted");
        SceneManager.LoadScene(0, LoadSceneMode.Single);
        Debug.Log("this was excuted successfully");
    }

    public void QuitGame()
    {
        Debug.Log("quit");
        Application.Quit();
    }
}

public class playerDamage : MonoBehaviour
{
    public float healthplayer = 100f;
    public float currentHealth;

    public Healthbar healthbar;
    public GameObject GameOverUI;
    public pausmenu pausmenu;

    void Start()
    {
        currentHealth = healthplayer;
        healthbar.SetMaxHealth(healthplayer);
        
    }
  

    
    public void damagePlayer(float amount)
    {
        currentHealth = healthplayer -= amount;

        healthbar.SetHealth(currentHealth);

        if (currentHealth > 0)
        {
            Debug.Log("you took damage, your health is now:" + currentHealth);
        }

        if (currentHealth <= 0f)
        {
            Die();
        }

        void Die()
        {
            Debug.Log("you took health has been depleted you are dead");
            Cursor.lockState = CursorLockMode.Confined;
            GameOverUI.SetActive(true);
            Time.timeScale = 0f;
        }
    }
}

I’ve also tried to fix the problem by adding some lines that refer to both the spawnpoint object and the enemy prefab in the start and spawn new enemy functions but that made the game spawn one extra enemy for every time I run the game over sequence.
Other than that I haven’t changed anything.