After reloading level my object gets duplicated but when I destroy the duplicated object it breaks my script.

I have an EnemySpawner script that will spawn enemies when a level loads and when an enemy dies.
For the script to work I have to give the script an enemy in the inspector that it will spawn. When I reload a level using (SceneManager.LoadScene(SceneManager.GetActiveScene().name):wink: the EnemySpawner will duplicate but the duplicated object will of course not have the enemy attached to it in the inspector, so that means that it cannot spawn any enemies on the map.

The problem comes when I try to remove the duplicated EnemySpawner object. Why when removing the duplicated object without the capabilities of spawning enemies give me the error: “MissingReferenceException: The object of type ‘EnemySpawner’ has been destroyed but you are still trying to access it.” after trying to kill an enemy. This doesn’t make sense because the EnemySpawner that created those enemies still exists. I have other scripts that notify the EnemySpawner when an enemy has been destroyed.

Here is my EnemySpawner script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawner : MonoBehaviour

{

public GameObject enemyPrefab;
public int maxEnemies = 10;
public float spawnSize = 10f;

public float spawnDelay = 5f;
public List<Transform> spawnPoints;

private List<GameObject> enemies = new List<GameObject>();
private static EnemySpawner _instance;

void Awake()
{

    DontDestroyOnLoad(this.gameObject);
    // Spawn initial enemies
    for (int i = 0; i < maxEnemies; i++)
    {
        SpawnEnemy();
    }

    // Subscribe to the OnEnemyDeath event
    Target.OnEnemyDeath += OnEnemyDeath;
}

private void Start()
{

}

private void SpawnEnemy()
{
    // Select a random spawn point from the list
    Transform randomSpawnPoint = spawnPoints[Random.Range(0, spawnPoints.Count)];

    // Create a new enemy instance at the random spawn point
    Vector3 randomPosition = randomSpawnPoint.position + Random.insideUnitSphere * spawnSize;
    randomPosition.y = 0f;
    GameObject enemy = Instantiate(enemyPrefab, randomPosition, transform.rotation);

    // Add the enemy to the list of enemies
    enemies.Add(enemy);
}

private void OnEnemyDeath(GameObject enemy)
{
    // Remove the dead enemy from the list of enemies
    enemies.Remove(enemy);
    Debug.Log("Enemy killed by player or destroyed because it was out of bounds and it should succesfully respawn shortly!");
    // Spawn a new enemy after a delay
    StartCoroutine(SpawnEnemyDelayed());
}

private IEnumerator SpawnEnemyDelayed()
{
    yield return new WaitForSeconds(spawnDelay);
    if (enemies.Count < maxEnemies)
    {
        SpawnEnemy();
        Debug.Log("Enemy Spawned!");
    }
}

}

You have several potential issues here. First of all, why does the script have a DontDestroyOnLoad on it when it’s in a scene that you’re going to reload? DontDestroyOnLoad objects are meant to survive loading a new level so they should never be in a scene that is going to be reloaded.

Second point is your Target.OnEnemyDeath event is probably a static event? You subscribe to the event in Awake, so you should unsubscribe in OnDestroy, ALWAYS. Of course when you subscribe to an instance that is going to be destroyed with the scene that wouldn’t matter. However static events survive everything. Subscriptions don’t magically disappear when the object gets destroyed. So you would have a dead object subscribed to the event.

So if this script is in a scene that is going to be reloaded, don’t use DontDestroyOnLoad. I don’t see any reason why this script should stay after reloading a scene. Also when you subscribe to an event, make sure you unsubscribe in the opposite callback. Awake ↔ OnDestroy, OnEnable ↔ OnDisable, …

Also note that DontDestroyOnLoad only works on root objects. When the object is nested (a child of another object that isn’t marked with DontDestroyOnLoad) the method has no effect.