I was pleasantly surprised when the following logic appears to work without any issues. I was expecting the original game object reference to break (or become null
) but somehow it proceeds to work.
public class MyEditorWindow : EditorWindow {
[MenuItem("Example/My Editor Window")]
public static void Display() {
EditorWindow.GetWindow<MyEditorWindow>();
}
public GameObject referenceToPrefab;
void OnGUI() {
referenceToPrefab = EditorGUILayout.ObjectField(referenceToPrefab, typeof(GameObject), false) as GameObject;
if (GUILayout.Button("Do Something")) {
DoSomething();
EditorGUIUtility.ExitGUI();
}
}
public void DoSomething() {
// Create instance of referenced prefab
GameObject go = PrefabUtility.InstantiatePrefab(referenceToPrefab) as GameObject;
go.hideFlags = HideFlags.HideAndDontSave;
// Change fields/properties of instantiated prefab
go.isStatic = !go.isStatic;
go.tag = "EditorOnly";
// Add a child object
GameObject child = new GameObject("New Child");
child.hideFlags = HideFlags.HideAndDontSave;
child.transform.parent = go.transform;
// Replace original instance of prefab with the changed one
PrefabUtility.ReplacePrefab(go, referenceToPrefab);
DestroyImmediate(go);
// Just for the fun of it, this works! how?
// Remember, this is still the original prefab reference!
Debug.Log(referenceToPrefab.tag); // EditorOnly
}
}
Q1. How does Unity achieve this under the hood?
Q2. Does it use a larger data type for references that keep track of the asset GUID?
Q3. If that is so, does this mean that non UnityEngine.Object
references waste memory?