- Home /
Copying GameObject with all of its references?
I want to be able to copy an entire hierarchy of GameObjects, which would be fairly easy with a custom recursive function and Instantiate(), but I also want to copy all the MonoBehaviour states, references inclueded. References to Objects inside of the hierarchy should be pointing to the newly created Objects instead of the original ones.
I can think of a way to do this, but it requires Reflection and would take around 3 weeks to implement, which is just not an option, considering the scope of my project. Is there an out of the box solution for this kind of problem that I'm unaware of?
I don't understand, how is a single call of Instantiate() method not sufficient?
It wouldn't work because the reference types would be copied too and still refer to the objects attached to the original hierarchy. It's a fairly common issue, you can look up shallow vs. deep copying in C# (and many other languages...) if you're interested.
That's actually not true. For any gameobject or component which belong to the cloned hierarchy internal references are adjusted accordingly. Though only references to gameobjects or components are affected. This is actually explained here Instantiate essentially serializes the original object and deserializes the saved data as a new object. So things not supported by the serialization system would be lost. References to UnityEngine.Object derived objects which have been cloned will be adjusted properly.
For more information see the script serialization manual
Answer by Bunny83 · Feb 23, 2020 at 02:48 AM
Actually Instantiate does perform a deep copy. However it depends on what kind of reference types we talk about. All components and relative references within the hierarchy will be duplicated and cross references will point to the newly created instances. Affected are all gameobjects and the components on those gameobjects which belong to the same hierarchy.
The fundamental question here is usually the question who actually owns an object. The transform components of gameobjects form the actual hierarchy. Child objects are considered to be owned by the parent gameobject. Likewise components are owned by the gameobject they are attached to. Similarly custom serializable classes (which act like structs from the serialization point of view) are owned by the containing object. Those are all cloned appropriately. However cross references are only "adjusted" for gameobject and components which belong to the cloned hierarchy.
Apart from those objects any references to "external" objects which do not belong to the cloned hierarchy will remain. This includes references to all kinds of assets (textures, meshes, audioclips, shaders, materials, scriptableobjects, "other" prefabs, ...). As already mentioned custom serializable classes act like structs. They are duplicated for every "reference" there might be inside your hierarchy. So if you have two or more references to one custom serializable object instance, after cloning each of those references will contain its own instance of that object.
Since we have to deal with various different types and classes of objects a complete deep copy usually doesn't make much sense. Also keep in mind there are certain kinds of objects which are difficult or even impossible to duplicate properly. Example are closures, delegates and running coroutines.
So your question sounds like you didn't spent much time thinking about what you actually need to be duplicated. So my counter question is do you have a contrete example of a reference that you wanted to be preserved / be adjusted which currently isn't when using Instantiate on the parent?
The reason why I don't want the solution to be specific to my class(hirearchy) is, because I want to leave to code open to expendability, and I don't want to think about this problem every time, when implementing a new feature later on. In fact expandibility is one of the most important element of my project.
Anyway, your first few paragraphs answered my question, I can work with this. I didn't know Instantiate works like that when using it on preInstantiated GameObjects.
For clarity and future readers of this Question the answer for your counter question: -Lets have 2 GameObjects A and B. -B is the child of A. -ScriptA has a field: "public ScriptB referenceName;" (referring to it's child's Script B). I want to copy something like that, only arbitrarily more complicated. No coroutines, delegates, only references to each other and basic types.
Thank you for taking the time to answer.
Answer by sacredgeometry · Feb 22, 2020 at 03:38 PM
Is there any reason you need a deep copy of your game objects? But a simple/ quick way to do it would be to use something like newtonsoft to serialise it then you can deserialise it into a new object.
Your answer
Follow this Question
Related Questions
Efficiently mimic movements of GameObject 2 Answers
Any suggestions on this approach to multiple objects and materials 0 Answers
Clone class variables to another... Copy class not by reference 4 Answers
How do I get an A.I. to follow my movements? 0 Answers
Prefab Variables Changing in the Original, Not the Copies 2 Answers