I have an elevator in a scene that has only one floor. If someone presses button 2, when the doors open, I want the floor to look different from when the doors open on the 3rd floor. So, I’ve placed the furniture for each floor in its own prefab and I call up the prefabs as indicated below.
The instantiations are working fine. However, if I select floor 3 after I’ve been to floor 1, floor 3 prefab appears but floor 1 prefab doesn’t go away.
It looks like Destroy isn’t working. And I get an error message: Destroying assets is not permitted to avoid data loss. If you really want to remove an asset use DestroyImmediate (theObject, true).
In reading about DestroyImmediate, it doesn’t look like what I need.
switch (currFloor)
{
case "01":
Instantiate(floorPrefab[0], new Vector3(-0.221f, 0f, -0.286f), Quaternion.identity);
Destroy(floorPrefab[1]);
Destroy(floorPrefab[2]);
Destroy(floorPrefab[3]);
Debug.Log("floor1");
break;
case "02":
Instantiate(floorPrefab[1], new Vector3(-0.221f, 0f, -0.286f), Quaternion.identity);
Destroy(floorPrefab[0]);
Destroy(floorPrefab[2]);
Destroy(floorPrefab[3]);
Debug.Log("floor2");
break;
You are one of those who confuse a “prefab” with an “instance of a prefab”. You try to actually destroy the prefab itself. The thing that lives in your project. What you want to destroy is the instance of your prefab that lives in your scene. Note that the Instantiate method returns the instance it creates. It does nothing to the source object you pass in. The instance also has no relation to the object it was cloned from.
If you want to manage your instantiated floor objects you have to store the reference to the instantiated object somewhere.
To me it looks like that at any time you only want to have a single floor object in your scene. If that’s the case you can simply use a single GameObject variable inside your class like this:
private GameObject currentFloorObj = null;
in your instantiate code you would first destroy the old one, if there is one and then create the new one:
case "01":
if (currentFloorObj != null)
Destroy(currentFloorObj);
currentFloorObj = Instantiate(floorPrefab[0], new Vector3(-0.221f, 0f, -0.286f), Quaternion.identity);
break;
Note that your switch case construct looks like a horrible approach. Why is “currFloor” a string? Since you have your different floor prefabs already in an array, why not using an int variable? That way you can get rid of the whole switch case thing. Just create another array with your spawn positions or group the prefab with your spawn position together in a custom serializable class. We don’t know what logic is behind your code. However you should learn how to seperate logic from configuration data. In general avoid any hardcoded values inside your code. If you do something similar more than twice, it’s most likely you could simplify your code into a loop / array / method / … We don’t see the whole picture of your project so we can not tell you what you could do.
You should disable instead of destroying them.
This is very helpful. and it explains why my prefab information disappeared in Inspector after running Play. 
I used a string because the currFloor variable is also being used by another method in the script to change the floor number that is in a TextMeshpro text field.
I’m using switch because I want to add some additional code to the cases which will be unique for each floor. For example, the sound of the elevator moving will run longer for floor 8 than for floor 2.
Based on your feedback though, I’m reexamining how I have this set up and I’m reworking it. Thanks!