Error: Destroying assets is not permitted to avoid data loss

I get this error: Destroying assets is not permitted to avoid data loss.
This is my code:

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

public class GeneratorScript : MonoBehaviour
{
    public GameObject[] availableRooms;
    public List<GameObject> currentRooms;
    private float screenWidthInPoints;
    private IEnumerator GeneratorCheck()
    {
    while (true)
    {
        GenerateRoomIfRequired();
        yield return new WaitForSeconds(0.25f);
    }
    }


    // Start is called before the first frame update
    void Start()
    {
        float height = 2.0f * Camera.main.orthographicSize;
        screenWidthInPoints = height * Camera.main.aspect;
        StartCoroutine(GeneratorCheck());
    }

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

    void AddRoom(float farthestRoomEndX)
    {
    //1
    int randomRoomIndex = Random.Range(0, availableRooms.Length);
    //2
    GameObject room = (GameObject)Instantiate(availableRooms[randomRoomIndex]);
    //3
    float roomWidth = room.transform.Find("floor").localScale.x;
    //4
    float roomCenter = farthestRoomEndX + roomWidth * 0.5f;
    //5
    room.transform.position = new Vector3(roomCenter, 0, 0);
    //6
    currentRooms.Add(room);
    }

    private void GenerateRoomIfRequired()
    {
    //1
    List<GameObject> roomsToRemove = new List<GameObject>();
    //2
    bool addRooms = true;
    //3
    float playerX = transform.position.x;
    //4
    float removeRoomX = playerX - screenWidthInPoints;
    //5
    float addRoomX = playerX + screenWidthInPoints;
    //6
    float farthestRoomEndX = 0;
    foreach (var room in currentRooms)
    {
        //7
        float roomWidth = room.transform.Find("floor").localScale.x;
        float roomStartX = room.transform.position.x - (roomWidth * 0.5f);
        float roomEndX = roomStartX + roomWidth;
        //8
        if (roomStartX > addRoomX)
        {
            addRooms = false;
        }
        //9
        if (roomEndX < removeRoomX)
        {
            roomsToRemove.Add(room);
        }
        //10
        farthestRoomEndX = Mathf.Max(farthestRoomEndX, roomEndX);
    }
    //11
    foreach (var room in roomsToRemove)
    {
        currentRooms.Remove(room);
        Destroy(room);
    }
    //12
    if (addRooms)
    {
        AddRoom(farthestRoomEndX);
    }
    }
}

2 Answers

2

Since your currentRooms list is public, are you sure you did NOT drag anything into that List in the inspector? Because dragging prefabs into that list would cause exactly that issue. Your List is supposed to hold instances of prefabs, not prefabs themselfs. Prefabs are assets that live in your project and can act as a cloning source (which you did when using Instantiate) to clone them into the scene. Prefabs can not / should not be destroyed as they are authored in the editor.

In the public list of currentrooms (in the inspector) the prefab of the room is assigned, and when I give it play it starts to generate the clones, but there comes a moment when it stops and the destroy error appears.

@saimon024 But that's exactly the problem. You should NOT assign prefabs into the currentrooms List. Your currentrooms List is supposed to hold instances and not prefabs since you go through that list and Destroy them at some point. You can not Destroy prefabs, only instances. A prefab is NOT something that lives in the scene. A prefab is an asset like a Texture, Mesh or Material. They live in the project and can not be destroyed at runtime. When you call Instantiate on a prefab reference, you actually create an instance of that prefab which is returned by Instantiate.

I think I understand you (excuse my igorance haha). I will make the respective changes and let you know of any updates, thank you very much.

Make sure you only call Destroy on instances of GameObjects in the scene, not a Prefab reference. Although, I don’t see the issue in your code. Are you sure you posted the code that has the error?

Yes, it is supposed to be. And yes, that is the code that supposedly has the error.