How to copy GameObject and preserve Prefab connection and Component values from editor script
Hey I am trying to copy a GameObject in my scene and preserve the prefab connection while also preserving the values that were changed in the instance's components. So far I have tried these two methods:
[MenuItem("Test/Test1")]
public static void Test1()
{
Object prefabRoot = PrefabUtility.GetPrefabParent(Selection.activeGameObject);
PrefabUtility.InstantiatePrefab(prefabRoot);
}
[MenuItem("Test/Test2")]
public static void Test2()
{
GameObject go = Object.Instantiate(Selection.activeGameObject);
var prefabParent = PrefabUtility.GetPrefabParent(Selection.activeGameObject);
PrefabUtility.ConnectGameObjectToPrefab(go, prefabParent as GameObject);
}
But both of them behave like they instantiate a completely new copy of the prefab instead of keeping values like name, location etc. and the values that were changed from the original prefab values in the instance's components.
Essentially I just want to replicate the behavior of ctrl-D after which i can apply my own changes to the GameObject
Answer by unity-marcus · Jul 06, 2020 at 03:54 PM
Not pretty but it works (tested in 2019.3).
Selection.activeGameObject = someGameObjectToCopy;
Unsupported.CopyGameObjectsToPasteboard();
Unsupported.PasteGameObjectsFromPasteboard();
var copy = Selection.activeGameObject;
Very nice solution. Not pretty indeed, but totally working.
Unity, WTF with this fishy class name? But hey it worked.
Answer by Leight · Jun 24, 2018 at 01:46 AM
Hello. I had same issue and spent a lot of time on this. Following code allows you to duplicate prefab objects and keep overrides:
// *** Try get prefab of an object *** //
GameObject obj = null;
Object prefab = PrefabUtility.GetPrefabParent(objectPrototype);
// *** Instantiate obj *** //
bool objIsPrefab = prefab != null;
if(objIsPrefab) {
// *** Save overrides from original obj *** //
PropertyModification[] mods = PrefabUtility.GetPropertyModifications(objectPrototype);
// *** instantiate clean prefab *** //
Object spawnedObj = PrefabUtility.InstantiatePrefab(prefab);
// *** Apply prefab overrides to a new instance *** //
PrefabUtility.SetPropertyModifications(spawnedObj, mods);
obj = (GameObject)spawnedObj;
} else {
obj = Instantiate(objectPrototype, wspacePos, Quaternion.identity, parentObj);
}
Please note that this method only handles properties and objects that are already a part of your original prefab. For instance, if you put a "cube" inside your prefab instance in scene and execute this code "cube" will not appear inside a new duplicated object. So you need to modify this code in order to handle this situation too.