- Home /
Cloning a GameObject with Linked Prefab Children
Hello,
Say we have three objects: A Prefab Asset (call it "A"), a regular GameObject in the scene ("B"), and a prefab instance of A that is a child of B ("C"):
Project
Prefab Asset A
Scene Hierarchy
GameObject B
- Prefab Instance C (connected to Prefab Asset A)
I would like to clone GameObject B, in such a way that its children (i.e. Prefab Instance C) maintain their connections to their prefab assets, as well as any overrides they may have. This is trivial in the editor (using Duplicate, or Copy & Paste), however I need to do this via scripting.
UnityEditor.PrefabUtility.InstantiatePrefab doesn't work, since it won't accept a non-asset as a parameter, so I can't pass it GameObject B. Object.Instantiate obviously won't work either since it breaks the prefab connections. I've looked through the rest of PrefabUtility's static methods and don't see anything else there that'd be helpful, but I'm hoping that I'm missing something. Does anyone know of a way to do this via scripting?
Much thanks in advance.
(Unity 2019.4)
Answer by smark12007 · Jul 22, 2020 at 06:16 PM
Use some tricks like UnityEditor.Unsupported.DuplicateGameObjectsUsingPasteboard?
UnityEngine.Object recordSelected = UnityEditor.Selection.activeObject;
UnityEditor.Selection.activeObject = GameObjectB;
UnityEditor.Unsupported.DuplicateGameObjectsUsingPasteboard();
UnityEditor.Selection.activeObject = recordSelected;
https://forum.unity.com/threads/no-function-to-ctrl-d-duplicate-through-an-editor-script.263891/
Creative. It worked. One issue with this is that DuplicateGameObjectsUsingPasteboard returns void, and I needed a reference to the new object so I can do things with it (like re-parent it). But it seems to reliably add the new object to the end of the parent's child hierarchy, so using GetChild on the parent transform seems to be a viable way to get the new object. I'm using this for an editor tool I hope to use in several projects, so I don't love using an unsupported method, but at least for now, it gets the job done. I'll leave this open for the moment in case anyone has any other suggestions, then close it.
For things you want to return, perhaps the trick is simple too
UnityEngine.Object[] recordSelectedObjects = UnityEditor.Selection.objects;
UnityEditor.Selection.activeObject = GameObjectB;
UnityEditor.Unsupported.DuplicateGameObjectsUsingPasteboard();
UnityEngine.Object GameObjectC = UnityEditor.Selection.activeObject;
UnityEditor.Selection.objects = recordSelectedObjects;
return GameObjectC;
Since you don't prefer unsupported methods, I'll look for elegant way when I have time.
As the previous answer said: UnityEditor.Unsupported.DuplicateGameObjectsUsingPasteboard(); <-- Sometimes doesn't select anything afterwards (specifically with prefabs in some ocasions, no idea why). And so Selection.activeObject or Selection.activeGameObject returns null.