Why when destroying objects it's not destroying all of them in the editor mode ?

I want the script to be working also in editor mode but also when running the game.
What i want to do is when i uncheck the bool variable generateNew to destroy all objects in the editor mode/game view mode.

The problem is if i’m running the game when i check the bool once it will add objects but then when i uncheck it again it’s not destroying all the objects maybe only some. I keep see the objects before not only the new ones.

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

[ExecuteInEditMode]
public class InstantiateObjects : MonoBehaviour
{
    public GameObject prefab;
    public Terrain terrain;
    public float yOffset = 0.5f;
    public int objectsToInstantiate;
    public bool parent = true;
    public string tagName = "";
    public bool randomScale = false;
    public float randScaleX, randScaleY, randScaleZ;
    public bool generateNew = false;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private int numberOfObjectsToCreate;
    private GameObject objInstance;
    private List<GameObject> generatedObjects;

    public void Start()
    {
        //Get terrain size
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;

        //Get terrain position
        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;

        numberOfObjectsToCreate = objectsToInstantiate;
    }

    private void Update()
    {
        if (generateNew == true)
            generateObjectOnTerrain();
        if (generateNew == false)
        {
            for (int i = 0; i < generatedObjects.Count; i++)
            {
                DestroyImmediate(generatedObjects[i]);
            }
        }
    }

    public void generateObjectOnTerrain()
    {
        generatedObjects = new List<GameObject>();
        for (int i = 0; i < objectsToInstantiate; i++)
        {
            //Generate random x,z,y position on the terrain
            float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
            float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

            float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

            //Generate random x,y,z scale on the terrain
            randScaleX = Random.Range(3, 70);
            randScaleY = Random.Range(70, 170);
            randScaleZ = Random.Range(50, 270);

            //Apply Offset if needed
            yVal = yVal + yOffset;

            //Generate the Prefab on the generated position        
            objInstance = Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
            if (randomScale == true)
                objInstance.transform.localScale = new Vector3(randScaleX, randScaleY, randScaleZ);

            if (tagName != "")
                objInstance.name = tagName;

            if (parent)
                objInstance.transform.parent = this.transform;

            generatedObjects.Add(objInstance);
        }
    }
}

Your thread title says it doesn’t destroy them all in editor mode, but your post says it doesn’t destroy them all when you’re running the game. So I think there may be some confusion there.

Keep in mind that the Update method, when the game is not running, executes only when something changes. I’m not sure whether that includes the automatic reset of all property values at the end of a run. This might be adding to the confusion.

Also, trying to keep information around in a private List, even between runs, makes me all squirmy. Especially since this list will sometimes contain references to things which were created at runtime, and get destroyed automatically. You might consider instead just finding the generated objects by name, tag, or location in the hierarchy (e.g., create them all with this object as the parent, and then you can easily find and destroy them).

HTH,

  • Joe

When generateNew is true you’re re-creating your list and adding new stuff to it every frame but when you set it to false you’re only destroying what is in the list from the last frame.

2 Likes